lib/goog/testing/jsunit.js

1// Copyright 2007 The Closure Library Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS-IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15/**
16 * @fileoverview Utilities for working with JsUnit. Writes out the JsUnit file
17 * that needs to be included in every unit test.
18 *
19 * Testing code should not have dependencies outside of goog.testing so as to
20 * reduce the chance of masking missing dependencies.
21 *
22 */
23
24goog.provide('goog.testing.jsunit');
25
26goog.require('goog.testing.TestCase');
27goog.require('goog.testing.TestRunner');
28
29
30/**
31 * Base path for JsUnit app files, relative to Closure's base path.
32 * @type {string}
33 */
34goog.testing.jsunit.BASE_PATH =
35 '../../third_party/java/jsunit/core/app/';
36
37
38/**
39 * Filename for the core JS Unit script.
40 * @type {string}
41 */
42goog.testing.jsunit.CORE_SCRIPT =
43 goog.testing.jsunit.BASE_PATH + 'jsUnitCore.js';
44
45
46/**
47 * @define {boolean} If this code is being parsed by JsTestC, we let it disable
48 * the onload handler to avoid running the test in JsTestC.
49 */
50goog.define('goog.testing.jsunit.AUTO_RUN_ONLOAD', true);
51
52
53/**
54 * @define {number} Sets a delay in milliseconds after the window onload event
55 * and running the tests. Used to prevent interference with Selenium and give
56 * tests with asynchronous operations time to finish loading.
57 */
58goog.define('goog.testing.jsunit.AUTO_RUN_DELAY_IN_MS', 500);
59
60
61(function() {
62 // Increases the maximum number of stack frames in Google Chrome from the
63 // default 10 to 50 to get more useful stack traces.
64 Error.stackTraceLimit = 50;
65
66 // Store a reference to the window's timeout so that it can't be overridden
67 // by tests.
68 /** @type {!Function} */
69 var realTimeout = window.setTimeout;
70
71 // Check for JsUnit's test runner (need to check for >2.2 and <=2.2)
72 if (top['JsUnitTestManager'] || top['jsUnitTestManager']) {
73 // Running inside JsUnit so add support code.
74 var path = goog.basePath + goog.testing.jsunit.CORE_SCRIPT;
75 document.write('<script type="text/javascript" src="' +
76 path + '"></' + 'script>');
77
78 } else {
79
80 // Create a test runner.
81 var tr = new goog.testing.TestRunner();
82
83 // Export it so that it can be queried by Selenium and tests that use a
84 // compiled test runner.
85 goog.exportSymbol('G_testRunner', tr);
86 goog.exportSymbol('G_testRunner.initialize', tr.initialize);
87 goog.exportSymbol('G_testRunner.isInitialized', tr.isInitialized);
88 goog.exportSymbol('G_testRunner.isFinished', tr.isFinished);
89 goog.exportSymbol('G_testRunner.isSuccess', tr.isSuccess);
90 goog.exportSymbol('G_testRunner.getReport', tr.getReport);
91 goog.exportSymbol('G_testRunner.getRunTime', tr.getRunTime);
92 goog.exportSymbol('G_testRunner.getNumFilesLoaded', tr.getNumFilesLoaded);
93 goog.exportSymbol('G_testRunner.setStrict', tr.setStrict);
94 goog.exportSymbol('G_testRunner.logTestFailure', tr.logTestFailure);
95 goog.exportSymbol('G_testRunner.getTestResults', tr.getTestResults);
96
97 // Export debug as a global function for JSUnit compatibility. This just
98 // calls log on the current test case.
99 if (!goog.global['debug']) {
100 goog.exportSymbol('debug', goog.bind(tr.log, tr));
101 }
102
103 // If the application has defined a global error filter, set it now. This
104 // allows users who use a base test include to set the error filter before
105 // the testing code is loaded.
106 if (goog.global['G_errorFilter']) {
107 tr.setErrorFilter(goog.global['G_errorFilter']);
108 }
109
110 // Add an error handler to report errors that may occur during
111 // initialization of the page.
112 var onerror = window.onerror;
113 window.onerror = function(error, url, line) {
114 // Call any existing onerror handlers.
115 if (onerror) {
116 onerror(error, url, line);
117 }
118 if (typeof error == 'object') {
119 // Webkit started passing an event object as the only argument to
120 // window.onerror. It doesn't contain an error message, url or line
121 // number. We therefore log as much info as we can.
122 if (error.target && error.target.tagName == 'SCRIPT') {
123 tr.logError('UNKNOWN ERROR: Script ' + error.target.src);
124 } else {
125 tr.logError('UNKNOWN ERROR: No error information available.');
126 }
127 } else {
128 tr.logError('JS ERROR: ' + error + '\nURL: ' + url + '\nLine: ' + line);
129 }
130 };
131
132 // Create an onload handler, if the test runner hasn't been initialized then
133 // no test has been registered with the test runner by the test file. We
134 // then create a new test case and auto discover any tests in the global
135 // scope. If this code is being parsed by JsTestC, we let it disable the
136 // onload handler to avoid running the test in JsTestC.
137 if (goog.testing.jsunit.AUTO_RUN_ONLOAD) {
138 var onload = window.onload;
139 window.onload = function(e) {
140 // Call any existing onload handlers.
141 if (onload) {
142 onload(e);
143 }
144 // Wait so that we don't interfere with WebDriver.
145 realTimeout(function() {
146 if (!tr.initialized) {
147 var test = new goog.testing.TestCase(document.title);
148 test.autoDiscoverTests();
149 tr.initialize(test);
150 }
151 tr.execute();
152 }, goog.testing.jsunit.AUTO_RUN_DELAY_IN_MS);
153 window.onload = null;
154 };
155 }
156 }
157})();