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/unittest/constants.html"> 9<script> 10'use strict'; 11 12tr.exportTo('tr.b.unittest', function() { 13 var TestTypes = tr.b.unittest.TestTypes; 14 15 function TestCase(name, opt_testFn, opt_options) { 16 if (!name) 17 throw new Error('Name must be provided'); 18 this.guid_ = tr.b.GUID.allocate(); 19 this.suite_ = undefined; // Set by TestSuite.addTest. 20 this.name_ = name; 21 22 if (opt_options) 23 this.options_ = opt_options; 24 else 25 this.options_ = {}; 26 27 this.testFn_ = opt_testFn; 28 } 29 30 TestCase.parseFullyQualifiedName = function(fqn) { 31 var i = fqn.lastIndexOf('.'); 32 if (i == -1) 33 throw new Error('FullyQualifiedNames must have a period in them'); 34 return { 35 suiteName: fqn.substr(0, i), 36 testCaseName: fqn.substr(i + 1) 37 }; 38 }; 39 40 TestCase.prototype = { 41 __proto__: Object.prototype, 42 43 get guid() { 44 return this.guid_; 45 }, 46 47 get suite() { 48 return this.suite_; 49 }, 50 51 set suite(suite) { 52 if (this.suite_ !== undefined) 53 throw new Error('Suite can only be assigned once.'); 54 this.suite_ = suite; 55 }, 56 57 get testType() { 58 return TestTypes.UNITTEST; 59 }, 60 61 get name() { 62 return this.name_; 63 }, 64 65 get fullyQualifiedName() { 66 return this.suite_.name + '.' + this.name_; 67 }, 68 69 get options() { 70 return this.options_; 71 }, 72 73 setUp: function() { 74 if (this.options_.setUp) 75 this.options_.setUp.call(this); 76 }, 77 78 run: function(htmlHook) { 79 return this.testFn_(); 80 }, 81 82 tearDown: function() { 83 if (this.options_.tearDown) 84 this.options_.tearDown.call(this); 85 }, 86 87 // TODO(nduca): The routing of this is a bit awkward. Probably better 88 // to install a global function. 89 addHTMLOutput: function(element) { 90 tr.b.unittest.addHTMLOutputForCurrentTest(element); 91 } 92 }; 93 94 function PerfTestCase(name, testFn, opt_options) { 95 TestCase.call(this, name, testFn, opt_options); 96 this.iterations = this.options.iterations || 10; 97 } 98 99 PerfTestCase.prototype = { 100 __proto__: TestCase.prototype, 101 102 get testType() { 103 return TestTypes.PERFTEST; 104 }, 105 106 run: function() { 107 var durations = []; 108 var iterations = this.iterations; 109 for (var i = 0; i < iterations; ++i) { 110 var start = window.performance.now(); 111 this.runOneIteration(); 112 var duration = window.performance.now() - start; 113 durations.push(duration); 114 } 115 116 var durationStrings = durations.map(function(d) { 117 return d.toFixed(2) + 'ms'; 118 }); 119 var average = tr.b.Statistics.mean(durations); 120 var min = tr.b.Statistics.min(durations); 121 122 var summaryString = ' ['; 123 summaryString += 'min ' + min.toFixed(2) + 'ms, '; 124 summaryString += 'avg ' + average.toFixed(2) + 'ms'; 125 summaryString += ']'; 126 127 return durationStrings.join(', ') + summaryString; 128 }, 129 130 runOneIteration: function() { 131 this.testFn_(); 132 } 133 }; 134 135 return { 136 TestCase: TestCase, 137 PerfTestCase: PerfTestCase 138 }; 139}); 140</script> 141