123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340 |
- // Copyright 2009 The Closure Library Authors. All Rights Reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS-IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- goog.provide('goog.testing.ContinuationTestCaseTest');
- goog.setTestOnly('goog.testing.ContinuationTestCaseTest');
- goog.require('goog.events');
- goog.require('goog.events.EventTarget');
- goog.require('goog.testing.ContinuationTestCase');
- goog.require('goog.testing.MockClock');
- goog.require('goog.testing.PropertyReplacer');
- goog.require('goog.testing.TestCase');
- goog.require('goog.testing.jsunit');
- /**
- * @fileoverview This test file uses the ContinuationTestCase to test itself,
- * which is a little confusing. It's also difficult to write a truly effective
- * test, since testing a failure causes an actual failure in the test runner.
- * All tests have been manually verified using a sophisticated combination of
- * alerts and false assertions.
- */
- var testCase = new goog.testing.ContinuationTestCase('Continuation Test Case');
- testCase.autoDiscoverTests();
- // Standalone Closure Test Runner.
- if (typeof G_testRunner != 'undefined') {
- G_testRunner.initialize(testCase);
- }
- var clock = new goog.testing.MockClock();
- var count = 0;
- var stubs = new goog.testing.PropertyReplacer();
- function setUpPage() {
- count = testCase.getCount();
- }
- /**
- * Resets the mock clock. Includes a wait step to verify that setUp routines
- * can contain continuations.
- */
- function setUp() {
- waitForTimeout(function() {
- // Pointless assertion to verify that setUp methods can contain waits.
- assertEquals(count, testCase.getCount());
- }, 0);
- clock.reset();
- }
- /**
- * Uninstalls the mock clock if it was installed, and restores the Step timeout
- * functions to the default window implementations.
- */
- function tearDown() {
- clock.uninstall();
- stubs.reset();
- waitForTimeout(function() {
- // Pointless assertion to verify that tearDown methods can contain waits.
- assertTrue(testCase.now() >= testCase.startTime_);
- }, 0);
- }
- /**
- * Installs the Mock Clock and replaces the Step timeouts with the mock
- * implementations.
- */
- function installMockClock() {
- clock.install();
- // Overwrite the "protected" setTimeout and clearTimeout with the versions
- // replaced by MockClock. Normal tests should never do this, but we need to
- // test the ContinuationTest itself.
- stubs.set(
- goog.testing.ContinuationTestCase.Step, 'protectedClearTimeout_',
- window.clearTimeout);
- stubs.set(
- goog.testing.ContinuationTestCase.Step, 'protectedSetTimeout_',
- window.setTimeout);
- }
- /**
- * @return {goog.testing.ContinuationTestCase.Step} A generic step in a
- * continuation test.
- */
- function getSampleStep() {
- return new goog.testing.ContinuationTestCase.Step('test', function() {});
- }
- /**
- * @return {goog.testing.ContinuationTestCase.ContinuationTest} A simple
- * continuation test with generic setUp, test, and tearDown functions.
- */
- function getSampleTest() {
- var setupStep = new goog.testing.TestCase.Test('setup', function() {});
- var testStep = new goog.testing.TestCase.Test('test', function() {});
- var teardownStep = new goog.testing.TestCase.Test('teardown', function() {});
- return new goog.testing.ContinuationTestCase.ContinuationTest(
- setupStep, testStep, teardownStep);
- }
- function testStepWaiting() {
- var step = getSampleStep();
- assertTrue(step.waiting);
- }
- function testStepSetTimeout() {
- installMockClock();
- var step = getSampleStep();
- var timeoutReached = false;
- step.setTimeout(function() { timeoutReached = true }, 100);
- clock.tick(50);
- assertFalse(timeoutReached);
- clock.tick(50);
- assertTrue(timeoutReached);
- }
- function testStepClearTimeout() {
- var step = new goog.testing.ContinuationTestCase.Step('test', function() {});
- var timeoutReached = false;
- step.setTimeout(function() { timeoutReached = true }, 100);
- clock.tick(50);
- assertFalse(timeoutReached);
- step.clearTimeout();
- clock.tick(50);
- assertFalse(timeoutReached);
- }
- function testTestPhases() {
- var test = getSampleTest();
- assertEquals('setup', test.getCurrentPhase()[0].name);
- test.cancelCurrentPhase();
- assertEquals('test', test.getCurrentPhase()[0].name);
- test.cancelCurrentPhase();
- assertEquals('teardown', test.getCurrentPhase()[0].name);
- test.cancelCurrentPhase();
- assertNull(test.getCurrentPhase());
- }
- function testTestSetError() {
- var test = getSampleTest();
- var error1 = new Error('Oh noes!');
- var error2 = new Error('B0rken.');
- assertNull(test.getError());
- test.setError(error1);
- assertEquals(error1, test.getError());
- test.setError(error2);
- assertEquals(
- 'Once an error has been set, it should not be overwritten.', error1,
- test.getError());
- }
- function testAddStep() {
- var test = getSampleTest();
- var step = getSampleStep();
- // Try adding a step to each phase and then cancelling the phase.
- for (var i = 0; i < 3; i++) {
- assertEquals(1, test.getCurrentPhase().length);
- test.addStep(step);
- assertEquals(2, test.getCurrentPhase().length);
- assertEquals(step, test.getCurrentPhase()[1]);
- test.cancelCurrentPhase();
- }
- assertNull(test.getCurrentPhase());
- }
- function testCancelTestPhase() {
- var test = getSampleTest();
- test.cancelTestPhase();
- assertEquals('teardown', test.getCurrentPhase()[0].name);
- test = getSampleTest();
- test.cancelCurrentPhase();
- test.cancelTestPhase();
- assertEquals('teardown', test.getCurrentPhase()[0].name);
- test = getSampleTest();
- test.cancelTestPhase();
- test.cancelTestPhase();
- assertEquals('teardown', test.getCurrentPhase()[0].name);
- }
- function testWaitForTimeout() {
- var reachedA = false;
- var reachedB = false;
- var reachedC = false;
- waitForTimeout(function a() {
- reachedA = true;
- assertTrue('A must be true at callback a.', reachedA);
- assertFalse('B must be false at callback a.', reachedB);
- assertFalse('C must be false at callback a.', reachedC);
- }, 10);
- waitForTimeout(function b() {
- reachedB = true;
- assertTrue('A must be true at callback b.', reachedA);
- assertTrue('B must be true at callback b.', reachedB);
- assertFalse('C must be false at callback b.', reachedC);
- }, 20);
- waitForTimeout(function c() {
- reachedC = true;
- assertTrue('A must be true at callback c.', reachedA);
- assertTrue('B must be true at callback c.', reachedB);
- assertTrue('C must be true at callback c.', reachedC);
- }, 20);
- assertFalse('a', reachedA);
- assertFalse('b', reachedB);
- assertFalse('c', reachedC);
- }
- function testWaitForEvent() {
- var et = new goog.events.EventTarget();
- var eventFired = false;
- goog.events.listen(et, 'testPrefire', function() {
- eventFired = true;
- et.dispatchEvent('test');
- });
- waitForEvent(et, 'test', function() { assertTrue(eventFired); });
- et.dispatchEvent('testPrefire');
- }
- function testWaitForCondition() {
- var counter = 0;
- waitForCondition(
- function() { return ++counter >= 2; },
- function() { assertEquals(2, counter); }, 10, 200);
- }
- function testOutOfOrderWaits() {
- var counter = 0;
- // Note that if the delta between the timeout is too small, two
- // continuation may be invoked at the same timer tick, using the
- // registration order.
- waitForTimeout(function() { assertEquals(3, ++counter); }, 200);
- waitForTimeout(function() { assertEquals(1, ++counter); }, 0);
- waitForTimeout(function() { assertEquals(2, ++counter); }, 100);
- }
- /*
- * Any of the test functions below (except the condition check passed into
- * waitForCondition) can raise an assertion successfully. Any level of nested
- * test steps should be possible, in any configuration.
- */
- var testObj;
- function testCrazyNestedWaitFunction() {
- testObj = {lock: true, et: new goog.events.EventTarget(), steps: 0};
- waitForTimeout(handleTimeout, 10);
- waitForEvent(testObj.et, 'test', handleEvent);
- waitForCondition(condition, handleCondition, 1);
- }
- function handleTimeout() {
- testObj.steps++;
- assertEquals('handleTimeout should be called first.', 1, testObj.steps);
- waitForTimeout(fireEvent, 10);
- }
- function fireEvent() {
- testObj.steps++;
- assertEquals('fireEvent should be called second.', 2, testObj.steps);
- testObj.et.dispatchEvent('test');
- }
- function handleEvent() {
- testObj.steps++;
- assertEquals('handleEvent should be called third.', 3, testObj.steps);
- testObj.lock = false;
- }
- function condition() {
- return !testObj.lock;
- }
- function handleCondition() {
- assertFalse(testObj.lock);
- testObj.steps++;
- assertEquals('handleCondition should be called last.', 4, testObj.steps);
- }
|