3 # Any copyright is dedicated to the Public Domain.
4 # http://creativecommons.org/publicdomain/zero/1.0/
7 from __future__
import with_statement
8 import sys
, os
, unittest
, tempfile
, shutil
11 from StringIO
import StringIO
12 from xml
.etree
.ElementTree
import ElementTree
14 from mozbuild
.base
import MozbuildObject
15 os
.environ
.pop('MOZ_OBJDIR', None)
16 build_obj
= MozbuildObject
.from_environment()
18 from runxpcshelltests
import XPCShellTests
20 mozinfo
.find_and_update_from_json()
22 objdir
= build_obj
.topobjdir
.encode("utf-8")
25 from buildconfig
import substs
26 xpcshellBin
= os
.path
.join(objdir
, "dist", substs
['MOZ_MACBUNDLE_NAME'], "Contents", "MacOS", "xpcshell")
28 xpcshellBin
= os
.path
.join(objdir
, "dist", "bin", "xpcshell")
29 if sys
.platform
== "win32":
32 SIMPLE_PASSING_TEST
= "function run_test() { do_check_true(true); }"
33 SIMPLE_FAILING_TEST
= "function run_test() { do_check_true(false); }"
36 function run_test() { run_next_test(); }
38 add_test(function test_simple() {
44 ADD_TEST_FAILING
= '''
45 function run_test() { run_next_test(); }
47 add_test(function test_failing() {
53 CHILD_TEST_PASSING
= '''
54 function run_test () { run_next_test(); }
56 add_test(function test_child_simple () {
57 run_test_in_child("test_pass.js");
62 CHILD_TEST_FAILING
= '''
63 function run_test () { run_next_test(); }
65 add_test(function test_child_simple () {
66 run_test_in_child("test_fail.js");
72 function run_test () { run_next_test(); }
74 add_test(function test_child_simple () {
75 do_test_pending("hang test");
76 do_load_child_test_harness();
77 sendCommand("_log('child_test_start', {_message: 'CHILD-TEST-STARTED'}); " +
78 + "const _TEST_FILE=['test_pass.js']; _execute_test(); ",
85 Components.utils.import("resource://gre/modules/Promise.jsm");
87 function run_test() { run_next_test(); }
89 add_task(function test_task() {
90 yield Promise.resolve(true);
91 yield Promise.resolve(false);
95 ADD_TASK_MULTIPLE
= '''
96 Components.utils.import("resource://gre/modules/Promise.jsm");
98 function run_test() { run_next_test(); }
100 add_task(function test_task() {
101 yield Promise.resolve(true);
104 add_task(function test_2() {
105 yield Promise.resolve(true);
109 ADD_TASK_REJECTED
= '''
110 Components.utils.import("resource://gre/modules/Promise.jsm");
112 function run_test() { run_next_test(); }
114 add_task(function test_failing() {
115 yield Promise.reject(new Error("I fail."));
119 ADD_TASK_FAILURE_INSIDE
= '''
120 Components.utils.import("resource://gre/modules/Promise.jsm");
122 function run_test() { run_next_test(); }
124 add_task(function test() {
125 let result = yield Promise.resolve(false);
127 do_check_true(result);
131 ADD_TASK_RUN_NEXT_TEST
= '''
132 function run_test() { run_next_test(); }
134 add_task(function () {
141 ADD_TASK_STACK_TRACE
= '''
142 Components.utils.import("resource://gre/modules/Promise.jsm", this);
144 function run_test() { run_next_test(); }
146 add_task(function* this_test_will_fail() {
147 for (let i = 0; i < 10; ++i) {
148 yield Promise.resolve();
154 ADD_TASK_STACK_TRACE_WITHOUT_STAR
= '''
155 Components.utils.import("resource://gre/modules/Promise.jsm", this);
157 function run_test() { run_next_test(); }
159 add_task(function this_test_will_fail() {
160 for (let i = 0; i < 10; ++i) {
161 yield Promise.resolve();
167 ADD_TEST_THROW_STRING
= '''
168 function run_test() {do_throw("Passing a string to do_throw")};
171 ADD_TEST_THROW_OBJECT
= '''
173 message: "Error object",
174 fileName: "failure.js",
175 stack: "ERROR STACK",
176 toString: function() {return this.message;}
178 function run_test() {do_throw(error)};
181 ADD_TEST_REPORT_OBJECT
= '''
183 message: "Error object",
184 fileName: "failure.js",
185 stack: "ERROR STACK",
186 toString: function() {return this.message;}
188 function run_test() {do_report_unexpected_exception(error)};
191 # A test for genuine JS-generated Error objects
192 ADD_TEST_REPORT_REF_ERROR
= '''
193 function run_test() {
196 obj.noSuchFunction();
199 do_report_unexpected_exception(error);
204 # A test for failure to load a test due to a syntax error
205 LOAD_ERROR_SYNTAX_ERROR
= '''
209 # A test for failure to load a test due to an error other than a syntax error
210 LOAD_ERROR_OTHER_ERROR
= '''
211 function run_test() {
213 return "foo"; // can't use return in a generator!
217 # A test for asynchronous cleanup functions
219 function run_test() {
220 Components.utils.import("resource://gre/modules/Promise.jsm", this);
222 // The list of checkpoints in the order we encounter them.
223 let checkpoints = [];
225 // Cleanup tasks, in reverse order
226 do_register_cleanup(function cleanup_checkout() {
227 do_check_eq(checkpoints.join(""), "1234");
228 do_print("At this stage, the test has succeeded");
229 do_throw("Throwing an error to force displaying the log");
232 do_register_cleanup(function sync_cleanup_2() {
236 do_register_cleanup(function async_cleanup_2() {
237 let deferred = Promise.defer();
238 do_execute_soon(deferred.resolve);
239 return deferred.promise.then(function() {
244 do_register_cleanup(function sync_cleanup() {
248 do_register_cleanup(function async_cleanup() {
249 let deferred = Promise.defer();
250 do_execute_soon(deferred.resolve);
251 return deferred.promise.then(function() {
260 class XPCShellTestsTests(unittest
.TestCase
):
262 Yes, these are unit tests for a unit test harness.
265 self
.log
= StringIO()
266 self
.tempdir
= tempfile
.mkdtemp()
267 self
.x
= XPCShellTests(log
=self
.log
)
270 shutil
.rmtree(self
.tempdir
)
272 def writeFile(self
, name
, contents
):
274 Write |contents| to a file named |name| in the temp directory,
275 and return the full path to the file.
277 fullpath
= os
.path
.join(self
.tempdir
, name
)
278 with
open(fullpath
, "w") as f
:
282 def writeManifest(self
, tests
):
284 Write an xpcshell.ini in the temp directory and set
285 self.manifest to its pathname. |tests| is a list containing
286 either strings (for test names), or tuples with a test name
287 as the first element and manifest conditions as the following
292 testlines
.append("[%s]" % (t
if isinstance(t
, basestring
)
294 if isinstance(t
, tuple):
295 testlines
.extend(t
[1:])
296 self
.manifest
= self
.writeFile("xpcshell.ini", """
301 """ + "\n".join(testlines
))
303 def assertTestResult(self
, expected
, shuffle
=False, xunitFilename
=None, verbose
=False):
305 Assert that self.x.runTests with manifest=self.manifest
308 self
.assertEquals(expected
,
309 self
.x
.runTests(xpcshellBin
,
310 manifest
=self
.manifest
,
311 mozInfo
=mozinfo
.info
,
313 testsRootDir
=self
.tempdir
,
315 xunitFilename
=xunitFilename
,
317 msg
="""Tests should have %s, log:
321 """ % ("passed" if expected
else "failed", self
.log
.getvalue()))
323 def _assertLog(self
, s
, expected
):
324 l
= self
.log
.getvalue()
325 self
.assertEqual(expected
, s
in l
,
326 msg
="""Value %s %s in log:
329 ========""" % (s
, "expected" if expected
else "not expected", l
))
331 def assertInLog(self
, s
):
333 Assert that the string |s| is contained in self.log.
335 self
._assertLog
(s
, True)
337 def assertNotInLog(self
, s
):
339 Assert that the string |s| is not contained in self.log.
341 self
._assertLog
(s
, False)
345 Check that a simple test without any manifest conditions passes.
347 self
.writeFile("test_basic.js", SIMPLE_PASSING_TEST
)
348 self
.writeManifest(["test_basic.js"])
350 self
.assertTestResult(True)
351 self
.assertEquals(1, self
.x
.testCount
)
352 self
.assertEquals(1, self
.x
.passCount
)
353 self
.assertEquals(0, self
.x
.failCount
)
354 self
.assertEquals(0, self
.x
.todoCount
)
355 self
.assertInLog("TEST-PASS")
356 self
.assertNotInLog("TEST-UNEXPECTED-FAIL")
360 Check that a simple failing test without any manifest conditions fails.
362 self
.writeFile("test_basic.js", SIMPLE_FAILING_TEST
)
363 self
.writeManifest(["test_basic.js"])
365 self
.assertTestResult(False)
366 self
.assertEquals(1, self
.x
.testCount
)
367 self
.assertEquals(0, self
.x
.passCount
)
368 self
.assertEquals(1, self
.x
.failCount
)
369 self
.assertEquals(0, self
.x
.todoCount
)
370 self
.assertInLog("TEST-UNEXPECTED-FAIL")
371 self
.assertNotInLog("TEST-PASS")
373 @unittest.skipIf(build_obj
.defines
.get('MOZ_B2G'),
374 'selftests with child processes fail on b2g desktop builds')
375 def testChildPass(self
):
377 Check that a simple test running in a child process passes.
379 self
.writeFile("test_pass.js", SIMPLE_PASSING_TEST
)
380 self
.writeFile("test_child_pass.js", CHILD_TEST_PASSING
)
381 self
.writeManifest(["test_child_pass.js"])
383 self
.assertTestResult(True, verbose
=True)
384 self
.assertEquals(1, self
.x
.testCount
)
385 self
.assertEquals(1, self
.x
.passCount
)
386 self
.assertEquals(0, self
.x
.failCount
)
387 self
.assertEquals(0, self
.x
.todoCount
)
388 self
.assertInLog("TEST-PASS")
389 self
.assertInLog("CHILD-TEST-STARTED")
390 self
.assertInLog("CHILD-TEST-COMPLETED")
391 self
.assertNotInLog("TEST-UNEXPECTED-FAIL")
394 @unittest.skipIf(build_obj
.defines
.get('MOZ_B2G'),
395 'selftests with child processes fail on b2g desktop builds')
396 def testChildFail(self
):
398 Check that a simple failing test running in a child process fails.
400 self
.writeFile("test_fail.js", SIMPLE_FAILING_TEST
)
401 self
.writeFile("test_child_fail.js", CHILD_TEST_FAILING
)
402 self
.writeManifest(["test_child_fail.js"])
404 self
.assertTestResult(False)
405 self
.assertEquals(1, self
.x
.testCount
)
406 self
.assertEquals(0, self
.x
.passCount
)
407 self
.assertEquals(1, self
.x
.failCount
)
408 self
.assertEquals(0, self
.x
.todoCount
)
409 self
.assertInLog("TEST-UNEXPECTED-FAIL")
410 self
.assertInLog("CHILD-TEST-STARTED")
411 self
.assertInLog("CHILD-TEST-COMPLETED")
412 self
.assertNotInLog("TEST-PASS")
414 @unittest.skipIf(build_obj
.defines
.get('MOZ_B2G'),
415 'selftests with child processes fail on b2g desktop builds')
416 def testChildHang(self
):
418 Check that incomplete output from a child process results in a
421 self
.writeFile("test_pass.js", SIMPLE_PASSING_TEST
)
422 self
.writeFile("test_child_hang.js", CHILD_TEST_HANG
)
423 self
.writeManifest(["test_child_hang.js"])
425 self
.assertTestResult(False)
426 self
.assertEquals(1, self
.x
.testCount
)
427 self
.assertEquals(0, self
.x
.passCount
)
428 self
.assertEquals(1, self
.x
.failCount
)
429 self
.assertEquals(0, self
.x
.todoCount
)
430 self
.assertInLog("TEST-UNEXPECTED-FAIL")
431 self
.assertInLog("CHILD-TEST-STARTED")
432 self
.assertNotInLog("CHILD-TEST-COMPLETED")
433 self
.assertNotInLog("TEST-PASS")
435 def testSyntaxError(self
):
437 Check that running a test file containing a syntax error produces
438 a test failure and expected output.
440 self
.writeFile("test_syntax_error.js", '"')
441 self
.writeManifest(["test_syntax_error.js"])
443 self
.assertTestResult(False, verbose
=True)
444 self
.assertEquals(1, self
.x
.testCount
)
445 self
.assertEquals(0, self
.x
.passCount
)
446 self
.assertEquals(1, self
.x
.failCount
)
447 self
.assertEquals(0, self
.x
.todoCount
)
448 self
.assertInLog("TEST-UNEXPECTED-FAIL")
449 self
.assertNotInLog("TEST-PASS")
451 def testPassFail(self
):
453 Check that running more than one test works.
455 self
.writeFile("test_pass.js", SIMPLE_PASSING_TEST
)
456 self
.writeFile("test_fail.js", SIMPLE_FAILING_TEST
)
457 self
.writeManifest(["test_pass.js", "test_fail.js"])
459 self
.assertTestResult(False)
460 self
.assertEquals(2, self
.x
.testCount
)
461 self
.assertEquals(1, self
.x
.passCount
)
462 self
.assertEquals(1, self
.x
.failCount
)
463 self
.assertEquals(0, self
.x
.todoCount
)
464 self
.assertInLog("TEST-PASS")
465 self
.assertInLog("TEST-UNEXPECTED-FAIL")
469 Check that a simple failing test skipped in the manifest does
472 self
.writeFile("test_basic.js", SIMPLE_FAILING_TEST
)
473 self
.writeManifest([("test_basic.js", "skip-if = true")])
474 self
.assertTestResult(True)
475 self
.assertEquals(1, self
.x
.testCount
)
476 self
.assertEquals(0, self
.x
.passCount
)
477 self
.assertEquals(0, self
.x
.failCount
)
478 self
.assertEquals(0, self
.x
.todoCount
)
479 self
.assertNotInLog("TEST-UNEXPECTED-FAIL")
480 self
.assertNotInLog("TEST-PASS")
482 def testKnownFail(self
):
484 Check that a simple failing test marked as known-fail in the manifest
485 does not cause failure.
487 self
.writeFile("test_basic.js", SIMPLE_FAILING_TEST
)
488 self
.writeManifest([("test_basic.js", "fail-if = true")])
489 self
.assertTestResult(True)
490 self
.assertEquals(1, self
.x
.testCount
)
491 self
.assertEquals(0, self
.x
.passCount
)
492 self
.assertEquals(0, self
.x
.failCount
)
493 self
.assertEquals(1, self
.x
.todoCount
)
494 self
.assertInLog("TEST-KNOWN-FAIL")
495 # This should be suppressed because the harness doesn't include
496 # the full log from the xpcshell run when things pass.
497 self
.assertNotInLog("TEST-UNEXPECTED-FAIL")
498 self
.assertNotInLog("TEST-PASS")
500 def testUnexpectedPass(self
):
502 Check that a simple failing test marked as known-fail in the manifest
503 that passes causes an unexpected pass.
505 self
.writeFile("test_basic.js", SIMPLE_PASSING_TEST
)
506 self
.writeManifest([("test_basic.js", "fail-if = true")])
507 self
.assertTestResult(False)
508 self
.assertEquals(1, self
.x
.testCount
)
509 self
.assertEquals(0, self
.x
.passCount
)
510 self
.assertEquals(1, self
.x
.failCount
)
511 self
.assertEquals(0, self
.x
.todoCount
)
512 # From the outer (Python) harness
513 self
.assertInLog("TEST-UNEXPECTED-PASS")
514 self
.assertNotInLog("TEST-KNOWN-FAIL")
515 # From the inner (JS) harness
516 self
.assertInLog("TEST-PASS")
518 def testReturnNonzero(self
):
520 Check that a test where xpcshell returns nonzero fails.
522 self
.writeFile("test_error.js", "throw 'foo'")
523 self
.writeManifest(["test_error.js"])
525 self
.assertTestResult(False)
526 self
.assertEquals(1, self
.x
.testCount
)
527 self
.assertEquals(0, self
.x
.passCount
)
528 self
.assertEquals(1, self
.x
.failCount
)
529 self
.assertEquals(0, self
.x
.todoCount
)
530 self
.assertInLog("TEST-UNEXPECTED-FAIL")
531 self
.assertNotInLog("TEST-PASS")
533 def testAddTestSimple(self
):
535 Ensure simple add_test() works.
537 self
.writeFile("test_add_test_simple.js", ADD_TEST_SIMPLE
)
538 self
.writeManifest(["test_add_test_simple.js"])
540 self
.assertTestResult(True)
541 self
.assertEquals(1, self
.x
.testCount
)
542 self
.assertEquals(1, self
.x
.passCount
)
543 self
.assertEquals(0, self
.x
.failCount
)
545 def testLogCorrectFileName(self
):
547 Make sure a meaningful filename and line number is logged
550 self
.writeFile("test_add_test_simple.js", ADD_TEST_SIMPLE
)
551 self
.writeManifest(["test_add_test_simple.js"])
553 self
.assertTestResult(True, verbose
=True)
554 self
.assertInLog("true == true")
555 self
.assertNotInLog("[do_check_true :")
556 self
.assertInLog("[test_simple : 5]")
558 def testAddTestFailing(self
):
560 Ensure add_test() with a failing test is reported.
562 self
.writeFile("test_add_test_failing.js", ADD_TEST_FAILING
)
563 self
.writeManifest(["test_add_test_failing.js"])
565 self
.assertTestResult(False)
566 self
.assertEquals(1, self
.x
.testCount
)
567 self
.assertEquals(0, self
.x
.passCount
)
568 self
.assertEquals(1, self
.x
.failCount
)
570 def testAddTaskTestSingle(self
):
572 Ensure add_test_task() with a single passing test works.
574 self
.writeFile("test_add_task_simple.js", ADD_TASK_SINGLE
)
575 self
.writeManifest(["test_add_task_simple.js"])
577 self
.assertTestResult(True)
578 self
.assertEquals(1, self
.x
.testCount
)
579 self
.assertEquals(1, self
.x
.passCount
)
580 self
.assertEquals(0, self
.x
.failCount
)
582 def testAddTaskTestMultiple(self
):
584 Ensure multiple calls to add_test_task() work as expected.
586 self
.writeFile("test_add_task_multiple.js",
588 self
.writeManifest(["test_add_task_multiple.js"])
590 self
.assertTestResult(True)
591 self
.assertEquals(1, self
.x
.testCount
)
592 self
.assertEquals(1, self
.x
.passCount
)
593 self
.assertEquals(0, self
.x
.failCount
)
595 def testAddTaskTestRejected(self
):
597 Ensure rejected task reports as failure.
599 self
.writeFile("test_add_task_rejected.js",
601 self
.writeManifest(["test_add_task_rejected.js"])
603 self
.assertTestResult(False)
604 self
.assertEquals(1, self
.x
.testCount
)
605 self
.assertEquals(0, self
.x
.passCount
)
606 self
.assertEquals(1, self
.x
.failCount
)
608 def testAddTaskTestFailureInside(self
):
610 Ensure tests inside task are reported as failures.
612 self
.writeFile("test_add_task_failure_inside.js",
613 ADD_TASK_FAILURE_INSIDE
)
614 self
.writeManifest(["test_add_task_failure_inside.js"])
616 self
.assertTestResult(False)
617 self
.assertEquals(1, self
.x
.testCount
)
618 self
.assertEquals(0, self
.x
.passCount
)
619 self
.assertEquals(1, self
.x
.failCount
)
621 def testAddTaskRunNextTest(self
):
623 Calling run_next_test() from inside add_task() results in failure.
625 self
.writeFile("test_add_task_run_next_test.js",
626 ADD_TASK_RUN_NEXT_TEST
)
627 self
.writeManifest(["test_add_task_run_next_test.js"])
629 self
.assertTestResult(False)
630 self
.assertEquals(1, self
.x
.testCount
)
631 self
.assertEquals(0, self
.x
.passCount
)
632 self
.assertEquals(1, self
.x
.failCount
)
634 def testAddTaskStackTrace(self
):
636 Ensuring that calling Assert.ok(false) from inside add_task()
637 results in a human-readable stack trace.
639 self
.writeFile("test_add_task_stack_trace.js",
640 ADD_TASK_STACK_TRACE
)
641 self
.writeManifest(["test_add_task_stack_trace.js"])
643 self
.assertTestResult(False)
644 self
.assertInLog("this_test_will_fail")
645 self
.assertInLog("run_next_test")
646 self
.assertInLog("run_test")
647 self
.assertNotInLog("Task.jsm")
649 def testAddTaskStackTraceWithoutStar(self
):
651 Ensuring that calling Assert.ok(false) from inside add_task()
652 results in a human-readable stack trace. This variant uses deprecated
653 `function()` syntax instead of now standard `function*()`.
655 self
.writeFile("test_add_task_stack_trace_without_star.js",
656 ADD_TASK_STACK_TRACE
)
657 self
.writeManifest(["test_add_task_stack_trace_without_star.js"])
659 self
.assertTestResult(False)
660 self
.assertInLog("this_test_will_fail")
661 self
.assertInLog("run_next_test")
662 self
.assertInLog("run_test")
663 self
.assertNotInLog("Task.jsm")
665 def testMissingHeadFile(self
):
667 Ensure that missing head file results in fatal error.
669 self
.writeFile("test_basic.js", SIMPLE_PASSING_TEST
)
670 self
.writeManifest([("test_basic.js", "head = missing.js")])
675 # The actual return value is never checked because we raise.
676 self
.assertTestResult(True)
677 except Exception, ex
:
679 self
.assertEquals(ex
.message
[0:9], "head file")
681 self
.assertTrue(raised
)
683 def testMissingTailFile(self
):
685 Ensure that missing tail file results in fatal error.
687 self
.writeFile("test_basic.js", SIMPLE_PASSING_TEST
)
688 self
.writeManifest([("test_basic.js", "tail = missing.js")])
693 self
.assertTestResult(True)
694 except Exception, ex
:
696 self
.assertEquals(ex
.message
[0:9], "tail file")
698 self
.assertTrue(raised
)
700 def testRandomExecution(self
):
702 Check that random execution doesn't break.
705 for i
in range(0, 10):
706 filename
= "test_pass_%d.js" % i
707 self
.writeFile(filename
, SIMPLE_PASSING_TEST
)
708 manifest
.append(filename
)
710 self
.writeManifest(manifest
)
711 self
.assertTestResult(True, shuffle
=True)
712 self
.assertEquals(10, self
.x
.testCount
)
713 self
.assertEquals(10, self
.x
.passCount
)
715 def testXunitOutput(self
):
717 Check that Xunit XML files are written.
719 self
.writeFile("test_00.js", SIMPLE_PASSING_TEST
)
720 self
.writeFile("test_01.js", SIMPLE_FAILING_TEST
)
721 self
.writeFile("test_02.js", SIMPLE_PASSING_TEST
)
726 ("test_02.js", "skip-if = true")
729 self
.writeManifest(manifest
)
731 filename
= os
.path
.join(self
.tempdir
, "xunit.xml")
733 self
.assertTestResult(False, xunitFilename
=filename
)
735 self
.assertTrue(os
.path
.exists(filename
))
736 self
.assertTrue(os
.path
.getsize(filename
) > 0)
740 suite
= tree
.getroot()
742 self
.assertTrue(suite
is not None)
743 self
.assertEqual(suite
.get("tests"), "3")
744 self
.assertEqual(suite
.get("failures"), "1")
745 self
.assertEqual(suite
.get("skip"), "1")
747 testcases
= suite
.findall("testcase")
748 self
.assertEqual(len(testcases
), 3)
750 for testcase
in testcases
:
751 attributes
= testcase
.keys()
752 self
.assertTrue("classname" in attributes
)
753 self
.assertTrue("name" in attributes
)
754 self
.assertTrue("time" in attributes
)
756 self
.assertTrue(testcases
[1].find("failure") is not None)
757 self
.assertTrue(testcases
[2].find("skipped") is not None)
759 def testDoThrowString(self
):
761 Check that do_throw produces reasonable messages when the
762 input is a string instead of an object
764 self
.writeFile("test_error.js", ADD_TEST_THROW_STRING
)
765 self
.writeManifest(["test_error.js"])
767 self
.assertTestResult(False)
768 self
.assertInLog("TEST-UNEXPECTED-FAIL")
769 self
.assertInLog("Passing a string to do_throw")
770 self
.assertNotInLog("TEST-PASS")
772 def testDoThrowForeignObject(self
):
774 Check that do_throw produces reasonable messages when the
775 input is a generic object with 'filename', 'message' and 'stack' attributes
776 but 'object instanceof Error' returns false
778 self
.writeFile("test_error.js", ADD_TEST_THROW_OBJECT
)
779 self
.writeManifest(["test_error.js"])
781 self
.assertTestResult(False)
782 self
.assertInLog("TEST-UNEXPECTED-FAIL")
783 self
.assertInLog("failure.js")
784 self
.assertInLog("Error object")
785 self
.assertInLog("ERROR STACK")
786 self
.assertNotInLog("TEST-PASS")
788 def testDoReportForeignObject(self
):
790 Check that do_report_unexpected_exception produces reasonable messages when the
791 input is a generic object with 'filename', 'message' and 'stack' attributes
792 but 'object instanceof Error' returns false
794 self
.writeFile("test_error.js", ADD_TEST_REPORT_OBJECT
)
795 self
.writeManifest(["test_error.js"])
797 self
.assertTestResult(False)
798 self
.assertInLog("TEST-UNEXPECTED-FAIL")
799 self
.assertInLog("failure.js")
800 self
.assertInLog("Error object")
801 self
.assertInLog("ERROR STACK")
802 self
.assertNotInLog("TEST-PASS")
804 def testDoReportRefError(self
):
806 Check that do_report_unexpected_exception produces reasonable messages when the
807 input is a JS-generated Error
809 self
.writeFile("test_error.js", ADD_TEST_REPORT_REF_ERROR
)
810 self
.writeManifest(["test_error.js"])
812 self
.assertTestResult(False)
813 self
.assertInLog("TEST-UNEXPECTED-FAIL")
814 self
.assertInLog("test_error.js")
815 self
.assertInLog("obj.noSuchFunction is not a function")
816 self
.assertInLog("run_test@")
817 self
.assertNotInLog("TEST-PASS")
819 def testDoReportSyntaxError(self
):
821 Check that attempting to load a test file containing a syntax error
822 generates details of the error in the log
824 self
.writeFile("test_error.js", LOAD_ERROR_SYNTAX_ERROR
)
825 self
.writeManifest(["test_error.js"])
827 self
.assertTestResult(False)
828 self
.assertInLog("TEST-UNEXPECTED-FAIL")
829 self
.assertInLog("test_error.js")
830 self
.assertInLog("test_error.js contains SyntaxError")
831 self
.assertInLog("Diagnostic: SyntaxError: missing formal parameter at")
832 self
.assertInLog("test_error.js:3")
833 self
.assertNotInLog("TEST-PASS")
835 def testDoReportNonSyntaxError(self
):
837 Check that attempting to load a test file containing an error other
838 than a syntax error generates details of the error in the log
840 self
.writeFile("test_error.js", LOAD_ERROR_OTHER_ERROR
)
841 self
.writeManifest(["test_error.js"])
843 self
.assertTestResult(False)
844 self
.assertInLog("TEST-UNEXPECTED-FAIL")
845 self
.assertInLog("Diagnostic: TypeError: generator function run_test returns a value at")
846 self
.assertInLog("test_error.js:4")
847 self
.assertNotInLog("TEST-PASS")
849 def testAsyncCleanup(self
):
851 Check that do_register_cleanup handles nicely cleanup tasks that
854 self
.writeFile("test_asyncCleanup.js", ASYNC_CLEANUP
)
855 self
.writeManifest(["test_asyncCleanup.js"])
856 self
.assertTestResult(False)
857 self
.assertInLog("\"1234\" == \"1234\"")
858 self
.assertInLog("At this stage, the test has succeeded")
859 self
.assertInLog("Throwing an error to force displaying the log")
861 if __name__
== "__main__":