Add nice little things to the in-browser test runner.
[dygraphs.git] / auto_tests / misc / local.js
CommitLineData
11c21001
RK
1var DygraphsLocalTester = function() {
2 this.tc = null; // Selected test case
3 this.name = null;
add4749b
RK
4 this.resultsDiv = null;
5 this.results = [];
6 this.summary = { failed: 0, passed: 0 };
7
8 var self = this;
9 jstestdriver.attachListener({
10 start : function(tc) {
11 self.start_(tc);
12 },
13 finish : function(tc, name, result, e) {
14 self.finish_(tc, name, result, e);
15 }
16 });
11c21001
RK
17};
18
19/**
20 * Call this to replace Dygraphs.warn so it throws an error.
21 *
22 * In some cases we will still allow warnings to be warnings, however.
23 */
24DygraphsLocalTester.prototype.overrideWarn = function() {
243eecfb 25 // save Dygraph.warn so we can catch warnings.
11c21001
RK
26 var originalDygraphWarn = Dygraph.warn;
27 Dygraph.warn = function(msg) {
28 // This warning is still
29 if (msg == "Using default labels. Set labels explicitly via 'labels' in the options parameter") {
30 originalDygraphWarn(msg);
31 return;
243eecfb 32 }
11c21001 33 throw "Warnings not permitted: " + msg;
243eecfb 34 }
11c21001 35 Dygraph.prototype.warn = Dygraph.warn;
243eecfb
RK
36};
37
11c21001 38DygraphsLocalTester.prototype.processVariables = function() {
243eecfb
RK
39 var splitVariables = function() { // http://www.idealog.us/2006/06/javascript_to_p.html
40 var query = window.location.search.substring(1);
41 var args = {};
42 var vars = query.split("&");
43 for (var i = 0; i < vars.length; i++) {
44 if (vars[i].length > 0) {
45 var pair = vars[i].split("=");
46 args[pair[0]] = pair[1];
47 }
48 }
49 return args;
50 }
51
52 var args = splitVariables();
53 var test = args.test;
54 var command = args.command;
55
56 // args.testCaseName uses the string name of the test.
57 if (args.testCaseName) {
58 var testCases = getAllTestCases();
59 name = args.testCaseName;
60 for (var idx in testCases) {
61 var entry = testCases[idx];
62 if (entry.name == args.testCaseName) {
63 var prototype = entry.testCase;
add4749b 64 this.tc = new entry.testCase();
243eecfb
RK
65 break;
66 }
67 }
68 } else if (args.testCase) { // The class name of the test.
69 name = args.testCase;
add4749b
RK
70 eval("tc__= new " + args.testCase + "()");
71 this.tc = tc_;
243eecfb
RK
72 }
73
243eecfb 74 // If the test class is defined.
11c21001 75 if (this.tc != null) {
243eecfb
RK
76 if (args.command == "runAllTests") {
77 console.log("Running all tests for " + args.testCase);
add4749b 78 this.tc.runAllTests();
243eecfb
RK
79 } else if (args.command == "runTest") {
80 console.log("Running test " + args.testCase + "." + args.test);
add4749b 81 this.tc.runTest(args.test);
243eecfb
RK
82 }
83 } else {
84 if (args.command == "runAllTests") {
85 console.log("Running all tests for all test cases");
86 var testCases = getAllTestCases();
243eecfb
RK
87 for (var idx in testCases) {
88 var entry = testCases[idx];
89 var prototype = entry.testCase;
11c21001 90 this.tc = new entry.testCase();
add4749b 91 this.tc.runAllTests();
243eecfb
RK
92 }
93 }
94 }
11c21001 95 this.resultsDiv = this.createResultsDiv();
add4749b 96 this.postResults();
11c21001 97 this.resultsDiv.appendChild(document.createElement("hr"));
add4749b 98 document.getElementById('summary').innerHTML = "(" + this.summary.failed + " failed, " + this.summary.passed + " passed)";
243eecfb
RK
99}
100
11c21001 101DygraphsLocalTester.prototype.createResultsDiv = function() {
243eecfb
RK
102 div = document.createElement("div");
103 div.id='results';
104 div.innerHTML = "Test results: <span id='summary'></span> <a href='#' id='passed'>passed</a> <a href='#' id='failed'>failed</a> <a href='#' id='all'>all</a><br/>";
add4749b
RK
105
106 var body = document.getElementsByTagName("body")[0];
243eecfb
RK
107 body.insertBefore(div, body.firstChild);
108
109 var setByClassName = function(name, displayStyle) {
110 var elements = div.getElementsByClassName(name);
111 for (var i = 0; i < elements.length; i++) {
112 elements[i].style.display = displayStyle;
113 }
114 }
115
116 var passedAnchor = document.getElementById('passed');
117 var failedAnchor = document.getElementById('failed');
118 var allAnchor = document.getElementById('all');
119 passedAnchor.onclick = function() {
120 setByClassName('fail', 'none');
121 setByClassName('pass', 'block');
122
123 passedAnchor.setAttribute("class", 'activeAnchor');
124 failedAnchor.setAttribute("class", '');
125 };
126 failedAnchor.onclick = function() {
127 setByClassName('fail', 'block');
128 setByClassName('pass', 'none');
129 passedAnchor.setAttribute("class", '');
130 failedAnchor.setAttribute("class", 'activeAnchor');
131 };
132 allAnchor.onclick = function() {
133 setByClassName('fail', 'block');
134 setByClassName('pass', 'block');
135 passedAnchor.setAttribute("class", '');
136 failedAnchor.setAttribute("class", '');
137 };
138 return div;
139}
140
add4749b 141DygraphsLocalTester.prototype.postResults = function() {
7cf85dd5
RK
142 var table = document.createElement("table");
143 this.resultsDiv.appendChild(table);
add4749b
RK
144 for (var idx = 0; idx < this.results.length; idx++) {
145 var result = this.results[idx];
7cf85dd5
RK
146 var tr = document.createElement("tr");
147 tr.setAttribute("class", result.result ? 'pass' : 'fail');
148
149 var tdResult = document.createElement("td");
150 tdResult.setAttribute("class", "outcome");
151 tdResult.innerText = result.result ? 'pass' : 'fail';
152 tr.appendChild(tdResult);
153
154 var tdName = document.createElement("td");
b99970f8
RK
155 var div = document.createElement("div");
156 div.innerText = result.name;
157 div.onclick = function(name) {
158 return function() {
159 var s = name.split(".");
160 var testCase = s[0];
161 var testName = s[1];
162 url = window.location.pathname +
163 "?testCaseName=" + testCase +
164 "&test=" + testName +
165 "&command=runTest";
166 window.location.href = url;
167 };
168 }(result.name);
169 div.setAttribute("class", "anchor");
170 tdName.appendChild(div);
7cf85dd5
RK
171 tr.appendChild(tdName);
172
173 var tdDuration = document.createElement("td");
174 tdDuration.innerText = result.duration;
175 tr.appendChild(tdDuration);
176
b99970f8
RK
177 if (result.e) {
178 var tdDetails = document.createElement("td");
179 div = document.createElement("div");
180 div.innerText = "more...";
181 div.setAttribute("class", "anchor");
182 div.onclick = function(e) {
183 return function() {
184 alert(e + "\n" + e.stack);
185 };
186 }(result.e);
187 tdDetails.appendChild(div);
188 tr.appendChild(tdDetails);
189 }
190
7cf85dd5 191 table.appendChild(tr);
243eecfb
RK
192 }
193}
194
11c21001 195DygraphsLocalTester.prototype.run = function() {
243eecfb
RK
196 var selector = document.getElementById("selector");
197
198 if (selector != null) { // running a test
199 var createAttached = function(name, parent) {
200 var elem = document.createElement(name);
201 parent.appendChild(elem);
202 return elem;
203 }
204
205 var description = createAttached("div", selector);
206 var list = createAttached("ul", selector);
207 var parent = list.parentElement;
208 var createLink = function(parent, text, url) {
209 var li = createAttached("li", parent);
210 var a = createAttached("a", li);
211 a.innerHTML = text;
212 a.href = url;
213 }
11c21001 214 if (this.tc == null) {
243eecfb
RK
215 description.innerHTML = "Test cases:";
216 var testCases = getAllTestCases();
217 createLink(list, "(run all tests)", document.URL + "?command=runAllTests");
218 for (var idx in testCases) {
219 var entryName = testCases[idx].name;
220 createLink(list, entryName, document.URL + "?testCaseName=" + entryName);
221 }
222 } else {
223 description.innerHTML = "Tests for " + name;
add4749b 224 var names = this.tc.getTestNames();
243eecfb
RK
225 createLink(list, "Run All Tests", document.URL + "&command=runAllTests");
226 for (var idx in names) {
227 var name = names[idx];
228 createLink(list, name, document.URL + "&test=" + name + "&command=runTest");
229 }
230 }
231 }
232}
add4749b
RK
233
234DygraphsLocalTester.prototype.start_ = function(tc) {
235 this.startms_ = new Date().getTime();
236}
237
238DygraphsLocalTester.prototype.finish_ = function(tc, name, result, e) {
239 var endms_ = new Date().getTime();
240 this.results.push({
241 name : tc.name + "." + name,
242 result : result,
b99970f8
RK
243 duration : endms_ - this.startms_,
244 e : e
add4749b
RK
245 });
246 this.summary.passed += result ? 1 : 0;
247 this.summary.failed += result ? 0 : 1;
248}