1558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
2558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// found in the LICENSE file.
4558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
5558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch/**
6558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch * Tests that an observation matches the expected value.
7558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch * @param {Object} expected The expected value.
8558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch * @param {Object} observed The actual value.
9558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch * @param {string=} opt_message Optional message to include with a test
10558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch *     failure.
11558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch */
12558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochfunction assertEquals(expected, observed, opt_message) {
13558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (observed !== expected) {
14558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    var message = 'Assertion Failed\n  Observed: ' + observed +
153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        '\n  Expected: ' + expected;
16558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    if (opt_message)
17558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      message = message + '\n  ' + opt_message;
18558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    throw new Error(message);
19558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
20558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
21558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
22558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch/**
23558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch * Verifies that a test result is true.
24558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch * @param {boolean} observed The observed value.
25558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch * @param {string=} opt_message Optional message to include with a test
26558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch *     failure.
27558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch */
28558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochfunction assertTrue(observed, opt_message) {
29558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  assertEquals(true, observed, opt_message);
30558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
31558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
32558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch/**
33558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch * Verifies that a test result is false.
34558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch * @param {boolean} observed The observed value.
35558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch * @param {string=} opt_message Optional message to include with a test
36558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch *     failure.
37558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch */
38558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochfunction assertFalse(observed, opt_message) {
39558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  assertEquals(false, observed, opt_message);
40558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
41558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
42558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch/**
43558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch * Verifies that the observed and reference values differ.
44558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch * @param {Object} reference The target value for comparison.
45558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch * @param {Object} observed The test result.
46558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch * @param {string=} opt_message Optional message to include with a test
47558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch *     failure.
48558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch */
49558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochfunction assertNotEqual(reference, observed, opt_message) {
50558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (observed === reference) {
51558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    var message = 'Assertion Failed\n  Observed: ' + observed +
523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        '\n  Reference: ' + reference;
53558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    if (opt_message)
54558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      message = message + '\n  ' + opt_message;
55558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    throw new Error(message);
56558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
57558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
58558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
59558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch/**
60558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch * Verifies that a test evaluation results in an exception.
61558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch * @param {!Function} f The test function.
62558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch */
63558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochfunction assertThrows(f) {
64558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  var triggeredError = false;
65558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  try {
66558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    f();
673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  } catch(err) {
68558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    triggeredError = true;
69558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
70558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (!triggeredError)
71558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    throw new Error('Assertion Failed: throw expected.');
72558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
73558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
74558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch/**
75558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch * Verifies that the contents of the expected and observed arrays match.
76558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch * @param {!Array} expected The expected result.
77558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch * @param {!Array} observed The actual result.
78558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch */
79558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochfunction assertArrayEquals(expected, observed) {
80558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  var v1 = Array.prototype.slice.call(expected);
81558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  var v2 = Array.prototype.slice.call(observed);
82558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  var equal = v1.length == v2.length;
83558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (equal) {
84558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    for (var i = 0; i < v1.length; i++) {
85558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      if (v1[i] !== v2[i]) {
86558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        equal = false;
87558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        break;
88558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      }
89558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    }
90558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
91558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (!equal) {
92558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    var message =
933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)       ['Assertion Failed', 'Observed: ' + v2, 'Expected: ' + v1].join('\n  ');
94558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    throw new Error(message);
95558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
96558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
97558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
98558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch/**
99558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch * Verifies that the expected and observed result have the same content.
100558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch * @param {*} expected The expected result.
101558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch * @param {*} observed The actual result.
102558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch */
103558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochfunction assertDeepEquals(expected, observed, opt_message) {
104558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (typeof expected == 'object' && expected != null) {
105558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    assertNotEqual(null, observed);
106558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    for (var key in expected) {
107558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      assertTrue(key in observed, opt_message);
108558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      assertDeepEquals(expected[key], observed[key], opt_message);
109558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    }
110558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    for (var key in observed) {
111558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      assertTrue(key in expected, opt_message);
112558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    }
113558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  } else {
114558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    assertEquals(expected, observed, opt_message);
115558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
116558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
117558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
118558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch/**
119558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch * Defines runTests.
120558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch */
121558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch(function(exports) {
122558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  /**
123558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch   * List of test cases.
124558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch   * @type {Array.<string>} List of function names for tests to run.
125558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch   */
126558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  var testCases = [];
127558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
128558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  /**
129558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch   * Indicates if all tests have run successfully.
130558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch   * @type {boolean}
131558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch   */
132558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  var cleanTestRun = true;
133558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
134558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  /**
135558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch   * Armed during setup of a test to call the matching tear down code.
136558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch   * @type {Function}
137558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch   */
138558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  var pendingTearDown = null;
139558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
140558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  /**
141558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch   * Runs all functions starting with test and reports success or
142558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch   * failure of the test suite.
143558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch   */
144558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  function runTests() {
145558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    for (var name in window) {
146558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      if (typeof window[name] == 'function' && /^test/.test(name))
147558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        testCases.push(name);
148558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    }
149558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    if (!testCases.length) {
150558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      console.error('Failed to find test cases.');
151558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      cleanTestRun = false;
152558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    }
153558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    continueTesting();
154558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
155558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
156558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  /**
157558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch   * Runs the next test in the queue. Reports the test results if the queue is
158558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch   * empty.
15968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)   * @param {boolean=} opt_asyncTestFailure Optional parameter indicated if the
16068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)   *     last asynchronous test failed.
161558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch   */
16268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  function continueTesting(opt_asyncTestFailure) {
16368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (opt_asyncTestFailure)
16468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      cleanTestRun = false;
16568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    var done = false;
166558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    if (pendingTearDown) {
167558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      pendingTearDown();
168558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      pendingTearDown = null;
169558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    }
170558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    if (testCases.length > 0) {
171558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      var fn = testCases.pop();
172558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      var isAsyncTest = window[fn].length;
173558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      try {
174558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        if (window.setUp)
175558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch          window.setUp();
176558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        pendingTearDown = window.tearDown;
177558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        window[fn](continueTesting);
1783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      } catch(err) {
179558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        console.error('Failure in test ' + fn + '\n' + err);
180558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        console.log(err.stack);
181558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        cleanTestRun = false;
182558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      }
183558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      // Asynchronous tests must manually call continueTesting when complete.
184558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      if (!isAsyncTest)
185558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        continueTesting();
1863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    } else {
18768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      done = true;
1883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      endTests(cleanTestRun);
189558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    }
19068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (!done) {
191558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      domAutomationController.setAutomationId(1);
192558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      domAutomationController.send('PENDING');
193558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    }
194558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  };
195558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
196558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  exports.runTests = runTests;
197558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch})(this);
198558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)/**
2003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * Signals completion of a test.
2013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) * @param {boolean} success Indicates if the test completed successfully.
2023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) */
2033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)function endTests(success) {
2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  domAutomationController.setAutomationId(1);
2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  domAutomationController.send(success ? 'SUCCESS' : 'FAILURE');
2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)window.onerror = function() {
2093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  endTests(false);
2103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
211