[483] | 1 | dojo.provide("dojox.lang.tests.observable"); |
---|
| 2 | dojo.require("dojox.lang.observable"); |
---|
| 3 | |
---|
| 4 | (function(){ |
---|
| 5 | tests.register("dojox.lang.tests.observable", [ |
---|
| 6 | function propertyAccessMakeObservable(t){ |
---|
| 7 | console.log("start"); |
---|
| 8 | var testStrs = []; |
---|
| 9 | var observable = new dojox.lang.makeObservable( |
---|
| 10 | function(obj,i){ |
---|
| 11 | testStrs.push("onRead " + i); |
---|
| 12 | return obj[i]; |
---|
| 13 | }, |
---|
| 14 | function(obj,i,value){ |
---|
| 15 | testStrs.push("onWrite " + i); |
---|
| 16 | obj[i] = value; |
---|
| 17 | }, |
---|
| 18 | function(scope,obj,i,args){ |
---|
| 19 | testStrs.push("onInvoke " + i); |
---|
| 20 | return obj[i].apply(scope,args); |
---|
| 21 | } |
---|
| 22 | ); |
---|
| 23 | var obj = {foo:"bar",test:function(){ |
---|
| 24 | return this.foo; |
---|
| 25 | } |
---|
| 26 | }; |
---|
| 27 | var newObj = observable(obj); |
---|
| 28 | testStrs.push("returned " + newObj.test()); |
---|
| 29 | newObj.foo = "new"; |
---|
| 30 | testStrs.push(newObj.foo); |
---|
| 31 | t.assertEqual("onInvoke test,onRead foo,returned bar,onWrite foo,onRead foo,new",testStrs.join(',')); |
---|
| 32 | }, |
---|
| 33 | function propertyAccessObservable(t){ |
---|
| 34 | var testStrs = []; |
---|
| 35 | var obj = {foo:"bar",test:function(){ |
---|
| 36 | return this.foo; |
---|
| 37 | }}; |
---|
| 38 | var newObj = dojox.lang.observable(obj,function(obj,i){ |
---|
| 39 | testStrs.push("onRead " + i); |
---|
| 40 | return obj[i]; |
---|
| 41 | },function(obj,i,value){ |
---|
| 42 | testStrs.push("onWrite " + i); |
---|
| 43 | obj[i] = value; |
---|
| 44 | },function(scope,obj,i,args){ |
---|
| 45 | testStrs.push("onInvoke " + i); |
---|
| 46 | return obj[i].apply(scope,args); |
---|
| 47 | } |
---|
| 48 | ); |
---|
| 49 | testStrs.push("returned " + newObj.test()); |
---|
| 50 | newObj.foo = "new"; |
---|
| 51 | testStrs.push(newObj.foo); |
---|
| 52 | t.assertEqual("onInvoke test,onRead foo,returned bar,onWrite foo,onRead foo,new",testStrs.join(',')); |
---|
| 53 | }, |
---|
| 54 | function readonlyProxy(t){ |
---|
| 55 | console.log("start"); |
---|
| 56 | var testStrs = []; |
---|
| 57 | var obj = {foo:"bar"}; |
---|
| 58 | var newObj = dojox.lang.ReadOnlyProxy(obj); |
---|
| 59 | testStrs.push(newObj.foo); |
---|
| 60 | newObj.foo = "illegal"; |
---|
| 61 | |
---|
| 62 | testStrs.push(newObj.foo); |
---|
| 63 | obj.foo = "new"; |
---|
| 64 | testStrs.push(newObj.foo); |
---|
| 65 | t.assertEqual("bar,bar,new",testStrs.join(',')); |
---|
| 66 | }, |
---|
| 67 | function perf(t){ |
---|
| 68 | var getter = function(obj,i){ |
---|
| 69 | return obj[i]; |
---|
| 70 | }; |
---|
| 71 | var observable = new dojox.lang.makeObservable( |
---|
| 72 | function(obj,i){ |
---|
| 73 | return obj[i]; |
---|
| 74 | }, |
---|
| 75 | function(obj,i,value){ |
---|
| 76 | obj[i] = value; |
---|
| 77 | }, |
---|
| 78 | function(scope,obj,i,args){ |
---|
| 79 | return obj[i].apply(scope,args); |
---|
| 80 | } |
---|
| 81 | ); |
---|
| 82 | var obj = {foo:"bar",bar:'foo'}; |
---|
| 83 | var newObj = observable(obj); |
---|
| 84 | var start = new Date().getTime(); |
---|
| 85 | for(var i = 0; i < 100000;i++){ // normal access |
---|
| 86 | var a = obj.foo; |
---|
| 87 | a = obj.bar; |
---|
| 88 | } |
---|
| 89 | var store = { |
---|
| 90 | getValue:function(item, property,lazyCallback){ |
---|
| 91 | // summary: |
---|
| 92 | // Gets the value of an item's 'property' |
---|
| 93 | // |
---|
| 94 | // item: /* object */ |
---|
| 95 | // property: /* string */ |
---|
| 96 | // property to look up value for |
---|
| 97 | // lazyCallback: /* function*/ |
---|
| 98 | // not part of the API, but if you are using lazy loading properties, you may provide a callback to resume, in order to have asynchronous loading |
---|
| 99 | var value = item[property]; |
---|
| 100 | if(value instanceof dojo.Deferred){ |
---|
| 101 | dojox.rpc._sync = !lazyCallback; // tell the service to operate synchronously (I have some concerns about the "thread" safety with FF3, as I think it does event stacking on sync calls) |
---|
| 102 | value.addCallback(function(returned){ |
---|
| 103 | value = returned; |
---|
| 104 | if(lazyCallback){lazyCallback(value);} |
---|
| 105 | return value; |
---|
| 106 | } |
---|
| 107 | ); |
---|
| 108 | delete dojox.rpc._sync; // revert to normal async behavior |
---|
| 109 | }else if(lazyCallback){lazyCallback(value);} |
---|
| 110 | return value; |
---|
| 111 | } |
---|
| 112 | }; |
---|
| 113 | console.log(new Date().getTime() - start); |
---|
| 114 | start = new Date().getTime(); |
---|
| 115 | for(i = 0; i < 100000;i++){// observed access |
---|
| 116 | a = store.getValue(obj,"foo"); |
---|
| 117 | a = store.getValue(obj,"bar"); |
---|
| 118 | } |
---|
| 119 | console.log(new Date().getTime() - start); |
---|
| 120 | start = new Date().getTime(); |
---|
| 121 | for(i = 0; i < 1000000;i++){ // measure the loop time itself |
---|
| 122 | } |
---|
| 123 | console.log(new Date().getTime() - start); |
---|
| 124 | } |
---|
| 125 | ]); |
---|
| 126 | })(); |
---|