Commit | Line | Data |
---|---|---|
644eff8b RK |
1 | // Copyright (c) 2011 Google, Inc. |
2 | // | |
3 | // Permission is hereby granted, free of charge, to any person obtaining a copy | |
4 | // of this software and associated documentation files (the "Software"), to deal | |
5 | // in the Software without restriction, including without limitation the rights | |
6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
7 | // copies of the Software, and to permit persons to whom the Software is | |
8 | // furnished to do so, subject to the following conditions: | |
9 | // | |
10 | // The above copyright notice and this permission notice shall be included in | |
11 | // all copies or substantial portions of the Software. | |
12 | // | |
13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
19 | // THE SOFTWARE. | |
20 | ||
21 | /** | |
22 | * @fileoverview Mocked-out jstestdriver api that lets me test locally. | |
23 | * | |
24 | * @author konigsberg@google.com (Robert Konigsberg) | |
25 | */ | |
26 | var jstestdriver = { | |
add4749b RK |
27 | jQuery : jQuery, |
28 | listeners_ : [], | |
29 | announce_ : function(name, args) { | |
30 | for (var idx = 0; idx < jstestdriver.listeners_.length; idx++) { | |
31 | var listener = jstestdriver.listeners_[idx]; | |
32 | if (listener[name]) { | |
33 | listener[name].apply(null, args); | |
34 | } | |
35 | } | |
36 | }, | |
37 | attachListener: function(listener) { | |
38 | jstestdriver.listeners_.push(listener); | |
39 | } | |
644eff8b RK |
40 | }; |
41 | ||
dfadd73f DV |
42 | if (!console) { |
43 | var console = { | |
44 | log: function(x) { | |
45 | // ... | |
46 | } | |
47 | }; | |
48 | } | |
49 | ||
644eff8b RK |
50 | var jstd = { |
51 | include : function(name) { | |
52 | this.sucker("Not including " + name); | |
53 | }, | |
54 | sucker : function(text) { | |
55 | console.log(text + ", sucker!"); | |
56 | } | |
57 | }; | |
58 | ||
3914c8e1 DV |
59 | var testCaseList = []; |
60 | ||
644eff8b | 61 | function TestCase(name) { |
357f7a8a RK |
62 | var testCase = function() { return this; }; |
63 | testCase.name = name; | |
64 | testCase.toString = function() { | |
644eff8b RK |
65 | return "Fake test case " + name; |
66 | }; | |
67 | ||
9d076ffe RK |
68 | testCase.prototype.setUp = function() { }; |
69 | testCase.prototype.tearDown = function() { }; | |
add4749b | 70 | testCase.prototype.name = name; |
47c97d86 RK |
71 | /** |
72 | * name can be a string, which is looked up in this object, or it can be a | |
73 | * function, in which case it's run. | |
74 | * | |
75 | * Examples: | |
76 | * var tc = new MyTestCase(); | |
77 | * tc.runTest("testThis"); | |
78 | * tc.runTest(tc.testThis); | |
79 | * | |
80 | * The duplication tc in runTest is irritating, but it plays well with | |
81 | * Chrome's console completion. | |
82 | */ | |
83 | testCase.prototype.runTest = function(func) { | |
add4749b RK |
84 | var result = false; |
85 | var ex = null; | |
86 | var name = typeof(func) == "string" ? func : "(anonymous function)"; | |
87 | jstestdriver.announce_("start", [this, name]); | |
ca6c43aa | 88 | try { |
add4749b | 89 | result = this.runTest_(func); |
ca6c43aa | 90 | } catch (e) { |
add4749b | 91 | ex = e; |
ca6c43aa | 92 | } |
add4749b | 93 | jstestdriver.announce_("finish", [this, name, result, ex]); |
0c59a428 | 94 | return result; // TODO(konigsberg): Remove this, and return value from runAllTests. |
add4749b RK |
95 | } |
96 | ||
97 | testCase.prototype.runTest_ = function(func) { | |
98 | this.setUp(); | |
99 | ||
100 | var fn = null; | |
101 | var parameterType = typeof(func); | |
102 | if (typeof(func) == "function") { | |
103 | fn = func; | |
104 | } else if (typeof(func) == "string") { | |
105 | fn = this[func]; | |
106 | } else { | |
107 | fail("can't supply " + typeof(func) + " to runTest"); | |
108 | } | |
109 | ||
110 | fn.apply(this, []); | |
111 | this.tearDown(); | |
112 | return true; | |
644eff8b | 113 | }; |
da11a9a7 | 114 | |
9d076ffe | 115 | testCase.prototype.runAllTests = function() { |
ca17c249 | 116 | var results = {}; |
357f7a8a RK |
117 | var names = this.getTestNames(); |
118 | for (var idx in names) { | |
119 | var name = names[idx]; | |
120 | console.log("Running " + name); | |
121 | var result = this.runTest(name); | |
ca17c249 | 122 | results[name] = result; |
357f7a8a | 123 | } |
ca17c249 RK |
124 | console.log(prettyPrintEntity_(results)); |
125 | return results; | |
357f7a8a RK |
126 | }; |
127 | ||
128 | testCase.prototype.getTestNames = function() { | |
129 | // what's better than for ... in for non-array objects? | |
130 | var tests = []; | |
9d076ffe RK |
131 | for (var name in this) { |
132 | if (name.indexOf('test') == 0 && typeof(this[name]) == 'function') { | |
357f7a8a | 133 | tests.push(name); |
9d076ffe RK |
134 | } |
135 | } | |
357f7a8a RK |
136 | return tests; |
137 | } | |
3914c8e1 | 138 | |
357f7a8a | 139 | testCaseList.push({name : name, testCase : testCase}); |
9d076ffe | 140 | return testCase; |
644eff8b | 141 | }; |
3914c8e1 DV |
142 | |
143 | // Note: this creates a bunch of global variables intentionally. | |
144 | function addGlobalTestSymbols() { | |
145 | globalTestDb = {}; // maps test name -> test function wrapper | |
146 | ||
147 | var num_tests = 0; | |
148 | for (var i = 0; i < testCaseList.length; i++) { | |
357f7a8a | 149 | var tc_class = testCaseList[i].testCase; |
3914c8e1 DV |
150 | for (var name in tc_class.prototype) { |
151 | if (name.indexOf('test') == 0 && typeof(tc_class.prototype[name]) == 'function') { | |
152 | if (globalTestDb.hasOwnProperty(name)) { | |
153 | console.log('Duplicated test name: ' + name); | |
154 | } else { | |
155 | globalTestDb[name] = function(name, tc_class) { | |
156 | return function() { | |
157 | var tc = new tc_class; | |
3914c8e1 DV |
158 | return tc.runTest(name); |
159 | }; | |
160 | }(name, tc_class); | |
161 | eval(name + " = globalTestDb['" + name + "'];"); | |
162 | num_tests += 1; | |
163 | } | |
164 | } | |
165 | } | |
166 | } | |
167 | console.log('Loaded ' + num_tests + ' tests in ' + | |
168 | testCaseList.length + ' test cases'); | |
169 | } | |
357f7a8a RK |
170 | |
171 | function getAllTestCases() { | |
172 | return testCaseList; | |
173 | } | |
add4749b RK |
174 | |
175 | jstestdriver.attachListener({ | |
176 | finish : function(tc, name, result, e) { | |
177 | if (e) { | |
178 | console.log(e); | |
179 | if (e.stack) { | |
180 | console.log(e.stack); | |
181 | } | |
182 | } | |
183 | } | |
184 | }); | |
185 |