source: Dev/trunk/src/client/dojox/lang/tests/test_aspect.html

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

Added Dojo 1.9.3 release.

File size: 16.4 KB
Line 
1<html>
2        <head>
3                <title>aspects</title>
4                <style type="text/css">
5                        @import "../../../dojo/resources/dojo.css";
6                </style>
7                <script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true"></script>
8                <script type="text/javascript" src="../aspect.js"></script>
9                <script type="text/javascript" src="../aspect/cflow.js"></script>
10                <script type="text/javascript" src="../aspect/tracer.js"></script>
11                <script type="text/javascript" src="../aspect/timer.js"></script>
12                <script type="text/javascript" src="../aspect/profiler.js"></script>
13                <script type="text/javascript" src="../aspect/counter.js"></script>
14                <script type="text/javascript" src="../aspect/memoizer.js"></script>
15                <script type="text/javascript" src="../aspect/memoizerGuard.js"></script>
16                <script type="text/javascript">
17                        dojo.require("dojox.lang.aspect");
18                        dojo.require("dojox.lang.aspect.cflow");
19                        dojo.require("dojox.lang.aspect.tracer");
20                        dojo.require("dojox.lang.aspect.timer");
21                        dojo.require("dojox.lang.aspect.profiler");
22                        dojo.require("dojox.lang.aspect.counter");
23                        dojo.require("dojox.lang.aspect.memoizer");
24                        dojo.require("dojox.lang.aspect.memoizerGuard");
25                        dojo.require("dojo.string");
26                        dojo.require("dojox.lang.functional.listcomp");
27                       
28                        var test = function(){
29                                // This is a test class, don't program like this!
30                                var Rect = function(){
31                                        this.x = this.y = this.width = this.height = 0;
32                                };
33                                dojo.extend(Rect, {
34                                        // getters
35                                        getX: function(){ return this.x; },
36                                        getY: function(){ return this.y; },
37                                        getWidth: function(){ return this.width; },
38                                        getHeight: function(){ return this.height; },
39                                        // setters
40                                        setX: function(val){ this.x = val; },
41                                        setY: function(val){ this.y = val; },
42                                        setWidth: function(val){ this.width = val; },
43                                        setHeight: function(val){ this.height = val; },
44                                        // special methods
45                                        getPerimeter: function(){ return 2 * (this.width + this.height); },
46                                        getArea: function(){ return this.width * this.height; },
47                                        getCorner: function(){ return {x: this.x + this.width, y: this.y + this.height}; },
48                                        move: function(x, y){ this.x = x; this.y = y; },
49                                        makeSquare: function(l){ this.width = this.height = l; },
50                                        scale: function(s){ this.width *= s; this.height *= s; },
51                                        pointInside: function(x, y){
52                                                return  this.x <= x && x < (this.x + this.width) &&
53                                                                this.y <= y && y < (this.y + this.height);
54                                        },
55                                        assertSquare: function(){
56                                                if(this.getHeight() != this.getWidth()){
57                                                        throw new Error("NOT A SQUARE!");
58                                                }
59                                        }
60                                });
61                               
62                                var aop = dojox.lang.aspect, df = dojox.lang.functional;
63                               
64                                // our simple advices
65                                var TraceArguments = {
66                                        before: function(/*arguments*/){
67                                                var joinPoint = aop.getContext().joinPoint,
68                                                        args = Array.prototype.join.call(arguments, ", ");
69                                                console.log("=> " + joinPoint.targetName + "(" + args + ")");
70                                        }
71                                };
72                                var TraceReturns = {
73                                        afterReturning: function(retVal){
74                                                var joinPoint = aop.getContext().joinPoint;
75                                                console.log("<= " + joinPoint.targetName + " returns " + retVal);
76                                        },
77                                        afterThrowing: function(excp){
78                                                var joinPoint = aop.getContext().joinPoint;
79                                                console.log("<= " + joinPoint.targetName + " throws: " + excp);
80                                        }
81                                };
82                               
83                                console.log("create rect1 and call its methods without aspects.");
84                                var rect1 = new Rect;
85                                rect1.move(100, 100);
86                                rect1.makeSquare(200);
87                                rect1.pointInside(150, 250);
88                                console.log("perimeter: " + rect1.getPerimeter());
89                                console.log("area: " + rect1.getArea());
90                                console.log("=================================");
91                               
92                                console.log("create rect2, attach advices to the instance, and repeat...");
93                                var rect2 = new Rect;
94                                aop.advise(rect2, /^get/, TraceReturns);
95                                aop.advise(rect2, [/^set/, "move", "makeSquare"], TraceArguments);
96                                aop.advise(rect2, "pointInside", [TraceReturns, TraceArguments]);
97                                rect2.move(100, 100);
98                                rect2.makeSquare(200);
99                                rect2.pointInside(150, 250);
100                                console.log("perimeter: " + rect2.getPerimeter());
101                                console.log("area: " + rect2.getArea());
102                                console.log("=================================");
103
104                                console.log("attach advices to the Rect class, and repeat with rect1...");
105                                var h1 = aop.advise(Rect, /^get/, TraceReturns);
106                                var h2 = aop.advise(Rect, [/^set/, "move", "makeSquare"], TraceArguments);
107                                var h3 = aop.advise(Rect, "pointInside", [TraceReturns, TraceArguments]);
108                                rect1.move(100, 100);
109                                rect1.makeSquare(200);
110                                rect1.pointInside(150, 250);
111                                console.log("perimeter: " + rect1.getPerimeter());
112                                console.log("area: " + rect1.getArea());
113                                console.log("=================================");
114                               
115                                console.log("remove advices for getters and setters from the class, and repeat with rect1...");
116                                aop.unadvise(h1);
117                                aop.unadvise(h2);
118                                rect1.move(100, 100);
119                                rect1.makeSquare(200);
120                                rect1.pointInside(150, 250);
121                                console.log("perimeter: " + rect1.getPerimeter());
122                                console.log("area: " + rect1.getArea());
123                                console.log("=================================");
124
125                                console.log("repeat with rect2...");
126                                rect2.move(100, 100);
127                                rect2.makeSquare(200);
128                                rect2.pointInside(150, 250);
129                                console.log("perimeter: " + rect2.getPerimeter());
130                                console.log("area: " + rect2.getArea());
131                                console.log("=================================");
132
133                                console.log("test rect2 with throwing an exception...");
134                                aop.advise(rect2, /^assert/, TraceReturns);
135                                try{
136                                        rect2.assertSquare();
137                                        rect2.width = 300; // triggering exception
138                                        rect2.assertSquare();
139                                }catch(e){
140                                        // squelch
141                                }
142                                console.log("=================================");
143                               
144                                // more complex dynamic tracing advice
145                                var Trace = function(context){
146                                        this.name = context.joinPoint.targetName;
147                                };
148                                dojo.extend(Trace, {
149                                        before: function(/*arguments*/){
150                                                this.args = Array.prototype.join.call(arguments, ", ");
151                                        },
152                                        afterReturning: function(retVal){
153                                                var buf = "-- " + this.name + "(" + this.args + ")";
154                                                if(typeof retVal == "undefined"){
155                                                        // procedure without a return value
156                                                        console.log(buf);
157                                                }else{
158                                                        // function with returned value
159                                                        console.log(buf + " returns: " + retVal);
160                                                }
161                                        },
162                                        afterThrowing: function(excp){
163                                                console.log("-- " + this.name + "(" + this.args + ") throws: " + excp);
164                                        }
165                                });
166                               
167                                // remove tracing for pointInside
168                                aop.unadvise(h3);
169                               
170                                console.log("create rect3, and trace all its methods...");
171                                var rect3 = new Rect;
172                                aop.advise(rect3, /^\S/, Trace);
173                                rect3.move(100, 100);
174                                rect3.makeSquare(200);
175                                rect3.pointInside(150, 250);
176                                console.log("perimeter: " + rect3.getPerimeter());
177                                console.log("area: " + rect3.getArea());
178                                rect3.assertSquare();
179                                console.log("=================================");
180                               
181                                var TraceAll = function(context, id){
182                                        this.name = context.joinPoint.targetName;
183                                        this.prefix = dojo.string.pad("", context.depth * 2, "--", true) + "-- #" + (id || 1);
184                                };
185                                dojo.extend(TraceAll, {
186                                        before: function(/*arguments*/){
187                                                var args = Array.prototype.join.call(arguments, ", ");
188                                                console.log(this.prefix + " => before " + this.name + "(" + args + ")");
189                                        },
190                                        around: function(/*arguments*/){
191                                                var args = Array.prototype.join.call(arguments, ", ");
192                                                console.log(this.prefix + " => around " + this.name + "(" + args + ")");
193                                                var retVal = aop.proceed.apply(null, arguments);
194                                                console.log(this.prefix + " <= around " + this.name + " returns " + retVal);
195                                                return retVal;  // should return a value, if the target returns a value
196                                        },
197                                        afterReturning: function(retVal){
198                                                console.log(this.prefix + " <= afterR " + this.name + " returns " + retVal);
199                                        },
200                                        afterThrowing: function(excp){
201                                                console.log(this.prefix + " <= afterT " + this.name + " throws: " + excp);
202                                        },
203                                        after: function(){
204                                                console.log(this.prefix + " <= after  " + this.name);
205                                        }
206                                });
207                               
208                                console.log("create rect4, and attach two tracer to all its methods...");
209                                var rect4 = new Rect;
210                                aop.advise(rect4, /^\S/, [
211                                        function(context){ return new TraceAll(context, 1); },
212                                        function(context){ return new TraceAll(context, 2); }
213                                ]);
214                                rect4.move(100, 100);
215                                rect4.makeSquare(200);
216                                rect4.pointInside(150, 250);
217                                console.log("perimeter: " + rect4.getPerimeter());
218                                console.log("area: " + rect4.getArea());
219                                try{
220                                        rect4.assertSquare();
221                                        rect4.width = 300; // triggering exception
222                                        rect4.assertSquare();
223                                }catch(e){
224                                        // squelch
225                                }
226                                console.log("=================================");
227
228                                var TraceTopLevel = function(context){
229                                        this.name = context.joinPoint.targetName;
230                                };
231                                dojo.extend(TraceTopLevel, {
232                                        before: function(/*arguments*/){
233                                                var args = Array.prototype.join.call(arguments, ", ");
234                                                console.log("=> " + this.name + "(" + args + ")");
235                                        },
236                                        afterReturning: function(retVal){
237                                                console.log("<= " + this.name + " returns: " + retVal);
238                                        },
239                                        afterThrowing: function(excp){
240                                                console.log("<= " + this.name + " throws: " + excp);
241                                        }
242                                });
243
244                                console.log("create rect5, and track only top-level calls...");
245                                var rect5 = new Rect;
246                                aop.advise(rect5, /^\S/,
247                                        function(context){
248                                                return aop.cflow(context.instance) ?    // the advised object
249                                                        {} :                                                            // do nothing
250                                                        new TraceTopLevel(context);                     // log top level
251                                        }
252                                );
253                                rect5.move(100, 100);
254                                rect5.makeSquare(200);
255                                rect5.pointInside(150, 250);
256                                console.log("perimeter: " + rect5.getPerimeter());
257                                console.log("area: " + rect5.getArea());
258                                try{
259                                        rect5.assertSquare();
260                                        rect5.width = 300; // triggering exception
261                                        rect5.assertSquare();
262                                }catch(e){
263                                        // squelch
264                                }
265                                console.log("=================================");
266                               
267                                var log = function(){
268                                        // log the rect1pointInside state
269                                        var dispatcher = "native";
270                                        if(rect1.pointInside.target){
271                                                if(rect1.pointInside.advices){
272                                                        dispatcher = "dojox.lang.aspect";
273                                                }else if(rect1.pointInside._listeners){
274                                                        dispatcher = "dojo.connect";
275                                                }
276                                        }
277                                        console.log("Dispatcher: " + dispatcher);
278                                };
279                               
280                                console.log("use dojo.connect() on rect1 to trace...");
281                                console.log("Running native method.");
282                                log();
283                                rect1.pointInside(150, 250);
284                                console.log("Connecting an event processor.");
285                                h1 = dojo.connect(rect1, "pointInside", function(){
286                                        var args = Array.prototype.join.call(arguments, ", ");
287                                        console.log("from dojo.connect(): " + args);
288                                });
289                                log();
290                                rect1.pointInside(150, 250);
291                                console.log("Connecting the TraceAll advice.");
292                                h2 = aop.advise(rect1, "pointInside", TraceAll);
293                                log();
294                                rect1.pointInside(150, 250);
295                                console.log("Disconnecting the event processor.");
296                                dojo.disconnect(h1);
297                                log();
298                                rect1.pointInside(150, 250);
299                                console.log("Disconnecting the advise.");
300                                aop.unadvise(h2);
301                                log();
302                                rect1.pointInside(150, 250);
303                                console.log("Connecting the TraceAll advice.");
304                                h2 = aop.advise(rect1, "pointInside", TraceAll);
305                                log();
306                                rect1.pointInside(150, 250);
307                                console.log("Connecting an event processor.");
308                                h1 = dojo.connect(rect1, "pointInside", function(){
309                                        var args = Array.prototype.join.call(arguments, ", ");
310                                        console.log("from dojo.connect(): " + args);
311                                });
312                                log();
313                                rect1.pointInside(150, 250);
314                                console.log("Disconnecting the advise.");
315                                aop.unadvise(h2);
316                                log();
317                                rect1.pointInside(150, 250);
318                                console.log("Disconnecting the event processor.");
319                                dojo.disconnect(h1);
320                                log();
321                                rect1.pointInside(150, 250);
322                                console.log("=================================");
323                               
324                                console.log("trace all methods of rect1...");
325                                h1 = aop.advise(rect1, /^\S/, aop.tracer(true));
326                                rect1.move(100, 100);
327                                rect1.makeSquare(200);
328                                rect1.pointInside(150, 250);
329                                console.log("perimeter: " + rect1.getPerimeter());
330                                console.log("area: " + rect1.getArea());
331                                try{
332                                        rect1.assertSquare();
333                                        rect1.width = 300; // triggering exception
334                                        rect1.assertSquare();
335                                }catch(e){
336                                        // squelch
337                                }
338                                aop.unadvise(h1);
339                                console.log("=================================");
340                               
341                                console.log("count all get* methods of rect1...");
342                                var counter = aop.counter();
343                                h1 = aop.advise(rect1, /^get/, counter);
344                                rect1.move(100, 100);
345                                rect1.makeSquare(200);
346                                rect1.pointInside(150, 250);
347                                console.log("perimeter: " + rect1.getPerimeter());
348                                console.log("area: " + rect1.getArea());
349                                try{
350                                        rect1.assertSquare();
351                                        rect1.width = 300; // triggering exception
352                                        rect1.assertSquare();
353                                }catch(e){
354                                        // squelch
355                                }
356                                aop.unadvise(h1);
357                                console.log("get* methods were called", counter.calls, "times, with", counter.errors, "errors.");
358                                console.log("=================================");
359
360                                console.log("time all methods of rect1...");
361                                h1 = aop.advise(rect1, /^\S/, aop.timer());
362                                rect1.move(100, 100);
363                                rect1.makeSquare(200);
364                                rect1.pointInside(150, 250);
365                                console.log("perimeter: " + rect1.getPerimeter());
366                                console.log("area: " + rect1.getArea());
367                                try{
368                                        rect1.assertSquare();
369                                        rect1.width = 300; // triggering exception
370                                        rect1.assertSquare();
371                                }catch(e){
372                                        // squelch
373                                }
374                                aop.unadvise(h1);
375                                console.log("=================================");
376
377                                /*
378                                console.log("profile all methods of rect1...");
379                                h1 = aop.advise(rect1, /^\S/, aop.profiler("Profile1"));
380                                rect1.move(100, 100);
381                                rect1.makeSquare(200);
382                                rect1.pointInside(150, 250);
383                                console.log("perimeter: " + rect1.getPerimeter());
384                                console.log("area: " + rect1.getArea());
385                                try{
386                                        rect1.assertSquare();
387                                        rect1.width = 300; // triggering exception
388                                        rect1.assertSquare();
389                                }catch(e){
390                                        // squelch
391                                }
392                                aop.unadvise(h1);
393                                console.log("=================================");
394                                */
395                               
396                                var Fibonacci = function(order){
397                                        if(arguments.length == 1){
398                                                this.setOrder(order);
399                                        }else{
400                                                this.offset = 2;
401                                        }
402                                }
403                                dojo.extend(Fibonacci, {
404                                        setOrder: function(order){
405                                                this.offset = order + 1;
406                                        },
407                                        getOrder: function(){
408                                                return this.offset - 1;
409                                        },
410                                        calculate: function(n){
411                                                if(n < 0){ return 0; }
412                                                if(n == 0){ return 1; }
413                                                return this.calculate(n - 1) + this.calculate(n - this.offset);
414                                        },
415                                        calculateN: function(n, o){
416                                                if(n < 0){ return 0; }
417                                                if(n == 0){ return 1; }
418                                                return this.calculateN(n - 1, o) + this.calculateN(n - 1 - o, o);
419                                        }
420                                });
421                                var args = df.listcomp("i for(i = 0; i < 15; ++i)");
422
423                                console.log("calculate Fibonacci numbers...");
424                                var fib = new Fibonacci;
425                                h1 = aop.advise(fib, /^calculate/, aop.timer("fib"));
426                               
427                                console.log("before memoization");
428                                fib.setOrder(0);
429                                console.log("0-order:", dojo.map(args, dojo.hitch(fib, "calculate")));
430                                fib.setOrder(1);
431                                console.log("1-order:", dojo.map(args, dojo.hitch(fib, "calculate")));
432                                fib.setOrder(2);
433                                console.log("2-order:", dojo.map(args, dojo.hitch(fib, "calculate")));
434                                fib.setOrder(3);
435                                console.log("3-order:", dojo.map(args, dojo.hitch(fib, "calculate")));
436                               
437                                console.log("after memoization");
438                                h2 = aop.advise(fib, "calculate", aop.memoizer());
439                                h3 = aop.advise(fib, /^set/, aop.memoizerGuard("calculate"));
440                                fib.setOrder(0);
441                                console.log("0-order:", dojo.map(args, dojo.hitch(fib, "calculate")));
442                                fib.setOrder(1);
443                                console.log("1-order:", dojo.map(args, dojo.hitch(fib, "calculate")));
444                                fib.setOrder(2);
445                                console.log("2-order:", dojo.map(args, dojo.hitch(fib, "calculate")));
446                                fib.setOrder(3);
447                                console.log("3-order:", dojo.map(args, dojo.hitch(fib, "calculate")));
448                                aop.unadvise(h3);
449                                aop.unadvise(h2);
450                               
451                                console.log("before memoization");
452                                console.log(fib.calculateN(15, 0));
453                                console.log(fib.calculateN(15, 1));
454                                console.log(fib.calculateN(15, 2));
455                                console.log(fib.calculateN(15, 3));
456                               
457                                console.log("after memoization");
458                                h2 = aop.advise(fib, "calculateN", aop.memoizer(function(a, b){ return a + "/" + b; }));
459                                h3 = aop.advise(fib, /^set/, aop.memoizerGuard("calculate"));
460                                console.log(fib.calculateN(15, 0));
461                                console.log(fib.calculateN(15, 1));
462                                console.log(fib.calculateN(15, 2));
463                                console.log(fib.calculateN(15, 3));
464                                aop.unadvise(h3);
465                                aop.unadvise(h2);
466
467                                aop.unadvise(h1);
468                               
469                                console.log("=================================");
470                        };
471                        //dojo.addOnLoad(test);
472                </script>
473        </head>
474        <body>
475                <p>This test is meant to run with Firebug. Open the console to see the output.</p>
476                <p><button onclick="test()">Start</button></p>
477        </body>
478</html>
Note: See TracBrowser for help on using the repository browser.