Home page Forum Wiki Mail Jabber Devel NIX-FILES

AltLUG Git

Git-repositories of Altai Linux User Group

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

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