source: Dev/trunk/src/client/dojo/tests/_base/declare.js

Last change on this file was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 11.5 KB
Line 
1// FIXME: this test assumes the existence of the global object "tests"
2tests= typeof tests=="undefined" ? {} : tests;
3
4define([
5        "doh/main", "dojo/aspect", "dojo/_base/declare", "dojo/_base/kernel", "dojo/_base/lang"
6], function(doh, aspect, declare, kernel, lang){
7        doh.register("tests._base.declare", [
8                function smokeTest(t){
9                        declare("tests._base.declare.tmp", null);
10                        var tmp = new tests._base.declare.tmp();
11                        declare("testsFoo", null);
12                        tmp = new testsFoo();
13                },
14                function smokeTest2(t){
15                        declare("tests._base.declare.foo", null, {
16                                foo: "thonk"
17                        });
18                        var tmp = new tests._base.declare.foo();
19                        t.is("thonk", tmp.foo);
20
21                        declare("testsFoo2", null, {
22                                foo: "thonk"
23                        });
24                        var tmp2 = new testsFoo2();
25                        t.is("thonk", tmp2.foo);
26                },
27                function smokeTestWithCtor(t){
28                        declare("tests._base.declare.fooBar", null, {
29                                constructor: function(){
30                                        this.foo = "blah";
31                                },
32                                foo: "thonk"
33                        });
34                        var tmp = new tests._base.declare.fooBar();
35                        t.is("blah", tmp.foo);
36                },
37                function smokeTestCompactArgs(t){
38                        declare("tests._base.declare.fooBar2", null, {
39                                foo: "thonk"
40                        });
41                        var tmp = new tests._base.declare.fooBar2();
42                        t.is("thonk", tmp.foo);
43                },
44                function subclass(t){
45                        declare("tests._base.declare.tmp3", null, {
46                                foo: "thonk"
47                        });
48                        declare("tests._base.declare.tmp4", tests._base.declare.tmp3);
49                        var tmp = new tests._base.declare.tmp4();
50                        t.is("thonk", tmp.foo);
51                },
52                function subclassWithCtor(t){
53                        declare("tests._base.declare.tmp5", null, {
54                                constructor: function(){
55                                        this.foo = "blah";
56                                },
57                                foo: "thonk"
58                        });
59                        declare("tests._base.declare.tmp6", tests._base.declare.tmp5);
60                        var tmp = new tests._base.declare.tmp6();
61                        t.is("blah", tmp.foo);
62                },
63                function mixinSubclass(t){
64                        declare("tests._base.declare.tmp7", null, {
65                                foo: "thonk"
66                        });
67                        declare("tests._base.declare.tmp8", null, {
68                                constructor: function(){
69                                        this.foo = "blah";
70                                }
71                        });
72                        var tmp = new tests._base.declare.tmp8();
73                        t.is("blah", tmp.foo);
74                        declare("tests._base.declare.tmp9",
75                                [
76                                        tests._base.declare.tmp7, // prototypal
77                                        tests._base.declare.tmp8  // mixin
78                                ]);
79                        var tmp2 = new tests._base.declare.tmp9();
80                        t.is("blah", tmp2.foo);
81                },
82                function superclassRef(t){
83                        declare("tests._base.declare.tmp10", null, {
84                                foo: "thonk"
85                        });
86                        declare("tests._base.declare.tmp11", tests._base.declare.tmp10, {
87                                constructor: function(){
88                                        this.foo = "blah";
89                                }
90                        });
91                        var tmp = new tests._base.declare.tmp11();
92                        t.is("blah", tmp.foo);
93                        t.is("thonk", tests._base.declare.tmp11.superclass.foo);
94                },
95                function inheritedCall(t){
96                        var foo = "xyzzy";
97                        declare("tests._base.declare.tmp12", null, {
98                                foo: "thonk",
99                                bar: function(arg1, arg2){
100                                        if(arg1){
101                                                this.foo = arg1;
102                                        }
103                                        if(arg2){
104                                                foo = arg2;
105                                        }
106                                }
107                        });
108                        declare("tests._base.declare.tmp13", tests._base.declare.tmp12, {
109                                constructor: function(){
110                                        this.foo = "blah";
111                                }
112                        });
113                        var tmp = new tests._base.declare.tmp13();
114                        t.is("blah", tmp.foo);
115                        t.is("xyzzy", foo);
116                        tmp.bar("zot");
117                        t.is("zot", tmp.foo);
118                        t.is("xyzzy", foo);
119                        tmp.bar("trousers", "squiggle");
120                        t.is("trousers", tmp.foo);
121                        t.is("squiggle", foo);
122                },
123                function inheritedExplicitCall(t){
124                        var foo = "xyzzy";
125                        declare("tests._base.declare.tmp14", null, {
126                                foo: "thonk",
127                                bar: function(arg1, arg2){
128                                        if(arg1){
129                                                this.foo = arg1;
130                                        }
131                                        if(arg2){
132                                                foo = arg2;
133                                        }
134                                }
135                        });
136                        declare("tests._base.declare.tmp15", tests._base.declare.tmp14, {
137                                constructor: function(){
138                                        this.foo = "blah";
139                                },
140                                bar: function(arg1, arg2){
141                                        this.inherited("bar", arguments, [arg2, arg1]);
142                                },
143                                baz: function(arg1, arg2){
144                                        tests._base.declare.tmp15.superclass.bar.apply(this, arguments);
145                                }
146                        });
147                        var tmp = new tests._base.declare.tmp15();
148                        t.is("blah", tmp.foo);
149                        t.is("xyzzy", foo);
150                        tmp.baz("zot");
151                        t.is("zot", tmp.foo);
152                        t.is("xyzzy", foo);
153                        tmp.bar("trousers", "squiggle");
154                        t.is("squiggle", tmp.foo);
155                        t.is("trousers", foo);
156                },
157                function inheritedMixinCalls(t){
158                        declare("tests._base.declare.tmp16", null, {
159                                foo: "",
160                                bar: function(){
161                                        this.foo += "tmp16";
162                                }
163                        });
164                        declare("tests._base.declare.mixin16", null, {
165                                bar: function(){
166                                        this.inherited(arguments);
167                                        this.foo += ".mixin16";
168                                }
169                        });
170                        declare("tests._base.declare.mixin17", tests._base.declare.mixin16, {
171                                bar: function(){
172                                        this.inherited(arguments);
173                                        this.foo += ".mixin17";
174                                }
175                        });
176                        declare("tests._base.declare.tmp17", [tests._base.declare.tmp16, tests._base.declare.mixin17], {
177                                bar: function(){
178                                        this.inherited(arguments);
179                                        this.foo += ".tmp17";
180                                }
181                        });
182                        var tmp = new tests._base.declare.tmp17();
183                        tmp.bar();
184                        t.is("tmp16.mixin16.mixin17.tmp17", tmp.foo);
185                },
186                function mixinPreamble(t){
187                        var passed = false;
188                        declare("tests._base.declare.tmp16", null);
189                        new tests._base.declare.tmp16({ preamble: function(){ passed = true; } });
190                        t.t(passed);
191                },
192
193                function basicMixin(t){
194                        // testing if a plain Class-like object can be inherited
195                        // by declare
196                        var d = new doh.Deferred;
197
198                        var Thing = function(args){
199                                lang.mixin(this, args);
200                        };
201                        Thing.prototype.method = function(){
202                                t.t(true);
203                                d.callback(true);
204                        };
205
206                        declare("Thinger", Thing, {
207                                method: function(){
208                                        this.inherited(arguments);
209                                }
210                        });
211
212                        var it = new Thinger();
213                        it.method();
214
215                        return d;
216                },
217
218                function mutatedMethods(t){
219                        // testing if methods can be mutated (within a reason)
220                        declare("tests._base.declare.tmp18", null, {
221                                constructor: function(){ this.clear(); },
222                                clear: function(){ this.flag = 0; },
223                                foo: function(){ ++this.flag; },
224                                bar: function(){ ++this.flag; },
225                                baz: function(){ ++this.flag; }
226                        });
227                        declare("tests._base.declare.tmp19", tests._base.declare.tmp18, {
228                                foo: function(){ ++this.flag; this.inherited(arguments); },
229                                bar: function(){ ++this.flag; this.inherited(arguments); },
230                                baz: function(){ ++this.flag; this.inherited(arguments); }
231                        });
232                        var x = new tests._base.declare.tmp19();
233                        // smoke tests
234                        t.is(0, x.flag);
235                        x.foo();
236                        t.is(2, x.flag);
237                        x.clear();
238                        t.is(0, x.flag);
239                        var a = 0;
240                        // aspect.after() on a prototype method
241                        aspect.after(tests._base.declare.tmp19.prototype, "foo", function(){ a = 1; });
242                        x.foo();
243                        t.is(2, x.flag);
244                        t.is(1, a);
245                        x.clear();
246                        a = 0;
247                        // extra chaining
248                        var old = tests._base.declare.tmp19.prototype.bar;
249                        tests._base.declare.tmp19.prototype.bar = function(){
250                                a = 1;
251                                ++this.flag;
252                                old.call(this);
253                        };
254                        x.bar();
255                        t.is(3, x.flag);
256                        t.is(1, a);
257                        x.clear();
258                        a = 0;
259                        // replacement
260                        tests._base.declare.tmp19.prototype.baz = function(){
261                                a = 1;
262                                ++this.flag;
263                                this.inherited("baz", arguments);
264                        };
265                        x.baz();
266                        t.is(2, x.flag);
267                        t.is(1, a);
268                },
269
270                function modifiedInstance(t){
271                        var stack;
272                        declare("tests._base.declare.tmp20", null, {
273                                foo: function(){ stack.push(20); }
274                        });
275                        declare("tests._base.declare.tmp21", null, {
276                                foo: function(){
277                                        this.inherited(arguments);
278                                        stack.push(21);
279                                }
280                        });
281                        declare("tests._base.declare.tmp22", tests._base.declare.tmp20, {
282                                foo: function(){
283                                        this.inherited(arguments);
284                                        stack.push(22);
285                                }
286                        });
287                        declare("tests._base.declare.tmp23",
288                                                [tests._base.declare.tmp20, tests._base.declare.tmp21], {
289                                foo: function(){
290                                        this.inherited(arguments);
291                                        stack.push(22);
292                                }
293                        });
294                        var a = new tests._base.declare.tmp22();
295                        var b = new tests._base.declare.tmp23();
296                        var c = {
297                                foo: function(){
298                                        this.inherited("foo", arguments);
299                                        stack.push("INSIDE C");
300                                }
301                        };
302                        stack = [];
303                        a.foo();
304                        t.is([20, 22], stack);
305
306                        stack = [];
307                        b.foo();
308                        t.is([20, 21, 22], stack);
309
310                        lang.mixin(a, c);
311                        lang.mixin(b, c);
312
313                        stack = [];
314                        a.foo();
315                        t.is([20, 22, "INSIDE C"], stack);
316
317                        stack = [];
318                        b.foo();
319                        t.is([20, 21, 22, "INSIDE C"], stack);
320                },
321
322                function duplicatedBase(t){
323                        var stack;
324                        var A = declare(null, {
325                                constructor: function(){
326                                        stack.push(1);
327                                }
328                        });
329                        var B = declare([A, A, A], {
330                                constructor: function(){
331                                        stack.push(2);
332                                }
333                        });
334                        stack = [];
335                        new A;
336                        t.is([1], stack);
337                        stack = [];
338                        new B;
339                        t.is([1, 2], stack);
340                },
341
342                function indirectlyDuplicatedBase(t){
343                        var stack;
344                        var A = declare(null, {
345                                constructor: function(){
346                                        stack.push(1);
347                                }
348                        });
349                        var B = declare(A, {
350                                constructor: function(){
351                                        stack.push(2);
352                                }
353                        });
354                        var C = declare([A, B], {
355                                constructor: function(){
356                                        stack.push(3);
357                                }
358                        });
359                        var D = declare([B, A], {
360                                constructor: function(){
361                                        stack.push(4);
362                                }
363                        });
364                        stack = [];
365                        new C;
366                        t.is([1, 2, 3], stack);
367                        stack = [];
368                        new D;
369                        t.is([1, 2, 4], stack);
370                },
371
372                function wrongMultipleInheritance(t){
373                        var stack;
374                        var A = declare([], {
375                                constructor: function(){
376                                        stack.push(1);
377                                }
378                        });
379                        var B = declare([A], {
380                                constructor: function(){
381                                        stack.push(2);
382                                }
383                        });
384                        stack = [];
385                        new A;
386                        t.is([1], stack);
387                        stack = [];
388                        new B;
389                        t.is([1, 2], stack);
390                },
391
392                function impossibleBases(t){
393                        var A = declare(null);
394                        var B = declare(null);
395                        var C = declare([A, B]);
396                        var D = declare([B, A]);
397
398                        var flag = false;
399                        try{
400                                var E = declare([C, D]);
401                        }catch(e){
402                                flag = true;
403                        }
404                        t.t(flag);
405                },
406
407                function noNew(t){
408                        // all of the classes I create will use this as their
409                        // pseudo-constructor function
410                        function noNewConstructor(){
411                                this.noNew_Value = 'instance value';
412                        }
413
414                        var g = kernel.global;
415                        // this value will remain unchanged if the code for
416                        // calling a constructor without 'new' works correctly.
417                        g.noNew_Value = 'global value';
418
419                        // perform the actual test
420                        function noNewTest(cls){
421                                // call class function without new
422                                var obj = cls('instance value');
423                                t.is(obj.noNew_Value, 'instance value');
424                                t.is(g.noNew_Value, 'global value');
425                        }
426
427                        // There are three different functions that might be
428                        // created by declare(), so I need to test all
429                        // three.
430
431                        // 1. Class with manual-chained constructor
432                        noNewTest(
433                                declare(null, {
434                                        constructor: noNewConstructor,
435                                        '-chains-': {constructor: 'manual'}
436                                })
437                        );
438
439                        // 2. Class with no superclasses
440                        var A = declare(null, {
441                                constructor: noNewConstructor
442                        });
443                        noNewTest(A);
444
445                        // 3. Class with at least one superclass
446                        noNewTest(declare(A));
447
448                        // Make sure multiple inheritance call works
449                        var B = declare(A);
450                        var C = declare(null, { ctest: function(){return true;} });
451                        var D = declare([A, B, C], { dtest: function(){return true;} });
452                        noNewTest(D);
453                        // make sure I get the test functions from
454                        // all superclasses
455                        var d = D();
456                        t.t(d.ctest());
457                        t.t(d.dtest());
458
459                        // Make sure call through an object works
460                        var noNewClasses = {
461                                D: D,
462                                noNew_Value: 'unchanged'
463                        };
464                        var obj = noNewClasses.D();
465                        t.is(obj.noNew_Value, 'instance value');
466                        t.is(noNewClasses.noNew_Value, 'unchanged');
467                },
468
469                function createSubclass(t){
470                        var A = dojo.declare(null, {
471                                foo: "thonk"
472                        });
473                        var B = dojo.declare(null, {
474                        });
475                        var C = dojo.declare(null, {
476                                bar: "thonk"
477                        });
478                        var D1 = A.createSubclass([B, C], {
479                                constructor: function(){
480                                        this.foo = "blah";
481                                }
482                        });
483                        var D2 = A.createSubclass([B, C]);
484                        var d1 = new D1();
485                        var d2 = new D2();
486                        t.is("blah", d1.foo);
487                        t.is("thonk", d2.foo);
488                        t.is("thonk", d1.bar);
489                        t.is("thonk", d2.bar);
490                }
491
492                // FIXME: there are still some permutations to test like:
493                //      - ctor arguments
494                //      - multi-level inheritance + L/R conflict checks
495        ]);
496});
Note: See TracBrowser for help on using the repository browser.