1<!DOCTYPE html>
2<!--
3Copyright (c) 2014 The Chromium Authors. All rights reserved.
4Use of this source code is governed by a BSD-style license that can be
5found in the LICENSE file.
6-->
7<link rel="import" href="/tracing/base/guid.html">
8<link rel="import" href="/tracing/base/statistics.html">
9<link rel="import" href="/tracing/base/unittest/test_case.html">
10<link rel="import" href="/tracing/base/unittest/constants.html">
11<script>
12'use strict';
13
14tr.exportTo('tr.b.unittest', function() {
15  var TestCase = tr.b.unittest.TestCase;
16  var PerfTestCase = tr.b.unittest.PerfTestCase;
17
18  var TestTypes = tr.b.unittest.TestTypes;
19
20  function TestSuite(name, suiteConstructor) {
21    this.guid = tr.b.GUID.allocate();
22    this.name_ = name;
23    this.tests_ = [];
24    this.testNames_ = {}; // For dupe checking.
25
26    global.flakyTest = function(testCaseOrName, opt_testFn, opt_options) {
27      if (testCaseOrName instanceof TestCase) {
28        testCaseOrName.options['flaky'] = true;
29        test(testCaseOrName);
30      } else {
31        var options = opt_options || {};
32        options['flaky'] = true;
33        test(testCaseOrName, opt_testFn, options);
34      }
35    }.bind(this);
36
37    global.test = function(testCaseOrName, opt_testFn, opt_options) {
38      if (testCaseOrName instanceof TestCase) {
39        if (opt_testFn !== undefined)
40          throw new Error('opt_testFn cannot be given when giving a TestCase');
41        if (opt_options !== undefined)
42          throw new Error('opt_options cannot be given when giving a TestCase');
43        this.addTest(testCaseOrName);
44        return;
45      }
46
47      var testName = testCaseOrName;
48      var testFn = opt_testFn;
49      var options = opt_options || {};
50      if (testFn == undefined)
51        throw new Error('Must provide opt_testFn');
52
53      // If the test cares about DPI settings then we first push a test
54      // that fakes the DPI as the low or hi Dpi version, depending on what
55      // we're current using.
56      if (options.dpiAware) {
57        var defaultDevicePixelRatio = window.devicePixelRatio;
58        var dpi = defaultDevicePixelRatio > 1 ? 1 : 2;
59
60        var testWrapper = function() {
61          window.devicePixelRatio = dpi;
62          try {
63            testFn.bind(this).call();
64          } finally {
65            window.devicePixelRatio = defaultDevicePixelRatio;
66          }
67        };
68
69        var newName = name;
70        if (dpi === 1) {
71          newName += '_loDPI';
72          testName += '_hiDPI';
73        } else {
74          newName += '_hiDPI';
75          testName += '_loDPI';
76        }
77
78        this.addTest(new TestCase(newName,
79                                  testWrapper, options || {}));
80      }
81
82      this.addTest(new TestCase(testName,
83                                testFn, options || {}));
84    }.bind(this);
85
86    global.timedPerfTest = function(name, testFn, options) {
87      if (options === undefined || options.iterations === undefined)
88        throw new Error('timedPerfTest must have iteration option provided.');
89      this.addTest(new PerfTestCase(name, testFn, options));
90    }.bind(this);
91
92    try {
93      suiteConstructor.call();
94    } finally {
95      global.test = undefined;
96      global.timedPerfTest = undefined;
97    }
98  }
99
100  TestSuite.prototype = {
101    __proto__: Object.prototype,
102
103    get tests() {
104      return this.tests_;
105    },
106
107    addTest: function(test) {
108      if (test.suite !== undefined)
109        throw new Error('Test suite is already assigned');
110      if (this.testNames_[test.name] !== undefined)
111        throw new Error('Test name already used');
112      test.suite = this;
113      this.testNames_[test.name] = true;
114      this.tests_.push(test);
115    },
116
117    get name() {
118      return this.name_;
119    }
120  };
121
122  function testSuite(suiteConstructor) {
123    if (!global._currentSuiteLoader)
124      throw new Error('testSuites can only be defined during suite loading');
125    global._currentSuiteLoader.constructAndRegisterTestSuite(suiteConstructor);
126  }
127
128  return {
129    TestSuite: TestSuite,
130    testSuite: testSuite
131  };
132});
133</script>
134