Home page Forum Wiki Mail Jabber Devel NIX-FILES

AltLUG Git

Git-repositories of Altai Linux User Group

Lint: Tighten .jshintrc options and enforce them.
[qunit.git] / test / test.js
1 test("module without setup/teardown (default)", function() {
2         expect(1);
3         ok(true);
4 });
5
6 test("expect in test", 3, function() {
7         ok(true);
8         ok(true);
9         ok(true);
10 });
11
12 test("expect in test", 1, function() {
13         ok(true);
14 });
15
16 test("expect query and multiple issue", function() {
17         expect(2);
18         ok(true);
19         var expected = expect();
20         equal(expected, 2);
21         expect(expected + 1);
22         ok(true);
23 });
24
25 QUnit.module("assertion helpers");
26
27 QUnit.test( "QUnit.assert compatibility", 5, function( assert ) {
28         assert.ok( true, "Calling method on `assert` argument to test() callback" );
29
30         // Should also work, although discouraged and not documented
31         QUnit.assert.ok( true, "Calling method on QUnit.assert object" );
32
33         // Test compatibility aliases
34         QUnit.ok( true, "Calling aliased method in QUnit root object" );
35         ok( true, "Calling aliased function in global namespace" );
36
37         // Regression fix for #341
38         // The assert-context way of testing discouraged global variables,
39         // it doesn't make sense of it itself to be a global variable.
40         // Only allows for mistakes (e.g. forgetting to list 'assert' as parameter)
41         assert.notStrictEqual( window.assert, QUnit.assert, "Assert does not get exposed as a global variable" );
42 });
43
44 module("setup test", {
45         setup: function() {
46                 ok(true);
47         }
48 });
49
50 test("module with setup", function() {
51         expect(2);
52         ok(true);
53 });
54
55 test("module with setup, expect in test call", 2, function() {
56         ok(true);
57 });
58
59 var state;
60
61 module("setup/teardown test", {
62         setup: function() {
63                 state = true;
64                 ok(true);
65                 // Assert that we can introduce and delete globals in setup/teardown
66                 // without noglobals sounding any alarm.
67
68                 // Using an implied global variable instead of explicit window property
69                 // because there is no way to delete a window.property in IE6-8
70                 // `delete x` only works for `x = 1, and `delete window.x` throws exception.
71                 // No one-code fits all solution possible afaic. Resort to @cc.
72
73                 /*@cc_on
74                         @if (@_jscript_version < 9)
75                                 x = 1;
76                         @else @*/
77                                 window.x = 1;
78                         /*@end
79                 @*/
80         },
81         teardown: function() {
82                 ok(true);
83
84                 /*@cc_on
85                         @if (@_jscript_version < 9)
86                                 delete x;
87                         @else @*/
88                                 delete window.x;
89                         /*@end
90                 @*/
91         }
92 });
93
94 test("module with setup/teardown", function() {
95         expect(3);
96         ok(true);
97 });
98
99 module("setup/teardown test 2");
100
101 test("module without setup/teardown", function() {
102         expect(1);
103         ok(true);
104 });
105
106 var orgDate;
107
108 module("Date test", {
109         setup: function() {
110                 orgDate = Date;
111                 window.Date = function () {
112                         ok( false, 'QUnit should internally be independant from Date-related manipulation and testing' );
113                         return new orgDate();
114                 };
115         },
116         teardown: function() {
117                 window.Date = orgDate;
118         }
119 });
120
121 test("sample test for Date test", function () {
122         expect(1);
123         ok(true);
124 });
125
126 if (typeof setTimeout !== 'undefined') {
127 state = 'fail';
128
129 module("teardown and stop", {
130         teardown: function() {
131                 equal(state, "done", "Test teardown.");
132         }
133 });
134
135 test("teardown must be called after test ended", function() {
136         expect(1);
137         stop();
138         setTimeout(function() {
139                 state = "done";
140                 start();
141         }, 13);
142 });
143
144 test("parameter passed to stop increments semaphore n times", function() {
145         expect(1);
146         stop(3);
147         setTimeout(function() {
148                 state = "not enough starts";
149                 start();
150                 start();
151         }, 13);
152         setTimeout(function() {
153                 state = "done";
154                 start();
155         }, 15);
156 });
157
158 test("parameter passed to start decrements semaphore n times", function() {
159         expect(1);
160         stop();
161         stop();
162         stop();
163         setTimeout(function() {
164                 state = "done";
165                 start(3);
166         }, 18);
167 });
168
169 module("async setup test", {
170         setup: function() {
171                 stop();
172                 setTimeout(function() {
173                         ok(true);
174                         start();
175                 }, 500);
176         }
177 });
178
179 asyncTest("module with async setup", function() {
180         expect(2);
181         ok(true);
182         start();
183 });
184
185 module("async teardown test", {
186         teardown: function() {
187                 stop();
188                 setTimeout(function() {
189                         ok(true);
190                         start();
191                 }, 500);
192         }
193 });
194
195 asyncTest("module with async teardown", function() {
196         expect(2);
197         ok(true);
198         start();
199 });
200
201 module("asyncTest");
202
203 asyncTest("asyncTest", function() {
204         expect(2);
205         ok(true);
206         setTimeout(function() {
207                 state = "done";
208                 ok(true);
209                 start();
210         }, 13);
211 });
212
213 asyncTest("asyncTest", 2, function() {
214         ok(true);
215         setTimeout(function() {
216                 state = "done";
217                 ok(true);
218                 start();
219         }, 13);
220 });
221
222 test("sync", 2, function() {
223         stop();
224         setTimeout(function() {
225                 ok(true);
226                 start();
227         }, 13);
228         stop();
229         setTimeout(function() {
230                 ok(true);
231                 start();
232         }, 125);
233 });
234
235 test("test synchronous calls to stop", 2, function() {
236         stop();
237         setTimeout(function() {
238                 ok(true, 'first');
239                 start();
240                 stop();
241                 setTimeout(function() {
242                         ok(true, 'second');
243                         start();
244                 }, 150);
245         }, 150);
246 });
247 }
248
249 module("save scope", {
250         setup: function() {
251                 this.foo = "bar";
252         },
253         teardown: function() {
254                 deepEqual(this.foo, "bar");
255         }
256 });
257 test("scope check", function() {
258         expect(2);
259         deepEqual(this.foo, "bar");
260 });
261
262 module("simple testEnvironment setup", {
263         foo: "bar",
264         // example of meta-data
265         bugid: "#5311"
266 });
267 test("scope check", function() {
268         deepEqual(this.foo, "bar");
269 });
270 test("modify testEnvironment",function() {
271         expect(0);
272         this.foo="hamster";
273 });
274 test("testEnvironment reset for next test",function() {
275         deepEqual(this.foo, "bar");
276 });
277
278 module("testEnvironment with object", {
279         options:{
280                 recipe:"soup",
281                 ingredients:["hamster","onions"]
282         }
283 });
284 test("scope check", function() {
285         deepEqual(this.options, {recipe:"soup",ingredients:["hamster","onions"]}) ;
286 });
287 test("modify testEnvironment",function() {
288         expect(0);
289         // since we do a shallow copy, the testEnvironment can be modified
290         this.options.ingredients.push("carrots");
291 });
292 test("testEnvironment reset for next test",function() {
293         deepEqual(this.options, {recipe:"soup",ingredients:["hamster","onions","carrots"]}, "Is this a bug or a feature? Could do a deep copy") ;
294 });
295
296
297 module("testEnvironment tests");
298
299 function makeurl() {
300         var testEnv = QUnit.current_testEnvironment;
301         var url = testEnv.url || 'http://example.com/search';
302         var q   = testEnv.q   || 'a search test';
303         return url + '?q='+encodeURIComponent(q);
304 }
305
306 test("makeurl working",function() {
307         equal( QUnit.current_testEnvironment, this, 'The current testEnvironment is global');
308         equal( makeurl(), 'http://example.com/search?q=a%20search%20test', 'makeurl returns a default url if nothing specified in the testEnvironment');
309 });
310
311 module("testEnvironment with makeurl settings", {
312         url: 'http://google.com/',
313         q: 'another_search_test'
314 });
315 test("makeurl working with settings from testEnvironment", function() {
316         equal( makeurl(), 'http://google.com/?q=another_search_test', 'rather than passing arguments, we use test metadata to from the url');
317 });
318
319 module("jsDump");
320 test("jsDump output", function() {
321         equal( QUnit.jsDump.parse([1, 2]), "[\n  1,\n  2\n]" );
322         equal( QUnit.jsDump.parse({top: 5, left: 0}), "{\n  \"left\": 0,\n  \"top\": 5\n}" );
323         if (typeof document !== 'undefined' && document.getElementById("qunit-header")) {
324                 equal( QUnit.jsDump.parse(document.getElementById("qunit-header")), "<h1 id=\"qunit-header\"></h1>" );
325                 equal( QUnit.jsDump.parse(document.getElementsByTagName("h1")), "[\n  <h1 id=\"qunit-header\"></h1>\n]" );
326         }
327 });
328
329 module("assertions");
330 test("raises",function() {
331         function CustomError( message ) {
332                 this.message = message;
333         }
334
335         CustomError.prototype.toString = function() {
336                 return this.message;
337         };
338
339         throws(
340                 function() {
341                         throw "my error";
342                 }
343         );
344
345         throws(
346                 function() {
347                         throw "my error";
348                 },
349                 "simple string throw, no 'expected' value given"
350         );
351
352         throws(
353                 function() {
354                         throw new CustomError();
355                 },
356                 CustomError,
357                 'thrown error is an instance of CustomError'
358         );
359
360         throws(
361                 function() {
362                         throw new CustomError("some error description");
363                 },
364                 /description/,
365                 "use a regex to match against the stringified error"
366         );
367
368         throws(
369                 function() {
370                         throw new CustomError("some error description");
371                 },
372                 function( err ) {
373                         if ( (err instanceof CustomError) && /description/.test(err) ) {
374                                 return true;
375                         }
376                 },
377                 "custom validation function"
378         );
379
380         throws(
381                 function() {
382                         /*jshint evil:true */
383                         ( window.execScript || function( data ) {
384                                 window["eval"].call( window, data );
385                         })( "throw 'error';" );
386                 },
387                 'globally-executed errors caught'
388         );
389
390     this.CustomError = CustomError;
391
392     throws(
393         function() {
394             throw new this.CustomError("some error description");
395         },
396         /description/,
397         "throw error from property of 'this' context"
398     );
399
400     raises(
401         function() {
402             throw "error";
403         },
404         "simple throw, asserting with deprecated raises() function"
405     );
406
407 });
408
409 if (typeof document !== "undefined") {
410
411 module("fixture");
412 test("setup", function() {
413         expect(0);
414         document.getElementById("qunit-fixture").innerHTML = "foobar";
415 });
416 test("basics", function() {
417         equal( document.getElementById("qunit-fixture").innerHTML, "test markup", "automatically reset" );
418 });
419
420 test("running test name displayed", function() {
421         expect(2);
422
423         var displaying = document.getElementById("qunit-testresult");
424
425         ok( /running test name displayed/.test(displaying.innerHTML), "Expect test name to be found in displayed text" );
426         ok( /fixture/.test(displaying.innerHTML), "Expect module name to be found in displayed text" );
427 });
428
429 }
430
431 module("custom assertions");
432 (function() {
433         function mod2(value, expected, message) {
434                 var actual = value % 2;
435                 QUnit.push(actual == expected, actual, expected, message);
436         }
437         test("mod2", function() {
438                 mod2(2, 0, "2 % 2 == 0");
439                 mod2(3, 1, "3 % 2 == 1");
440         });
441 })();
442
443
444 module("recursions");
445
446 function Wrap(x) {
447         this.wrap = x;
448         if (x === undefined) {
449                 this.first = true;
450         }
451 }
452
453 function chainwrap(depth, first, prev) {
454         depth = depth || 0;
455         var last = prev || new Wrap();
456         first = first || last;
457
458         if (depth == 1) {
459                 first.wrap = last;
460         }
461         if (depth > 1) {
462                 last = chainwrap(depth-1, first, new Wrap(last));
463         }
464
465         return last;
466 }
467
468 test("check jsDump recursion", function() {
469         expect(4);
470
471         var noref = chainwrap(0);
472         var nodump = QUnit.jsDump.parse(noref);
473         equal(nodump, '{\n  "first": true,\n  "wrap": undefined\n}');
474
475         var selfref = chainwrap(1);
476         var selfdump = QUnit.jsDump.parse(selfref);
477         equal(selfdump, '{\n  "first": true,\n  "wrap": recursion(-1)\n}');
478
479         var parentref = chainwrap(2);
480         var parentdump = QUnit.jsDump.parse(parentref);
481         equal(parentdump, '{\n  "wrap": {\n    "first": true,\n    "wrap": recursion(-2)\n  }\n}');
482
483         var circref = chainwrap(10);
484         var circdump = QUnit.jsDump.parse(circref);
485         ok(new RegExp("recursion\\(-10\\)").test(circdump), "(" +circdump + ") should show -10 recursion level");
486 });
487
488 test("check (deep-)equal recursion", function() {
489         var noRecursion = chainwrap(0);
490         equal(noRecursion, noRecursion, "I should be equal to me.");
491         deepEqual(noRecursion, noRecursion, "... and so in depth.");
492
493         var selfref = chainwrap(1);
494         equal(selfref, selfref, "Even so if I nest myself.");
495         deepEqual(selfref, selfref, "... into the depth.");
496
497         var circref = chainwrap(10);
498         equal(circref, circref, "Or hide that through some levels of indirection.");
499         deepEqual(circref, circref, "... and checked on all levels!");
500 });
501
502
503 test('Circular reference with arrays', function() {
504
505         // pure array self-ref
506         var arr = [];
507         arr.push(arr);
508
509         var arrdump = QUnit.jsDump.parse(arr);
510
511         equal(arrdump, '[\n  recursion(-1)\n]');
512         equal(arr, arr[0], 'no endless stack when trying to dump arrays with circular ref');
513
514
515         // mix obj-arr circular ref
516         var obj = {};
517         var childarr = [obj];
518         obj.childarr = childarr;
519
520         var objdump = QUnit.jsDump.parse(obj);
521         var childarrdump = QUnit.jsDump.parse(childarr);
522
523         equal(objdump, '{\n  "childarr": [\n    recursion(-2)\n  ]\n}');
524         equal(childarrdump, '[\n  {\n    "childarr": recursion(-2)\n  }\n]');
525
526         equal(obj.childarr, childarr, 'no endless stack when trying to dump array/object mix with circular ref');
527         equal(childarr[0], obj, 'no endless stack when trying to dump array/object mix with circular ref');
528
529 });
530
531
532 test('Circular reference - test reported by soniciq in #105', function() {
533         var MyObject = function() {};
534         MyObject.prototype.parent = function(obj) {
535                 if (obj === undefined) { return this._parent; }
536                 this._parent = obj;
537         };
538         MyObject.prototype.children = function(obj) {
539                 if (obj === undefined) { return this._children; }
540                 this._children = obj;
541         };
542
543         var a = new MyObject(),
544                 b = new MyObject();
545
546         var barr = [b];
547         a.children(barr);
548         b.parent(a);
549
550         equal(a.children(), barr);
551         deepEqual(a.children(), [b]);
552 });
553
554 (function() {
555         var reset = QUnit.reset;
556         module("reset");
557         test("reset runs assertions", function() {
558                 expect(0);
559                 QUnit.reset = function() {
560                         ok( false, "reset should not modify test status" );
561                         reset.apply( this, arguments );
562                 };
563         });
564         test("reset runs assertions, cleanup", function() {
565                 expect(0);
566                 QUnit.reset = reset;
567         });
568 })();
569
570 function testAfterDone() {
571         var testName = "ensure has correct number of assertions";
572
573         function secondAfterDoneTest() {
574                 QUnit.config.done = [];
575                 // Because when this does happen, the assertion count parameter doesn't actually
576                 // work we use this test to check the assertion count.
577                 module("check previous test's assertion counts");
578                 test('count previous two test\'s assertions', function () {
579                         var i, countNodes,
580                                 spans = document.getElementsByTagName('span'),
581                                 tests = [];
582
583                         // Find these two tests
584                         for (i = 0; i < spans.length; i++) {
585                                 if (spans[i].innerHTML.indexOf(testName) !== -1) {
586                                         tests.push(spans[i]);
587                                 }
588                         }
589
590                         // Walk dom to counts.
591                         countNodes = tests[0].nextSibling.nextSibling.getElementsByTagName('b');
592                         equal(countNodes[1].innerHTML, "99");
593                         countNodes = tests[1].nextSibling.nextSibling.getElementsByTagName('b');
594                         equal(countNodes[1].innerHTML, "99");
595                 });
596         }
597         QUnit.config.done = [];
598         QUnit.done(secondAfterDoneTest);
599
600         module("Synchronous test after load of page");
601
602         asyncTest('Async test', function() {
603                 start();
604                 for (var i = 1; i < 100; i++) {
605                         ok(i);
606                 }
607         });
608
609         test(testName, 99, function() {
610                 for (var i = 1; i < 100; i++) {
611                         ok(i);
612                 }
613         });
614
615         // We need two of these types of tests in order to ensure that assertions
616         // don't move between tests.
617         test(testName + ' 2', 99, function() {
618                 for (var i = 1; i < 100; i++) {
619                         ok(i);
620                 }
621         });
622
623
624 }
625
626 if (typeof setTimeout !== 'undefined') {
627         QUnit.done(testAfterDone);
628 }

Hosting is provided AltSPAHow to use Git
Please direct any questions on jabber alex.wolf@jabber.ru

Valid HTML 4.0 Transitional Valid CSS!

Designer Alexander Wolf