Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(129)

Side by Side Diff: LayoutTests/http/tests/resources/testharness.js

Issue 1061543006: Pull in the latest upstream testharness.js changes. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebase/tweaks for affected tests Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | LayoutTests/http/tests/security/suborigins/multiple-suborigins-disallowed-expected.txt » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /*global self*/ 1 /*global self*/
2 /*jshint latedef: nofunc*/ 2 /*jshint latedef: nofunc*/
3 /* 3 /*
4 Distributed under both the W3C Test Suite License [1] and the W3C 4 Distributed under both the W3C Test Suite License [1] and the W3C
5 3-clause BSD License [2]. To contribute to a W3C Test Suite, see the 5 3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
6 policies and contribution forms [3]. 6 policies and contribution forms [3].
7 7
8 [1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license 8 [1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
9 [2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license 9 [2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
10 [3] http://www.w3.org/2004/10/27-testcases 10 [3] http://www.w3.org/2004/10/27-testcases
11 */ 11 */
12 12
13 /* 13 /* Documentation is in docs/api.md */
14 * == Introduction ==
15 *
16 * This file provides a framework for writing testcases. It is intended to
17 * provide a convenient API for making common assertions, and to work both
18 * for testing synchronous and asynchronous DOM features in a way that
19 * promotes clear, robust, tests.
20 *
21 * == Basic Usage ==
22 *
23 * To use this file, import the script and the testharnessreport script into
24 * the test document:
25 *
26 * <script src="/resources/testharness.js"></script>
27 * <script src="/resources/testharnessreport.js"></script>
28 *
29 * Within each file one may define one or more tests. Each test is atomic
30 * in the sense that a single test has a single result (pass/fail/timeout).
31 * Within each test one may have a number of asserts. The test fails at the
32 * first failing assert, and the remainder of the test is (typically) not run.
33 *
34 * If the file containing the tests is a HTML file, a table containing the test
35 * results will be added to the document after all tests have run. By default th is
36 * will be added to a div element with id=log if it exists, or a new div element
37 * appended to document.body if it does not.
38 *
39 * NOTE: By default tests must be created before the load event fires. For ways
40 * to create tests after the load event, see "Determining when all tests
41 * are complete", below
42 *
43 * == Synchronous Tests ==
44 *
45 * To create a synchronous test use the test() function:
46 *
47 * test(test_function, name, properties)
48 *
49 * test_function is a function that contains the code to test. For example a
50 * trivial passing test would be:
51 *
52 * test(function() {assert_true(true)}, "assert_true with true")
53 *
54 * The function passed in is run in the test() call.
55 *
56 * properties is an object that overrides default test properties. The
57 * recognised properties are:
58 * timeout - the test timeout in ms
59 *
60 * e.g.
61 * test(test_function, "Sample test", {timeout:1000})
62 *
63 * would run test_function with a timeout of 1s.
64 *
65 * Additionally, test-specific metadata can be passed in the properties. These
66 * are used when the individual test has different metadata from that stored
67 * in the <head>.
68 * The recognized metadata properties are:
69 *
70 * help - The url or an array of urls of the part(s) of the specification(s)
71 * being tested
72 *
73 * assert - A human readable description of what the test is attempting
74 * to prove
75 *
76 * author - Name and contact information for the author of the test in the
77 * format: "Name <email_addr>" or "Name http://contact/url"
78 *
79 * == Asynchronous Tests ==
80 *
81 * Testing asynchronous features is somewhat more complex since the result of
82 * a test may depend on one or more events or other callbacks. The API provided
83 * for testing these features is indended to be rather low-level but hopefully
84 * applicable to many situations.
85 *
86 * To create a test, one starts by getting a Test object using async_test:
87 *
88 * async_test(name, properties)
89 *
90 * e.g.
91 * var t = async_test("Simple async test")
92 *
93 * Assertions can be added to the test by calling the step method of the test
94 * object with a function containing the test assertions:
95 *
96 * t.step(function() {assert_true(true)});
97 *
98 * When all the steps are complete, the done() method must be called:
99 *
100 * t.done();
101 *
102 * As a convenience, async_test can also takes a function as first argument.
103 * This function is called with the test object as both its `this` object and
104 * first argument. The above example can be rewritten as:
105 *
106 * async_test(function(t) {
107 * object.some_event = function() {
108 * t.step(function (){assert_true(true); t.done();});
109 * };
110 * }, "Simple async test");
111 *
112 * which avoids cluttering the global scope with references to async
113 * tests instances.
114 *
115 * The properties argument is identical to that for test().
116 *
117 * In many cases it is convenient to run a step in response to an event or a
118 * callback. A convenient method of doing this is through the step_func method
119 * which returns a function that, when called runs a test step. For example
120 *
121 * object.some_event = t.step_func(function(e) {assert_true(e.a)});
122 *
123 * For asynchronous callbacks that should never execute, unreached_func can
124 * be used. For example:
125 *
126 * object.some_event = t.unreached_func("some_event should not fire");
127 *
128 * == Single Page Tests ==
129 *
130 * Sometimes, particularly when dealing with asynchronous behaviour,
131 * having exactly one test per page is desirable, and the overhead of
132 * wrapping everything in functions for isolation becomes
133 * burdensome. For these cases testharness.js support "single page
134 * tests".
135 *
136 * In order for a test to be interpreted as a "single page" test, the
137 * it must simply not call test() or async_test() anywhere on the page, and
138 * must call the done() function to indicate that the test is complete. All
139 * the assert_* functions are avaliable as normal, but are called without
140 * the normal step function wrapper. For example:
141 *
142 * <!doctype html>
143 * <title>Example single-page test</title>
144 * <script src="/resources/testharness.js"></script>
145 * <script src="/resources/testharnessreport.js"></script>
146 * <body>
147 * <script>
148 * assert_equals(document.body, document.getElementsByTagName("body")[0])
149 * done()
150 * </script>
151 *
152 * The test title for sinple page tests is always taken from document.title.
153 *
154 * == Making assertions ==
155 *
156 * Functions for making assertions start assert_
157 * The best way to get a list is to look in this file for functions names
158 * matching that pattern. The general signature is
159 *
160 * assert_something(actual, expected, description)
161 *
162 * although not all assertions precisely match this pattern e.g. assert_true
163 * only takes actual and description as arguments.
164 *
165 * The description parameter is used to present more useful error messages when
166 * a test fails
167 *
168 * NOTE: All asserts must be located in a test() or a step of an async_test().
169 * asserts outside these places won't be detected correctly by the harness
170 * and may cause a file to stop testing.
171 *
172 * == Cleanup ==
173 *
174 * Occasionally tests may create state that will persist beyond the test itself.
175 * In order to ensure that tests are independent, such state should be cleaned
176 * up once the test has a result. This can be achieved by adding cleanup
177 * callbacks to the test. Such callbacks are registered using the add_cleanup
178 * function on the test object. All registered callbacks will be run as soon as
179 * the test result is known. For example
180 *
181 * test(function() {
182 * window.some_global = "example";
183 * this.add_cleanup(function() {delete window.some_global});
184 * assert_true(false);
185 * });
186 *
187 * == Harness Timeout ==
188 *
189 * The overall harness admits two timeout values "normal" (the
190 * default) and "long", used for tests which have an unusually long
191 * runtime. After the timeout is reached, the harness will stop
192 * waiting for further async tests to complete. By default the
193 * timeouts are set to 10s and 60s, respectively, but may be changed
194 * when the test is run on hardware with different performance
195 * characteristics to a common desktop computer. In order to opt-in
196 * to the longer test timeout, the test must specify a meta element:
197 *
198 * <meta name="timeout" content="long">
199 *
200 * Occasionally tests may have a race between the harness timing out and
201 * a particular test failing; typically when the test waits for some event
202 * that never occurs. In this case it is possible to use test.force_timeout()
203 * in place of assert_unreached(), to immediately fail the test but with a
204 * status of "timeout". This should only be used as a last resort when it is
205 * not possible to make the test reliable in some other way.
206 *
207 * == Setup ==
208 *
209 * Sometimes tests require non-trivial setup that may fail. For this purpose
210 * there is a setup() function, that may be called with one or two arguments.
211 * The two argument version is:
212 *
213 * setup(func, properties)
214 *
215 * The one argument versions may omit either argument.
216 * func is a function to be run synchronously. setup() becomes a no-op once
217 * any tests have returned results. Properties are global properties of the test
218 * harness. Currently recognised properties are:
219 *
220 *
221 * explicit_done - Wait for an explicit call to done() before declaring all
222 * tests complete (see below; implicitly true for single page
223 * tests)
224 *
225 * output_document - The document to which results should be logged. By default
226 * this is the current document but could be an ancestor
227 * document in some cases e.g. a SVG test loaded in an HTML
228 * wrapper
229 *
230 * explicit_timeout - disable file timeout; only stop waiting for results
231 * when the timeout() function is called (typically for
232 * use when integrating with some existing test framework
233 * that has its own timeout mechanism).
234 *
235 * allow_uncaught_exception - don't treat an uncaught exception as an error;
236 * needed when e.g. testing the window.onerror
237 * handler.
238 *
239 * timeout_multiplier - Multiplier to apply to per-test timeouts.
240 *
241 * == Determining when all tests are complete ==
242 *
243 * By default the test harness will assume there are no more results to come
244 * when:
245 * 1) There are no Test objects that have been created but not completed
246 * 2) The load event on the document has fired
247 *
248 * This behaviour can be overridden by setting the explicit_done property to
249 * true in a call to setup(). If explicit_done is true, the test harness will
250 * not assume it is done until the global done() function is called. Once done()
251 * is called, the two conditions above apply like normal.
252 *
253 * == Generating tests ==
254 *
255 * There are scenarios in which is is desirable to create a large number of
256 * (synchronous) tests that are internally similar but vary in the parameters
257 * used. To make this easier, the generate_tests function allows a single
258 * function to be called with each set of parameters in a list:
259 *
260 * generate_tests(test_function, parameter_lists, properties)
261 *
262 * For example:
263 *
264 * generate_tests(assert_equals, [
265 * ["Sum one and one", 1+1, 2],
266 * ["Sum one and zero", 1+0, 1]
267 * ])
268 *
269 * Is equivalent to:
270 *
271 * test(function() {assert_equals(1+1, 2)}, "Sum one and one")
272 * test(function() {assert_equals(1+0, 1)}, "Sum one and zero")
273 *
274 * Note that the first item in each parameter list corresponds to the name of
275 * the test.
276 *
277 * The properties argument is identical to that for test(). This may be a
278 * single object (used for all generated tests) or an array.
279 *
280 * == Callback API ==
281 *
282 * The framework provides callbacks corresponding to 3 events:
283 *
284 * start - happens when the first Test is created
285 * result - happens when a test result is recieved
286 * complete - happens when all results are recieved
287 *
288 * The page defining the tests may add callbacks for these events by calling
289 * the following methods:
290 *
291 * add_start_callback(callback) - callback called with no arguments
292 * add_result_callback(callback) - callback called with a test argument
293 * add_completion_callback(callback) - callback called with an array of tests
294 * and an status object
295 *
296 * tests have the following properties:
297 * status: A status code. This can be compared to the PASS, FAIL, TIMEOUT and
298 * NOTRUN properties on the test object
299 * message: A message indicating the reason for failure. In the future this
300 * will always be a string
301 *
302 * The status object gives the overall status of the harness. It has the
303 * following properties:
304 * status: Can be compared to the OK, ERROR and TIMEOUT properties
305 * message: An error message set when the status is ERROR
306 *
307 * == External API ==
308 *
309 * In order to collect the results of multiple pages containing tests, the test
310 * harness will, when loaded in a nested browsing context, attempt to call
311 * certain functions in each ancestor and opener browsing context:
312 *
313 * start - start_callback
314 * result - result_callback
315 * complete - completion_callback
316 *
317 * These are given the same arguments as the corresponding internal callbacks
318 * described above.
319 *
320 * == External API through cross-document messaging ==
321 *
322 * Where supported, the test harness will also send messages using
323 * cross-document messaging to each ancestor and opener browsing context. Since
324 * it uses the wildcard keyword (*), cross-origin communication is enabled and
325 * script on different origins can collect the results.
326 *
327 * This API follows similar conventions as those described above only slightly
328 * modified to accommodate message event API. Each message is sent by the harnes s
329 * is passed a single vanilla object, available as the `data` property of the
330 * event object. These objects are structures as follows:
331 *
332 * start - { type: "start" }
333 * result - { type: "result", test: Test }
334 * complete - { type: "complete", tests: [Test, ...], status: TestsStatus }
335 *
336 * == List of assertions ==
337 *
338 * assert_true(actual, description)
339 * asserts that /actual/ is strictly true
340 *
341 * assert_false(actual, description)
342 * asserts that /actual/ is strictly false
343 *
344 * assert_equals(actual, expected, description)
345 * asserts that /actual/ is the same value as /expected/
346 *
347 * assert_not_equals(actual, expected, description)
348 * asserts that /actual/ is a different value to /expected/. Yes, this means
349 * that "expected" is a misnomer
350 *
351 * assert_in_array(actual, expected, description)
352 * asserts that /expected/ is an Array, and /actual/ is equal to one of the
353 * members -- expected.indexOf(actual) != -1
354 *
355 * assert_array_equals(actual, expected, description)
356 * asserts that /actual/ and /expected/ have the same length and the value of
357 * each indexed property in /actual/ is the strictly equal to the correspondin g
358 * property value in /expected/
359 *
360 * assert_approx_equals(actual, expected, epsilon, description)
361 * asserts that /actual/ is a number within +/- /epsilon/ of /expected/
362 *
363 * assert_less_than(actual, expected, description)
364 * asserts that /actual/ is a number less than /expected/
365 *
366 * assert_greater_than(actual, expected, description)
367 * asserts that /actual/ is a number greater than /expected/
368 *
369 * assert_less_than_equal(actual, expected, description)
370 * asserts that /actual/ is a number less than or equal to /expected/
371 *
372 * assert_greater_than_equal(actual, expected, description)
373 * asserts that /actual/ is a number greater than or equal to /expected/
374 *
375 * assert_regexp_match(actual, expected, description)
376 * asserts that /actual/ matches the regexp /expected/
377 *
378 * assert_class_string(object, class_name, description)
379 * asserts that the class string of /object/ as returned in
380 * Object.prototype.toString is equal to /class_name/.
381 *
382 * assert_own_property(object, property_name, description)
383 * assert that object has own property property_name
384 *
385 * assert_inherits(object, property_name, description)
386 * assert that object does not have an own property named property_name
387 * but that property_name is present in the prototype chain for object
388 *
389 * assert_idl_attribute(object, attribute_name, description)
390 * assert that an object that is an instance of some interface has the
391 * attribute attribute_name following the conditions specified by WebIDL
392 *
393 * assert_readonly(object, property_name, description)
394 * assert that property property_name on object is readonly
395 *
396 * assert_throws(code, func, description)
397 * code - the expected exception:
398 * o string: the thrown exception must be a DOMException with the given
399 * name, e.g., "TimeoutError" (for compatibility with existing
400 * tests, a constant is also supported, e.g., "TIMEOUT_ERR")
401 * o object: the thrown exception must have a property called "name" that
402 * matches code.name
403 * o null: allow any exception (in general, one of the options above
404 * should be used)
405 * func - a function that should throw
406 *
407 * assert_unreached(description)
408 * asserts if called. Used to ensure that some codepath is *not* taken e.g.
409 * an event does not fire.
410 *
411 * assert_any(assert_func, actual, expected_array, extra_arg_1, ... extra_arg_N)
412 * asserts that one assert_func(actual, expected_array_N, extra_arg1, ..., ext ra_arg_N)
413 * is true for some expected_array_N in expected_array. This only works for as sert_func
414 * with signature assert_func(actual, expected, args_1, ..., args_N). Note tha t tests
415 * with multiple allowed pass conditions are bad practice unless the spec spec ifically
416 * allows multiple behaviours. Test authors should not use this method simply to hide
417 * UA bugs.
418 *
419 * assert_exists(object, property_name, description)
420 * *** deprecated ***
421 * asserts that object has an own property property_name
422 *
423 * assert_not_exists(object, property_name, description)
424 * *** deprecated ***
425 * assert that object does not have own property property_name
426 *
427 * == Metadata ==
428 *
429 * It is possible to add optional metadata to tests; this can be done in one of two ways;
430 * either by adding <meta> elements to the head of the document containing the t ests,
431 * or by adding the metadata to individual [async_]test calls, as properties.
432 */
433 14
434 (function () 15 (function ()
435 { 16 {
436 var debug = false; 17 var debug = false;
437 // default timeout is 10 seconds, test can override if needed 18 // default timeout is 10 seconds, test can override if needed
438 var settings = { 19 var settings = {
439 output:true, 20 output:true,
440 harness_timeout:{ 21 harness_timeout:{
441 "normal":10000, 22 "normal":10000,
442 "long":60000 23 "long":60000
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 this.output_handler = null; 64 this.output_handler = null;
484 this.all_loaded = false; 65 this.all_loaded = false;
485 var this_obj = this; 66 var this_obj = this;
486 on_event(window, 'load', function() { 67 on_event(window, 'load', function() {
487 this_obj.all_loaded = true; 68 this_obj.all_loaded = true;
488 }); 69 });
489 } 70 }
490 71
491 WindowTestEnvironment.prototype._dispatch = function(selector, callback_args , message_arg) { 72 WindowTestEnvironment.prototype._dispatch = function(selector, callback_args , message_arg) {
492 this._forEach_windows( 73 this._forEach_windows(
493 function(w, is_same_origin) { 74 function(w, same_origin) {
494 if (is_same_origin && selector in w) { 75 if (same_origin) {
495 try { 76 try {
496 w[selector].apply(undefined, callback_args); 77 var has_selector = selector in w;
497 } catch (e) { 78 } catch(e) {
498 if (debug) { 79 // If document.domain was set at some point same_ori gin can be
499 throw e; 80 // wrong and the above will fail.
81 has_selector = false;
82 }
83 if (has_selector) {
84 try {
85 w[selector].apply(undefined, callback_args);
86 } catch (e) {
87 if (debug) {
88 throw e;
89 }
500 } 90 }
501 } 91 }
502 } 92 }
503 if (supports_post_message(w) && w !== self) { 93 if (supports_post_message(w) && w !== self) {
504 w.postMessage(message_arg, "*"); 94 w.postMessage(message_arg, "*");
505 } 95 }
506 }); 96 });
507 }; 97 };
508 98
509 WindowTestEnvironment.prototype._forEach_windows = function(callback) { 99 WindowTestEnvironment.prototype._forEach_windows = function(callback) {
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
876 .catch(test.step_func( 466 .catch(test.step_func(
877 function(value) { 467 function(value) {
878 if (value instanceof AssertionError) { 468 if (value instanceof AssertionError) {
879 throw value; 469 throw value;
880 } 470 }
881 assert(false, "promise_test", null, 471 assert(false, "promise_test", null,
882 "Unhandled rejection with value: ${value}", {value:va lue}); 472 "Unhandled rejection with value: ${value}", {value:va lue});
883 })); 473 }));
884 } 474 }
885 475
476 function promise_rejects(test, expected, promise) {
477 return promise.then(test.unreached_func("Should have rejected.")).catch( function(e) {
478 assert_throws(expected, function() { throw e });
479 });
480 }
481
482 /**
483 * This constructor helper allows DOM events to be handled using Promises,
484 * which can make it a lot easier to test a very specific series of events,
485 * including ensuring that unexpected events are not fired at any point.
486 */
487 function EventWatcher(test, watchedNode, eventTypes)
488 {
489 if (typeof eventTypes == 'string') {
490 eventTypes = [eventTypes];
491 }
492
493 var waitingFor = null;
494
495 var eventHandler = test.step_func(function(evt) {
496 assert_true(!!waitingFor,
497 'Not expecting event, but got ' + evt.type + ' event');
498 assert_equals(evt.type, waitingFor.types[0],
499 'Expected ' + waitingFor.types[0] + ' event, but got ' +
500 evt.type + ' event instead');
501 if (waitingFor.types.length > 1) {
502 // Pop first event from array
503 waitingFor.types.shift();
504 return;
505 }
506 // We need to null out waitingFor before calling the resolve functio n
507 // since the Promise's resolve handlers may call wait_for() which wi ll
508 // need to set waitingFor.
509 var resolveFunc = waitingFor.resolve;
510 waitingFor = null;
511 resolveFunc(evt);
512 });
513
514 for (var i = 0; i < eventTypes.length; i++) {
515 watchedNode.addEventListener(eventTypes[i], eventHandler);
516 }
517
518 /**
519 * Returns a Promise that will resolve after the specified event or
520 * series of events has occured.
521 */
522 this.wait_for = function(types) {
523 if (waitingFor) {
524 return Promise.reject('Already waiting for an event or events');
525 }
526 if (typeof types == 'string') {
527 types = [types];
528 }
529 return new Promise(function(resolve, reject) {
530 waitingFor = {
531 types: types,
532 resolve: resolve,
533 reject: reject
534 };
535 });
536 };
537
538 function stop_watching() {
539 for (var i = 0; i < eventTypes.length; i++) {
540 watchedNode.removeEventListener(eventTypes[i], eventHandler);
541 }
542 };
543
544 test.add_cleanup(stop_watching);
545
546 return this;
547 }
548 expose(EventWatcher, 'EventWatcher');
549
886 function setup(func_or_properties, maybe_properties) 550 function setup(func_or_properties, maybe_properties)
887 { 551 {
888 var func = null; 552 var func = null;
889 var properties = {}; 553 var properties = {};
890 if (arguments.length === 2) { 554 if (arguments.length === 2) {
891 func = func_or_properties; 555 func = func_or_properties;
892 properties = maybe_properties; 556 properties = maybe_properties;
893 } else if (func_or_properties instanceof Function) { 557 } else if (func_or_properties instanceof Function) {
894 func = func_or_properties; 558 func = func_or_properties;
895 } else { 559 } else {
(...skipping 27 matching lines...) Expand all
923 } 587 }
924 588
925 function on_event(object, event, callback) 589 function on_event(object, event, callback)
926 { 590 {
927 object.addEventListener(event, callback, false); 591 object.addEventListener(event, callback, false);
928 } 592 }
929 593
930 expose(test, 'test'); 594 expose(test, 'test');
931 expose(async_test, 'async_test'); 595 expose(async_test, 'async_test');
932 expose(promise_test, 'promise_test'); 596 expose(promise_test, 'promise_test');
597 expose(promise_rejects, 'promise_rejects');
933 expose(generate_tests, 'generate_tests'); 598 expose(generate_tests, 'generate_tests');
934 expose(setup, 'setup'); 599 expose(setup, 'setup');
935 expose(done, 'done'); 600 expose(done, 'done');
936 expose(on_event, 'on_event'); 601 expose(on_event, 'on_event');
937 602
938 /* 603 /*
939 * Return a string truncated to the given length, with ... added at the end 604 * Return a string truncated to the given length, with ... added at the end
940 * if it was longer. 605 * if it was longer.
941 */ 606 */
942 function truncate(s, len) 607 function truncate(s, len)
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
1186 function assert_array_equals(actual, expected, description) 851 function assert_array_equals(actual, expected, description)
1187 { 852 {
1188 assert(actual.length === expected.length, 853 assert(actual.length === expected.length,
1189 "assert_array_equals", description, 854 "assert_array_equals", description,
1190 "lengths differ, expected ${expected} got ${actual}", 855 "lengths differ, expected ${expected} got ${actual}",
1191 {expected:expected.length, actual:actual.length}); 856 {expected:expected.length, actual:actual.length});
1192 857
1193 for (var i = 0; i < actual.length; i++) { 858 for (var i = 0; i < actual.length; i++) {
1194 assert(actual.hasOwnProperty(i) === expected.hasOwnProperty(i), 859 assert(actual.hasOwnProperty(i) === expected.hasOwnProperty(i),
1195 "assert_array_equals", description, 860 "assert_array_equals", description,
1196 "property ${i}, property expected to be $expected but was $ac tual", 861 "property ${i}, property expected to be ${expected} but was $ {actual}",
1197 {i:i, expected:expected.hasOwnProperty(i) ? "present" : "miss ing", 862 {i:i, expected:expected.hasOwnProperty(i) ? "present" : "miss ing",
1198 actual:actual.hasOwnProperty(i) ? "present" : "missing"}); 863 actual:actual.hasOwnProperty(i) ? "present" : "missing"});
1199 assert(same_value(expected[i], actual[i]), 864 assert(same_value(expected[i], actual[i]),
1200 "assert_array_equals", description, 865 "assert_array_equals", description,
1201 "property ${i}, expected ${expected} but got ${actual}", 866 "property ${i}, expected ${expected} but got ${actual}",
1202 {i:i, expected:expected[i], actual:actual[i]}); 867 {i:i, expected:expected[i], actual:actual[i]});
1203 } 868 }
1204 } 869 }
1205 expose(assert_array_equals, "assert_array_equals"); 870 expose(assert_array_equals, "assert_array_equals");
1206 871
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1248 "expected a number but got a ${type_actual}", 913 "expected a number but got a ${type_actual}",
1249 {type_actual:typeof actual}); 914 {type_actual:typeof actual});
1250 915
1251 assert(actual > expected, 916 assert(actual > expected,
1252 "assert_greater_than", description, 917 "assert_greater_than", description,
1253 "expected a number greater than ${expected} but got ${actual}", 918 "expected a number greater than ${expected} but got ${actual}",
1254 {expected:expected, actual:actual}); 919 {expected:expected, actual:actual});
1255 } 920 }
1256 expose(assert_greater_than, "assert_greater_than"); 921 expose(assert_greater_than, "assert_greater_than");
1257 922
923 function assert_between_exclusive(actual, lower, upper, description)
924 {
925 /*
926 * Test if a primitive number is between two others
927 */
928 assert(typeof actual === "number",
929 "assert_between_exclusive", description,
930 "expected a number but got a ${type_actual}",
931 {type_actual:typeof actual});
932
933 assert(actual > lower && actual < upper,
934 "assert_between_exclusive", description,
935 "expected a number greater than ${lower} " +
936 "and less than ${upper} but got ${actual}",
937 {lower:lower, upper:upper, actual:actual});
938 }
939 expose(assert_between_exclusive, "assert_between_exclusive");
940
1258 function assert_less_than_equal(actual, expected, description) 941 function assert_less_than_equal(actual, expected, description)
1259 { 942 {
1260 /* 943 /*
1261 * Test if a primitive number is less than or equal to another 944 * Test if a primitive number is less than or equal to another
1262 */ 945 */
1263 assert(typeof actual === "number", 946 assert(typeof actual === "number",
1264 "assert_less_than_equal", description, 947 "assert_less_than_equal", description,
1265 "expected a number but got a ${type_actual}", 948 "expected a number but got a ${type_actual}",
1266 {type_actual:typeof actual}); 949 {type_actual:typeof actual});
1267 950
1268 assert(actual <= expected, 951 assert(actual <= expected,
1269 "assert_less_than", description, 952 "assert_less_than_equal", description,
1270 "expected a number less than or equal to ${expected} but got ${ac tual}", 953 "expected a number less than or equal to ${expected} but got ${ac tual}",
1271 {expected:expected, actual:actual}); 954 {expected:expected, actual:actual});
1272 } 955 }
1273 expose(assert_less_than_equal, "assert_less_than_equal"); 956 expose(assert_less_than_equal, "assert_less_than_equal");
1274 957
1275 function assert_greater_than_equal(actual, expected, description) 958 function assert_greater_than_equal(actual, expected, description)
1276 { 959 {
1277 /* 960 /*
1278 * Test if a primitive number is greater than or equal to another 961 * Test if a primitive number is greater than or equal to another
1279 */ 962 */
1280 assert(typeof actual === "number", 963 assert(typeof actual === "number",
1281 "assert_greater_than_equal", description, 964 "assert_greater_than_equal", description,
1282 "expected a number but got a ${type_actual}", 965 "expected a number but got a ${type_actual}",
1283 {type_actual:typeof actual}); 966 {type_actual:typeof actual});
1284 967
1285 assert(actual >= expected, 968 assert(actual >= expected,
1286 "assert_greater_than_equal", description, 969 "assert_greater_than_equal", description,
1287 "expected a number greater than or equal to ${expected} but got $ {actual}", 970 "expected a number greater than or equal to ${expected} but got $ {actual}",
1288 {expected:expected, actual:actual}); 971 {expected:expected, actual:actual});
1289 } 972 }
1290 expose(assert_greater_than_equal, "assert_greater_than_equal"); 973 expose(assert_greater_than_equal, "assert_greater_than_equal");
1291 974
975 function assert_between_inclusive(actual, lower, upper, description)
976 {
977 /*
978 * Test if a primitive number is between to two others or equal to eithe r of them
979 */
980 assert(typeof actual === "number",
981 "assert_between_inclusive", description,
982 "expected a number but got a ${type_actual}",
983 {type_actual:typeof actual});
984
985 assert(actual >= lower && actual <= upper,
986 "assert_between_inclusive", description,
987 "expected a number greater than or equal to ${lower} " +
988 "and less than or equal to ${upper} but got ${actual}",
989 {lower:lower, upper:upper, actual:actual});
990 }
991 expose(assert_between_inclusive, "assert_between_inclusive");
992
1292 function assert_regexp_match(actual, expected, description) { 993 function assert_regexp_match(actual, expected, description) {
1293 /* 994 /*
1294 * Test if a string (actual) matches a regexp (expected) 995 * Test if a string (actual) matches a regexp (expected)
1295 */ 996 */
1296 assert(expected.test(actual), 997 assert(expected.test(actual),
1297 "assert_regexp_match", description, 998 "assert_regexp_match", description,
1298 "expected ${expected} but got ${actual}", 999 "expected ${expected} but got ${actual}",
1299 {expected:expected, actual:actual}); 1000 {expected:expected, actual:actual});
1300 } 1001 }
1301 expose(assert_regexp_match, "assert_regexp_match"); 1002 expose(assert_regexp_match, "assert_regexp_match");
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1433 TypeMismatchError: 17, 1134 TypeMismatchError: 17,
1434 SecurityError: 18, 1135 SecurityError: 18,
1435 NetworkError: 19, 1136 NetworkError: 19,
1436 AbortError: 20, 1137 AbortError: 20,
1437 URLMismatchError: 21, 1138 URLMismatchError: 21,
1438 QuotaExceededError: 22, 1139 QuotaExceededError: 22,
1439 TimeoutError: 23, 1140 TimeoutError: 23,
1440 InvalidNodeTypeError: 24, 1141 InvalidNodeTypeError: 24,
1441 DataCloneError: 25, 1142 DataCloneError: 25,
1442 1143
1144 EncodingError: 0,
1145 NotReadableError: 0,
1443 UnknownError: 0, 1146 UnknownError: 0,
1444 ConstraintError: 0, 1147 ConstraintError: 0,
1445 DataError: 0, 1148 DataError: 0,
1446 TransactionInactiveError: 0, 1149 TransactionInactiveError: 0,
1447 ReadOnlyError: 0, 1150 ReadOnlyError: 0,
1448 VersionError: 0 1151 VersionError: 0,
1152 OperationError: 0,
1449 }; 1153 };
1450 1154
1451 if (!(name in name_code_map)) { 1155 if (!(name in name_code_map)) {
1452 throw new AssertionError('Test bug: unrecognized DOMException co de "' + code + '" passed to assert_throws()'); 1156 throw new AssertionError('Test bug: unrecognized DOMException co de "' + code + '" passed to assert_throws()');
1453 } 1157 }
1454 1158
1455 var required_props = { code: name_code_map[name] }; 1159 var required_props = { code: name_code_map[name] };
1456 1160
1457 if (required_props.code === 0 || 1161 if (required_props.code === 0 ||
1458 ("name" in e && e.name !== e.name.toUpperCase() && e.name !== "DO MException")) { 1162 (typeof e == "object" &&
1163 "name" in e &&
1164 e.name !== e.name.toUpperCase() &&
1165 e.name !== "DOMException")) {
1459 // New style exception: also test the name property. 1166 // New style exception: also test the name property.
1460 required_props.name = name; 1167 required_props.name = name;
1461 } 1168 }
1462 1169
1463 //We'd like to test that e instanceof the appropriate interface, 1170 //We'd like to test that e instanceof the appropriate interface,
1464 //but we can't, because we don't know what window it was created 1171 //but we can't, because we don't know what window it was created
1465 //in. It might be an instanceof the appropriate interface on some 1172 //in. It might be an instanceof the appropriate interface on some
1466 //unknown other window. TODO: Work around this somehow? 1173 //unknown other window. TODO: Work around this somehow?
1467 1174
1468 assert(typeof e == "object", 1175 assert(typeof e == "object",
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1522 1229
1523 this.properties = properties; 1230 this.properties = properties;
1524 var timeout = properties.timeout ? properties.timeout : settings.test_ti meout; 1231 var timeout = properties.timeout ? properties.timeout : settings.test_ti meout;
1525 if (timeout !== null) { 1232 if (timeout !== null) {
1526 this.timeout_length = timeout * tests.timeout_multiplier; 1233 this.timeout_length = timeout * tests.timeout_multiplier;
1527 } else { 1234 } else {
1528 this.timeout_length = null; 1235 this.timeout_length = null;
1529 } 1236 }
1530 1237
1531 this.message = null; 1238 this.message = null;
1239 this.stack = null;
1532 1240
1533 this.steps = []; 1241 this.steps = [];
1534 1242
1535 this.cleanup_callbacks = []; 1243 this.cleanup_callbacks = [];
1536 1244
1537 tests.push(this); 1245 tests.push(this);
1538 } 1246 }
1539 1247
1540 Test.statuses = { 1248 Test.statuses = {
1541 PASS:0, 1249 PASS:0,
(...skipping 16 matching lines...) Expand all
1558 if (!this._structured_clone) { 1266 if (!this._structured_clone) {
1559 var msg = this.message; 1267 var msg = this.message;
1560 msg = msg ? String(msg) : msg; 1268 msg = msg ? String(msg) : msg;
1561 this._structured_clone = merge({ 1269 this._structured_clone = merge({
1562 name:String(this.name), 1270 name:String(this.name),
1563 properties:merge({}, this.properties), 1271 properties:merge({}, this.properties),
1564 }, Test.statuses); 1272 }, Test.statuses);
1565 } 1273 }
1566 this._structured_clone.status = this.status; 1274 this._structured_clone.status = this.status;
1567 this._structured_clone.message = this.message; 1275 this._structured_clone.message = this.message;
1276 this._structured_clone.stack = this.stack;
1568 this._structured_clone.index = this.index; 1277 this._structured_clone.index = this.index;
1569 return this._structured_clone; 1278 return this._structured_clone;
1570 }; 1279 };
1571 1280
1572 Test.prototype.step = function(func, this_obj) 1281 Test.prototype.step = function(func, this_obj)
1573 { 1282 {
1574 if (this.phase > this.phases.STARTED) { 1283 if (this.phase > this.phases.STARTED) {
1575 return; 1284 return;
1576 } 1285 }
1577 this.phase = this.phases.STARTED; 1286 this.phase = this.phases.STARTED;
(...skipping 12 matching lines...) Expand all
1590 if (arguments.length === 1) { 1299 if (arguments.length === 1) {
1591 this_obj = this; 1300 this_obj = this;
1592 } 1301 }
1593 1302
1594 try { 1303 try {
1595 return func.apply(this_obj, Array.prototype.slice.call(arguments, 2) ); 1304 return func.apply(this_obj, Array.prototype.slice.call(arguments, 2) );
1596 } catch (e) { 1305 } catch (e) {
1597 if (this.phase >= this.phases.HAS_RESULT) { 1306 if (this.phase >= this.phases.HAS_RESULT) {
1598 return; 1307 return;
1599 } 1308 }
1600 var message = (typeof e === "object" && e !== null) ? e.message : e; 1309 var message = String((typeof e === "object" && e !== null) ? e.messa ge : e);
1601 if (typeof e.stack != "undefined" && typeof e.message == "string") { 1310 var stack = e.stack ? e.stack : null;
1602 //Try to make it more informative for some exceptions, at least 1311
1603 //in Gecko and WebKit. This results in a stack dump instead of 1312 this.set_status(this.FAIL, message, stack);
1604 //just errors like "Cannot read property 'parentNode' of null"
1605 //or "root is null". Makes it a lot longer, of course.
1606 message += "(stack: " + e.stack + ")";
1607 }
1608 this.set_status(this.FAIL, message);
1609 this.phase = this.phases.HAS_RESULT; 1313 this.phase = this.phases.HAS_RESULT;
1610 this.done(); 1314 this.done();
1611 } 1315 }
1612 }; 1316 };
1613 1317
1614 Test.prototype.step_func = function(func, this_obj) 1318 Test.prototype.step_func = function(func, this_obj)
1615 { 1319 {
1616 var test_this = this; 1320 var test_this = this;
1617 1321
1618 if (arguments.length === 1) { 1322 if (arguments.length === 1) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1664 { 1368 {
1665 if (this.timeout_length !== null) { 1369 if (this.timeout_length !== null) {
1666 var this_obj = this; 1370 var this_obj = this;
1667 this.timeout_id = setTimeout(function() 1371 this.timeout_id = setTimeout(function()
1668 { 1372 {
1669 this_obj.timeout(); 1373 this_obj.timeout();
1670 }, this.timeout_length); 1374 }, this.timeout_length);
1671 } 1375 }
1672 }; 1376 };
1673 1377
1674 Test.prototype.set_status = function(status, message) 1378 Test.prototype.set_status = function(status, message, stack)
1675 { 1379 {
1676 this.status = status; 1380 this.status = status;
1677 this.message = message; 1381 this.message = message;
1382 this.stack = stack ? stack : null;
1678 }; 1383 };
1679 1384
1680 Test.prototype.timeout = function() 1385 Test.prototype.timeout = function()
1681 { 1386 {
1682 this.timeout_id = null; 1387 this.timeout_id = null;
1683 this.set_status(this.TIMEOUT, "Test timed out"); 1388 this.set_status(this.TIMEOUT, "Test timed out");
1684 this.phase = this.phases.HAS_RESULT; 1389 this.phase = this.phases.HAS_RESULT;
1685 this.done(); 1390 this.done();
1686 }; 1391 };
1687 1392
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1740 }); 1445 });
1741 clone.phases = merge({}, this.phases); 1446 clone.phases = merge({}, this.phases);
1742 return clone; 1447 return clone;
1743 }; 1448 };
1744 1449
1745 RemoteTest.prototype.cleanup = function() {}; 1450 RemoteTest.prototype.cleanup = function() {};
1746 RemoteTest.prototype.phases = Test.prototype.phases; 1451 RemoteTest.prototype.phases = Test.prototype.phases;
1747 RemoteTest.prototype.update_state_from = function(clone) { 1452 RemoteTest.prototype.update_state_from = function(clone) {
1748 this.status = clone.status; 1453 this.status = clone.status;
1749 this.message = clone.message; 1454 this.message = clone.message;
1455 this.stack = clone.stack;
1750 if (this.phase === this.phases.INITIAL) { 1456 if (this.phase === this.phases.INITIAL) {
1751 this.phase = this.phases.STARTED; 1457 this.phase = this.phases.STARTED;
1752 } 1458 }
1753 }; 1459 };
1754 RemoteTest.prototype.done = function() { 1460 RemoteTest.prototype.done = function() {
1755 this.phase = this.phases.COMPLETE; 1461 this.phase = this.phases.COMPLETE;
1756 } 1462 }
1757 1463
1758 /* 1464 /*
1759 * A RemoteWorker listens for test events from a worker. These events are 1465 * A RemoteWorker listens for test events from a worker. These events are
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1799 } 1505 }
1800 1506
1801 RemoteWorker.prototype.worker_error = function(error) { 1507 RemoteWorker.prototype.worker_error = function(error) {
1802 var message = error.message || String(error); 1508 var message = error.message || String(error);
1803 var filename = (error.filename ? " " + error.filename: ""); 1509 var filename = (error.filename ? " " + error.filename: "");
1804 // FIXME: Display worker error states separately from main document 1510 // FIXME: Display worker error states separately from main document
1805 // error state. 1511 // error state.
1806 this.worker_done({ 1512 this.worker_done({
1807 status: { 1513 status: {
1808 status: tests.status.ERROR, 1514 status: tests.status.ERROR,
1809 message: "Error in worker" + filename + ": " + message 1515 message: "Error in worker" + filename + ": " + message,
1516 stack: error.stack
1810 } 1517 }
1811 }); 1518 });
1812 error.preventDefault(); 1519 error.preventDefault();
1813 }; 1520 };
1814 1521
1815 RemoteWorker.prototype.test_state = function(data) { 1522 RemoteWorker.prototype.test_state = function(data) {
1816 var remote_test = this.tests[data.test.index]; 1523 var remote_test = this.tests[data.test.index];
1817 if (!remote_test) { 1524 if (!remote_test) {
1818 remote_test = new RemoteTest(data.test); 1525 remote_test = new RemoteTest(data.test);
1819 this.tests[data.test.index] = remote_test; 1526 this.tests[data.test.index] = remote_test;
1820 } 1527 }
1821 remote_test.update_state_from(data.test); 1528 remote_test.update_state_from(data.test);
1822 tests.notify_test_state(remote_test); 1529 tests.notify_test_state(remote_test);
1823 }; 1530 };
1824 1531
1825 RemoteWorker.prototype.test_done = function(data) { 1532 RemoteWorker.prototype.test_done = function(data) {
1826 var remote_test = this.tests[data.test.index]; 1533 var remote_test = this.tests[data.test.index];
1827 remote_test.update_state_from(data.test); 1534 remote_test.update_state_from(data.test);
1828 remote_test.done(); 1535 remote_test.done();
1829 tests.result(remote_test); 1536 tests.result(remote_test);
1830 }; 1537 };
1831 1538
1832 RemoteWorker.prototype.worker_done = function(data) { 1539 RemoteWorker.prototype.worker_done = function(data) {
1833 if (tests.status.status === null && 1540 if (tests.status.status === null &&
1834 data.status.status !== data.status.OK) { 1541 data.status.status !== data.status.OK) {
1835 tests.status.status = data.status.status; 1542 tests.status.status = data.status.status;
1836 tests.status.message = data.status.message; 1543 tests.status.message = data.status.message;
1544 tests.status.stack = data.status.stack;
1837 } 1545 }
1838 this.running = false; 1546 this.running = false;
1839 this.worker = null; 1547 this.worker = null;
1840 if (tests.all_done()) { 1548 if (tests.all_done()) {
1841 tests.complete(); 1549 tests.complete();
1842 } 1550 }
1843 }; 1551 };
1844 1552
1845 RemoteWorker.prototype.message_handlers = { 1553 RemoteWorker.prototype.message_handlers = {
1846 test_state: RemoteWorker.prototype.test_state, 1554 test_state: RemoteWorker.prototype.test_state,
1847 result: RemoteWorker.prototype.test_done, 1555 result: RemoteWorker.prototype.test_done,
1848 complete: RemoteWorker.prototype.worker_done 1556 complete: RemoteWorker.prototype.worker_done
1849 }; 1557 };
1850 1558
1851 /* 1559 /*
1852 * Harness 1560 * Harness
1853 */ 1561 */
1854 1562
1855 function TestsStatus() 1563 function TestsStatus()
1856 { 1564 {
1857 this.status = null; 1565 this.status = null;
1858 this.message = null; 1566 this.message = null;
1567 this.stack = null;
1859 } 1568 }
1860 1569
1861 TestsStatus.statuses = { 1570 TestsStatus.statuses = {
1862 OK:0, 1571 OK:0,
1863 ERROR:1, 1572 ERROR:1,
1864 TIMEOUT:2 1573 TIMEOUT:2
1865 }; 1574 };
1866 1575
1867 TestsStatus.prototype = merge({}, TestsStatus.statuses); 1576 TestsStatus.prototype = merge({}, TestsStatus.statuses);
1868 1577
1869 TestsStatus.prototype.structured_clone = function() 1578 TestsStatus.prototype.structured_clone = function()
1870 { 1579 {
1871 if (!this._structured_clone) { 1580 if (!this._structured_clone) {
1872 var msg = this.message; 1581 var msg = this.message;
1873 msg = msg ? String(msg) : msg; 1582 msg = msg ? String(msg) : msg;
1874 this._structured_clone = merge({ 1583 this._structured_clone = merge({
1875 status:this.status, 1584 status:this.status,
1876 message:msg 1585 message:msg,
1586 stack:this.stack
1877 }, TestsStatus.statuses); 1587 }, TestsStatus.statuses);
1878 } 1588 }
1879 return this._structured_clone; 1589 return this._structured_clone;
1880 }; 1590 };
1881 1591
1882 function Tests() 1592 function Tests()
1883 { 1593 {
1884 this.tests = []; 1594 this.tests = [];
1885 this.num_pending = 0; 1595 this.num_pending = 0;
1886 1596
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1956 } 1666 }
1957 } 1667 }
1958 } 1668 }
1959 1669
1960 if (func) { 1670 if (func) {
1961 try { 1671 try {
1962 func(); 1672 func();
1963 } catch (e) { 1673 } catch (e) {
1964 this.status.status = this.status.ERROR; 1674 this.status.status = this.status.ERROR;
1965 this.status.message = String(e); 1675 this.status.message = String(e);
1676 this.status.stack = e.stack ? e.stack : null;
1966 } 1677 }
1967 } 1678 }
1968 this.set_timeout(); 1679 this.set_timeout();
1969 }; 1680 };
1970 1681
1971 Tests.prototype.set_file_is_test = function() { 1682 Tests.prototype.set_file_is_test = function() {
1972 if (this.tests.length > 0) { 1683 if (this.tests.length > 0) {
1973 throw new Error("Tried to set file as test after creating a test"); 1684 throw new Error("Tried to set file as test after creating a test");
1974 } 1685 }
1975 this.wait_for_finish = true; 1686 this.wait_for_finish = true;
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
2313 ["p", {}, 2024 ["p", {},
2314 "Harness status: ", 2025 "Harness status: ",
2315 ["span", {"class":status_class(s tatus)}, 2026 ["span", {"class":status_class(s tatus)},
2316 status 2027 status
2317 ], 2028 ],
2318 ] 2029 ]
2319 ]]; 2030 ]];
2320 2031
2321 if (harness_status.status === harness_status .ERROR) { 2032 if (harness_status.status === harness_status .ERROR) {
2322 rv[0].push(["pre", {}, harness_status.me ssage]); 2033 rv[0].push(["pre", {}, harness_status.me ssage]);
2034 if (harness_status.stack) {
2035 rv[0].push(["pre", {}, harness_statu s.stack]);
2036 }
2323 } 2037 }
2324 return rv; 2038 return rv;
2325 }, 2039 },
2326 ["p", {}, "Found ${num_tests} tests"], 2040 ["p", {}, "Found ${num_tests} tests"],
2327 function() { 2041 function() {
2328 var rv = [["div", {}]]; 2042 var rv = [["div", {}]];
2329 var i = 0; 2043 var i = 0;
2330 while (status_text.hasOwnProperty(i)) { 2044 while (status_text.hasOwnProperty(i)) {
2331 if (status_number.hasOwnProperty(status_ text[i])) { 2045 if (status_number.hasOwnProperty(status_ text[i])) {
2332 var status = status_text[i]; 2046 var status = status_text[i];
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
2410 for (var i = 0; i < tests.length; i++) { 2124 for (var i = 0; i < tests.length; i++) {
2411 html += '<tr class="' + 2125 html += '<tr class="' +
2412 escape_html(status_class(status_text[tests[i].status])) + 2126 escape_html(status_class(status_text[tests[i].status])) +
2413 '"><td>' + 2127 '"><td>' +
2414 escape_html(status_text[tests[i].status]) + 2128 escape_html(status_text[tests[i].status]) +
2415 "</td><td>" + 2129 "</td><td>" +
2416 escape_html(tests[i].name) + 2130 escape_html(tests[i].name) +
2417 "</td><td>" + 2131 "</td><td>" +
2418 (assertions ? escape_html(get_assertion(tests[i])) + "</td><td>" : "") + 2132 (assertions ? escape_html(get_assertion(tests[i])) + "</td><td>" : "") +
2419 escape_html(tests[i].message ? tests[i].message : " ") + 2133 escape_html(tests[i].message ? tests[i].message : " ") +
2134 (tests[i].stack ? "<pre>" +
2135 escape_html(tests[i].stack) +
2136 "</pre>": "") +
2420 "</td></tr>"; 2137 "</td></tr>";
2421 } 2138 }
2422 html += "</tbody></table>"; 2139 html += "</tbody></table>";
2423 try { 2140 try {
2424 log.lastChild.innerHTML = html; 2141 log.lastChild.innerHTML = html;
2425 } catch (e) { 2142 } catch (e) {
2426 log.appendChild(document.createElementNS(xhtml_ns, "p")) 2143 log.appendChild(document.createElementNS(xhtml_ns, "p"))
2427 .textContent = "Setting innerHTML for the log threw an exception. "; 2144 .textContent = "Setting innerHTML for the log threw an exception. ";
2428 log.appendChild(document.createElementNS(xhtml_ns, "pre")) 2145 log.appendChild(document.createElementNS(xhtml_ns, "pre"))
2429 .textContent = html; 2146 .textContent = html;
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
2605 if (expected_true !== true) { 2322 if (expected_true !== true) {
2606 var msg = make_message(function_name, description, 2323 var msg = make_message(function_name, description,
2607 error, substitutions); 2324 error, substitutions);
2608 throw new AssertionError(msg); 2325 throw new AssertionError(msg);
2609 } 2326 }
2610 } 2327 }
2611 2328
2612 function AssertionError(message) 2329 function AssertionError(message)
2613 { 2330 {
2614 this.message = message; 2331 this.message = message;
2332 this.stack = this.get_stack();
2615 } 2333 }
2616 2334
2617 AssertionError.prototype.toString = function() { 2335 AssertionError.prototype = Object.create(Error.prototype);
2618 return this.message; 2336
2619 }; 2337 AssertionError.prototype.get_stack = function() {
2338 var lines = new Error().stack.split("\n");
2339 var rv = [];
2340 var re = /\/resources\/testharness\.js/;
2341 var i = 0;
2342 // Fire remove any preamble that doesn't match the regexp
2343 while (!re.test(lines[i])) {
2344 i++
2345 }
2346 // Then remove top frames in testharness.js itself
2347 while (re.test(lines[i])) {
2348 i++
2349 }
2350 return lines.slice(i).join("\n");
2351 }
2620 2352
2621 function make_message(function_name, description, error, substitutions) 2353 function make_message(function_name, description, error, substitutions)
2622 { 2354 {
2623 for (var p in substitutions) { 2355 for (var p in substitutions) {
2624 if (substitutions.hasOwnProperty(p)) { 2356 if (substitutions.hasOwnProperty(p)) {
2625 substitutions[p] = format_value(substitutions[p]); 2357 substitutions[p] = format_value(substitutions[p]);
2626 } 2358 }
2627 } 2359 }
2628 var node_form = substitute(["{text}", "${function_name}: ${description}" + error], 2360 var node_form = substitute(["{text}", "${function_name}: ${description}" + error],
2629 merge({function_name:function_name, 2361 merge({function_name:function_name,
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
2748 */ 2480 */
2749 2481
2750 var tests = new Tests(); 2482 var tests = new Tests();
2751 2483
2752 addEventListener("error", function(e) { 2484 addEventListener("error", function(e) {
2753 if (tests.file_is_test) { 2485 if (tests.file_is_test) {
2754 var test = tests.tests[0]; 2486 var test = tests.tests[0];
2755 if (test.phase >= test.phases.HAS_RESULT) { 2487 if (test.phase >= test.phases.HAS_RESULT) {
2756 return; 2488 return;
2757 } 2489 }
2758 var message = e.message; 2490 test.set_status(test.FAIL, e.message, e.stack);
2759 test.set_status(test.FAIL, message);
2760 test.phase = test.phases.HAS_RESULT; 2491 test.phase = test.phases.HAS_RESULT;
2761 test.done(); 2492 test.done();
2762 done(); 2493 done();
2763 } else if (!tests.allow_uncaught_exception) { 2494 } else if (!tests.allow_uncaught_exception) {
2764 tests.status.status = tests.status.ERROR; 2495 tests.status.status = tests.status.ERROR;
2765 tests.status.message = e.message; 2496 tests.status.message = e.message;
2497 tests.status.stack = e.stack;
2766 } 2498 }
2767 }); 2499 });
2768 2500
2769 test_environment.on_tests_ready(); 2501 test_environment.on_tests_ready();
2770 2502
2771 })(); 2503 })();
2772 // vim: set expandtab shiftwidth=4 tabstop=4: 2504 // vim: set expandtab shiftwidth=4 tabstop=4:
OLDNEW
« no previous file with comments | « no previous file | LayoutTests/http/tests/security/suborigins/multiple-suborigins-disallowed-expected.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698