Changeset 47

Show
Ignore:
Timestamp:
03/15/06 16:59:09 (3 years ago)
Author:
Jan-Klaas Kollhof
Message:

adding unittesting, rewritten iter, fixing global->public in operators, fixing sets and testing

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/jsolait/lib/iter.js

    r32 r47  
    11/* 
    2   Copyright (c) 2004 Jan-Klaas Kollhof 
     2  Copyright (c) 2004-2006 Jan-Klaas Kollhof 
    33 
    44  This is free software; you can redistribute it and/or modify 
     
    1919 
    2020/** 
    21     Iterator module providing iteration services. 
    22     There is one global function iter() which can be used to iterate over iterable objects synchronously or 
    23     if given a callback asynchronously. 
    24     An iterable object is an object which has an iterator function (__iter__) which returns an Iterator object. 
    25  
    26     The Range class is there to create an iterable object over a range of numbers. 
    27  
     21    Iteration module providing functionality for working with iterable objects. 
     22     
     23    To enable any object to be iterable the module introduces a number of iteration protocolls 
     24    and provides default implementation for it. 
     25     
     26    For an object to be iterable it must provide an __iter__() method that returns an Iterator object. 
     27    See iter.iter() and iter.Iterator for more info. 
     28     
     29    There are also some function provided for iterating over iterable object and performing operations on it's items. 
     30    iter() - for iterating over iterable objects, 
     31    map() - for maping items from an iterable object to a list, 
     32    filter() - for creating a list caontaining only certain items from an iterable object 
     33    list() - for creating a list containing all items from an iterable object. 
     34     
     35    The above methods only create an iterator for an iteratable object and call one of it's methods depending on what protocoll is used. 
     36    See iter.Iterator for more information. 
     37     
     38    There is also a range() method for creating a iterator for a range of numbers. 
     39         
    2840    @creator                 Jan-Klaas Kollhof 
    2941    @created                2004-12-08 
    3042    @lastchangedby       $LastChangedBy$ 
    3143    @lastchangeddate    $Date$ 
    32 *
     44**
    3345Module("iter", "$Revision$", function(mod){ 
    3446 
    3547    /** 
    3648        Base class for Iterators. 
    37     *
     49    **
    3850    mod.Iterator=Class(function(publ, supr){ 
    3951        /** 
    4052            Returns the next item in the iteration. 
    4153            If there is no item left it throws StopIteration 
    42         *
     54        **
    4355        publ.next=function(){ 
    4456            return undefined; 
    4557        }; 
     58                 
    4659        /** 
    4760            Used so an Iterator can be passed to iteration functions. 
    48         *
     61        **
    4962        publ.__iter__ = function(){ 
    5063            return this; 
    5164        }; 
     65         
     66        publ.__iterate__=function(thisObj, cb){ 
     67            var result; 
     68            thisObj = thisObj==null?this:thisObj; 
     69            while(((item=this.next()) !== undefined) && result===undefined){ 
     70                result=cb.call(thisObj, item, this); 
     71            } 
     72            return result; 
     73        }; 
     74         
     75        publ.__filter__ = function(thisObj, cb){ 
     76            var result=[]; 
     77            thisObj = thisObj==null?this:thisObj; 
     78            var item; 
     79            while((item=this.next()) !== undefined){ 
     80                if(cb.call(thisObj, item, this)){ 
     81                    result.push(item); 
     82                } 
     83            } 
     84            return result; 
     85        }; 
     86         
     87        publ.__map__ = function(thisObj, cb){ 
     88            var result=[]; 
     89            thisObj = thisObj==null?this:thisObj; 
     90            var  item; 
     91            while((item=this.next()) !== undefined){ 
     92                result.push(cb.call(thisObj, item, this)); 
     93            } 
     94            return result; 
     95        }; 
     96         
     97        publ.__list__ = function(){ 
     98            var list = []; 
     99            while((item=this.next()) !== undefined){ 
     100                list.push(item); 
     101            } 
     102            return list; 
     103        }; 
     104         
     105        publ.replace = function(item){ 
     106            throw new mod.Exception("Iterator::replace() not implemented"); 
     107        }; 
    52108    }); 
    53109 
    54110    /** 
    55111        A simple range class to iterate over a range of numbers. 
    56     *
     112    **
    57113    mod.Range =Class(mod.Iterator, function(publ, supr){ 
    58114        /** 
     
    61117            @param end       The last item in the range. 
    62118            @param step=1 The steps between each Item. 
    63         *
     119        **
    64120        publ.__init__=function(start, end, step){ 
    65121            switch(arguments.length){ 
     
    82138            this.current=this.start - this.step; 
    83139        }; 
    84  
     140         
    85141        publ.next = function(){ 
    86             if(this.current + this.step > this.end){ 
     142            var n = this.current + this.step; 
     143            if(n > this.end){ 
    87144                this.current=this.start; 
    88145                return undefined; 
    89146            }else{ 
    90                 this.current = this.current + this.step
     147                this.current = n
    91148                return this.current; 
    92149            } 
    93150        }; 
    94  
     151         
     152        publ.__iterate__=function(thisObj, cb){ 
     153            var result=undefined; 
     154            for(this.current += this.step; this.current <= this.end && result===undefined;this.current += this.step){ 
     155                result=cb.call(thisObj, this.current, this); 
     156            } 
     157            return result; 
     158        }; 
    95159    }); 
    96  
    97     Range = mod.Range; 
     160     
     161    /** 
     162        Returns a new Range object. 
     163        @param start=0  The first item in the range. 
     164        @param end       The last item in the range. 
     165        @param step=1 The steps between each Item. 
     166    **/ 
     167    mod.range = function(start, end, step){ 
     168        var r=new mod.Range(Class); 
     169        r.__init__.apply(r, arguments); 
     170        return r; 
     171    }; 
    98172 
    99173    /** 
    100174        Iterator for Arrays. 
    101     *
     175    **
    102176    mod.ArrayItereator=Class(mod.Iterator, function(publ, supr){ 
    103177        publ.__init__=function(array){ 
     
    105179            this.index = -1; 
    106180        }; 
     181         
    107182        publ.next = function(){ 
    108183            this.index += 1; 
     
    113188            } 
    114189        }; 
     190         
     191        publ.__iterate__=function(thisObj, cb){ 
     192            var result=undefined; 
     193            thisObj = thisObj==null?this:thisObj; 
     194            var args = [null,this]; 
     195            for(this.index++; this.index<this.array.length && result===undefined; this.index++){ 
     196                result= cb.call(thisObj, this.array[this.index], this); 
     197            } 
     198        }; 
     199         
     200        publ.__list__ = function(){ 
     201            return [].concat(this.array); 
     202        }; 
     203         
     204        publ.replace=function(item1, item2){ 
     205            switch(arguments.length){ 
     206                case 0: 
     207                    this.array.splice(this.index, 1); 
     208                    break; 
     209                case 1: 
     210                    this.array.splice(this.index, 1, item); 
     211                    break; 
     212                default: 
     213                    var a=[this.index, arguments.length]; 
     214                    for(var i=0;i<arguments.length;i++){ 
     215                        a.push(arguments[i]); 
     216                    } 
     217                    this.array.splice.apply(this.array,a); 
     218            } 
     219            this.index += arguments.length -1; 
     220        }; 
    115221    }); 
    116  
     222     
     223    Array.prototype.__iter__ = function(){ 
     224        return new mod.ArrayItereator(this); 
     225    }; 
     226     
    117227    /** 
    118228        Iterator for Objects. 
    119     *
     229    **
    120230    mod.ObjectIterator=Class(mod.Iterator, function(publ, supr){ 
    121231        publ.__init__=function(obj){ 
     
    125235                this.keys.push(n); 
    126236            } 
    127  
    128237            this.index = -1; 
    129238        }; 
     
    145254    }); 
    146255 
    147     Array.prototype.__iter__ = function(){ 
    148         return new mod.ArrayItereator(this); 
    149     }; 
    150  
     256    /** 
     257        Returns the iterator for an iterable object or iterates over al items of the iterable object by 
     258        using the iterable's iterator's __iterate__ method. 
     259         
     260        An iteration stops if the callback returns any value except undefined. 
     261        The value returned by the callback will be returned to the caller of iter(). 
     262        @param iterable          The iterable object. 
     263        @param thisObj=return The this object to use when calling the callback. 
     264        @param cb                  An IterationCallback object to call for each step. 
     265        @return                      An iterator object or the return value returned by the callback. 
     266    **/ 
     267    mod.iter=function(iterable, thisObj, cb){ 
     268        var iterator; 
     269        if(iterable.__iter__ !==undefined){ 
     270            iterator = iterable.__iter__(); 
     271        }else if(iterable.length != null){ 
     272            iterator = new mod.ArrayItereator(iterable); 
     273        }else if(iterable.constructor == Object){ 
     274            iterator  = new mod.ObjectIterator(iterable); 
     275        }else{ 
     276            throw new mod.Exception("Iterable object does not provide __iter__ method or no Iterator found.") 
     277        } 
     278        if(arguments.length==1){ 
     279            return iterator; 
     280        }else{ 
     281            if(cb == null){ 
     282                cb = thisObj; 
     283                thisObj = null; 
     284            } 
     285            return iterator.__iterate__(thisObj, cb); 
     286        } 
     287    }; 
     288     
    151289    /** 
    152290        Interface of a IterationCallback. 
    153291        @param item The item returned by the iterator for the current step. 
    154292        @param iteration The Iteration object handling the iteration. 
    155     *
     293    **
    156294    mod.IterationCallback = function(item, iteration){}; 
    157295 
    158296    /** 
    159         Iteration class for handling iteration steps and callbacks. 
    160     */ 
    161     mod.Iteration = Class(function(publ,supr){ 
    162         /** 
    163             Initializes an Iteration object. 
    164             @param iterable An itaratable object. 
    165             @param thisObj 
    166             @param callback An IterationCallback object. 
    167         */ 
    168         publ.__init__=function(iterable, thisObj, callback){ 
    169             this.doStop = false; 
    170             this.thisObj=thisObj; 
    171             if(iterable.__iter__ !==undefined){ 
    172                 this.iterator = iterable.__iter__(); 
    173             }else{ 
    174                 this.iterator = new mod.ObjectIterator(iterable); 
    175             } 
    176  
    177             this.callback = callback; 
    178         }; 
    179  
    180         ///Resumes a stoped iteration. 
    181         publ.resume = function(){ 
    182             this.doStop = false; 
    183             var item; 
    184             while(!this.doStop){ 
    185                 item=this.iterator.next(); 
    186                 if(item === undefined){ 
    187                     this.stop(); 
    188                 }else{ 
    189                     //let the callback handle the item 
    190                     this.callback.call(this.thisObj==null?this : this.thisObj,  item, this); 
    191                 } 
    192             } 
    193         }; 
    194  
    195         ///Stops an iteration 
    196         publ.stop = function(){ 
    197             this.doStop = true; 
    198         }; 
    199  
    200         ///Starts/resumes an iteration 
    201         publ.start = function(){ 
    202             this.resume(); 
    203         }; 
    204     }); 
    205  
    206     /** 
    207         Class for handling asynchronous iterations. 
    208     */ 
    209     mod.AsyncIteration = Class(mod.Iteration, function(publ, supr){ 
    210         /** 
    211             Initializes an AsyncIteration object. 
    212             @param iterable An itaratable object. 
    213             @param interval The time in ms betwen each step. 
    214             @param thisObj 
    215             @param callback An IterationCallback object. 
    216         */ 
    217         publ.__init__=function(iterable, interval, thisObj, callback){ 
    218             this.doStop = false; 
    219             this.thisObj=thisObj; 
    220             if(iterable.__iter__ !==undefined){ 
    221                 this.iterator = iterable.__iter__(); 
    222             }else{ 
    223                 this.iterator = new mod.ObjectIterator(iterable); 
    224             } 
    225             this.interval = interval; 
    226             this.callback = callback; 
    227             this.isRunning = false; 
    228         }; 
    229  
    230         publ.stop=function(){ 
    231             if(this.isRunning){ 
    232                 this.isRunning = false; 
    233                 clearTimeout(this.timeout); 
    234                 delete iter.iterations[this.__hash__()]; 
    235             } 
    236         }; 
    237  
    238         publ.resume = function(){ 
    239             if(this.isRunning == false){ 
    240                 this.isRunning = true; 
    241                 var id = this.__hash__(); 
    242                 iter.iterations[id] = this; 
    243                 //let the iteration be handled using a timer 
    244                 this.timeout = setTimeout("iter.handleAsyncStep('" + id + "')", this.interval); 
    245             } 
    246         }; 
    247  
    248         publ.handleAsyncStep = function(){ 
    249             if(this.isRunning){ 
    250                 var item=this.iterator.next(); 
    251                 if(item === undefined){ 
    252                     this.stop(); 
    253                 }else{ 
    254                     //let the callback handle the item 
    255                     this.callback.call(this.thisObj==null?this : this.thisObj,  item, this); 
    256                     this.timeout = setTimeout("iter.handleAsyncStep('" + this.__hash__()+ "')", this.interval); 
    257                 } 
    258             } 
    259         }; 
    260     }); 
    261  
    262  
    263     /** 
    264         Iterates over an iterable object and calls a callback for each item. 
     297        Returns a list containing all elements from an iteratable object for which the callback returns true. 
     298         
    265299        @param iterable          The iterable object. 
    266         @param delay=-1         If delay >-1 specifies the time between each iteration step and creates a ansync iteration. 
    267300        @param thisObj=return The this object to use when calling the callback. 
    268         @param cb                  An IterationCallback object to call for each step. 
    269         @return         An Iteration object. 
    270     */ 
    271     iter = function(iterable, delay, thisObj, cb){ 
    272         cb=arguments[arguments.length-1]; 
    273         if((arguments.length == 3) && (typeof delay =='object')){ 
    274             thisObj=delay; 
    275             delay=-1; 
    276         }else{ 
    277             thisObj=null; 
     301        @param cb                  An IterationCallback object to call for each item. 
     302        @return                      A list containing all elements that were filtered. 
     303    **/ 
     304    mod.filter=function(iterable, thisObj,cb){ 
     305        var iterator = mod.iter(iterable); 
     306        if(cb == null){ 
     307            cb = thisObj; 
     308            thisObj = null; 
    278309        } 
    279         if(delay >-1){ 
    280             var it = new mod.AsyncIteration(iterable, delay, thisObj, cb); 
    281         }else{ 
    282             var it = new mod.Iteration(iterable, thisObj, cb); 
     310        return iterator.__filter__(thisObj, cb); 
     311    }; 
     312     
     313    /** 
     314        Returns a list containing elements returned by the callback for each item form the itrable object. 
     315         
     316        @param iterable          The iterable object. 
     317        @param thisObj=return The this object to use when calling the callback. 
     318        @param cb                  An IterationCallback object to call for each item. 
     319        @return                      A list containing new elements. 
     320    **/         
     321    mod.map=function(iterable, thisObj, cb){ 
     322        var iterator  = mod.iter(iterable); 
     323        if(cb == null){ 
     324            cb = thisObj; 
     325            thisObj = null; 
    283326        } 
    284         it.start(); 
    285         return it; 
    286     }; 
    287  
    288     iter.handleAsyncStep = function(id){ 
    289         if(iter.iterations[id]){ 
    290            iter.iterations[id].handleAsyncStep(); 
    291         } 
    292     }; 
    293     ///Helper object containing all async. iteration objects. 
    294     iter.iterations = {}; 
    295  
    296  
    297     mod.__main__=function(){ 
    298  
    299  
    300         var  testing = imprt('testing'); 
    301         var task=function(){ 
    302             var s=''; 
    303             for(var i=0;i<10;i++){ 
    304                 s+=i; 
    305             } 
    306         }; 
    307  
    308         r = []; 
    309         for(var i=0;i<100;i++){ 
    310             r[i] = i; 
    311         } 
    312  
    313         print("for loop \t\t\t" + testing.profile(function(){ 
    314             var s=''; 
    315             for(var i=0;i<100;i++){ 
    316                 s+=r[i]; 
    317                 task(); 
    318             } 
    319         })); 
    320  
    321         print("Range iter \t\t" + testing.profile(function(){ 
    322             var s=''; 
    323             iter(new mod.Range(100), function(item,i){ 
    324                 s+=r[item]; 
    325                 task(); 
    326             }); 
    327         })); 
    328  
    329         print("Array iter \t\t\t" + testing.profile(function(){ 
    330             var s=''; 
    331             iter(r , function(item,i){ 
    332                 s+=item; 
    333                 task(); 
    334             }); 
    335  
    336         })); 
    337  
    338         print("for in on Array \t\t" + testing.profile(function(){ 
    339             var s=''; 
    340             for(var i in r){ 
    341                 s+=r[i]; 
    342                 task(); 
    343             } 
    344         })); 
    345  
    346         r = []; 
    347         for(var i=0;i<100;i++){ 
    348             r["k"+i] = i; 
    349         } 
    350  
    351         print("for in  on assoc. Array \t" + testing.profile(function(){ 
    352             var s=''; 
    353             for(var i in r){ 
    354                 s+=r[i]; 
    355                 task(); 
    356             } 
    357         })); 
    358  
    359         r = {}; 
    360         for(var i=0;i<100;i++){ 
    361             r["k"+i] = i; 
    362         } 
    363  
    364         print("for in on dictionary \t" + testing.profile(function(){ 
    365             var s=''; 
    366             for(var i in r){ 
    367                 s+=r[i]; 
    368                 task(); 
    369             } 
    370         })); 
    371  
    372         r = []; 
    373         for(var i=0;i<100;i++){ 
    374             r[i] = i; 
    375         } 
    376  
    377         print("for on Array + iter \t" + testing.profile(function(){ 
    378             var s=''; 
    379             for(i=r.__iter__(); item=i.next() !==undefined;){ 
    380                 s+= item; 
    381                 task(); 
    382             } 
    383         })); 
    384     }; 
     327        return iterator.__map__(thisObj, cb); 
     328    }; 
     329     
     330    /** 
     331        Returns a list containing all elements from an iteratable object. 
     332        I.e. this function turns any iterable object into a list(Array). 
     333         
     334        @param iterable          The iterable object. 
     335        @return                      A list containing all elements. 
     336    **/     
     337    mod.list=function(iterable){ 
     338        return mod.iter(iterable).__list__(); 
     339    }; 
     340 
    385341}); 
  • trunk/jsolait/lib/operators.js

    r44 r47  
    2929Module("operators", "$Revision: 20 $", function(mod){ 
    3030 
    31     lt=function(a, b){ 
     31    mod.lt=function(a, b){ 
    3232        if((a!=null) && (a.__lt__!==undefined)){ 
    3333            return a.__lt__(b); 
     
    3939    }; 
    4040 
    41     le=function(a, b){ 
     41    mod.le=function(a, b){ 
    4242        if((a!=null) && (a.__le__!==undefined)){ 
    4343            return a.__le__(b); 
     
    4949    }; 
    5050 
    51     eq=function(a, b){ 
     51    mod.eq=function(a, b){ 
    5252        if((a!=null) && (a.__eq__!==undefined)){ 
    5353            return a.__eq__(b); 
     
    5555            return b.__eq__(a); 
    5656        }else{ 
    57             return a===b; 
     57            return a==b; 
    5858        } 
    5959    }; 
    60  
    61     ne=function(a, b){ 
     60     
     61    mod.ne=function(a, b){ 
    6262        if((a!=null) && (a.__ne__!==undefined)){ 
    6363            return a.__ne__(b); 
     
    6565            return b.__ne__(a); 
    6666        }else{ 
    67             return a !== b; 
     67            return a != b; 
    6868        } 
    6969    }; 
    70  
    71     ge=function(a, b){ 
     70     
     71    mod.is=function(a,b){ 
     72        if((a!=null) && (a.__is__!==undefined)){ 
     73            return a.__is__(b); 
     74        }else if((b!=null) && (b.__is__!==undefined)){ 
     75            return b.__is__(a); 
     76        }else{ 
     77            return a===b; 
     78        } 
     79    }; 
     80     
     81    mod.isnot=function(a,b){ 
     82        if((a!=null) && (a.__isnot__!==undefined)){ 
     83            return a.__isnot__(b); 
     84        }else if((b!=null) && (b.__isnot__!==undefined)){ 
     85            return b.__isnot__(a); 
     86        }else{ 
     87            return a!==b; 
     88        } 
     89    }; 
     90     
     91    mod.ge=function(a, b){ 
    7292        if((a!=null) && (a.__ge__!==undefined)){ 
    7393            return a.__ge__(b); 
     
    7999    }; 
    80100 
    81     gt=function(a, b){ 
     101    mod.gt=function(a, b){ 
    82102        if((a!=null) && (a.__gt__!==undefined)){ 
    83103            return a.__gt__(b); 
     
    89109    }; 
    90110 
    91     not=function(a){ 
     111    mod.not=function(a){ 
    92112        if((a!=null) && (a.__not__!==undefined)){ 
    93113            return a.__not__(); 
  • trunk/jsolait/lib/sets.js

    r33 r47  
    5252        /** 
    5353            Initializes a Set instance. 
    54             @param elem*   An element which is added to the set or an Array, String or iterable object of which the elements are added to the set. 
     54            @param elem*   An element which is added to the set or an iterable object of which the elements are added to the set. 
    5555        **/ 
    5656        publ.__init__=function(elem){ 
    57  
    5857            this.items = {}; 
    59             var elems =[]; 
    60  
     58             
    6159            if(arguments.length > 1){ 
    62                elems=arguments; 
     60                for(var i=0;i<arguments.length;i++){ 
     61                    this.add(arguments[i]); 
     62                } 
    6363            }else if(arguments.length == 1){ 
    64                 elems = arguments[0]; 
     64                var elems = arguments[0]; 
    6565                if(elems instanceof Array){ 
    66                 }else if(typeof elems == "string"){ 
    67                     elems=elems.split(""); 
    68                 }else if(elems.__iter__){ 
    69                     var i=iterable.__iter__(); 
    70                     var item; 
    71                     while(item=i.next()!==undefined){ 
     66                    for(var i=0;i<elems.length;i++){ 
     67                        this.add(elems[i]); 
     68                    } 
     69                }else{//todo needs optimization! 
     70                    imprt('iter').iter(elems,this, function(item){ 
    7271                        this.add(item); 
    73                     } 
    74                     return; 
    75                 }else{ 
    76                     throw new mod.Exception("Array,String or iterable object expected but found %s".format(elems)); 
    77                 } 
    78             } 
    79  
    80             for(var i=0;i<elems.length;i++){ 
    81                 this.add(elems[i]); 
     72                    }); 
     73                } 
    8274            } 
    8375        }; 
     
    316308    }); 
    317309 
    318  
    319     mod.__main__=function(){ 
    320  
    321  
    322         var s1=new mod.Set("0123456"); 
    323         var s2=new mod.Set("3456789"); 
    324         var testing=imprt('testing'); 
    325  
    326         print(testing.test('sets', function(){ 
    327             testing.assertEquals("checking %s | %s".format(s1, s2), 
    328                                         new mod.Set("0123456789"), s1.union(s2)); 
    329  
    330             testing.assertEquals("checking %s | %s".format(s2, s1), 
    331                                         new mod.Set("0123456789"), s2.union(s1)); 
    332  
    333             testing.assertEquals("checking %s & %s".format(s1, s2), 
    334                                          new mod.Set("3456"), s1.intersection(s2)); 
    335  
    336             testing.assertEquals("checking %s & %s".format(s2, s1), 
    337                                         new mod.Set("3456"), s2.intersection(s1)); 
    338  
    339             testing.assertEquals("checking %s - %s".format(s1, s2), 
    340                                         new mod.Set("012"), s1.difference(s2)); 
    341  
    342             testing.assertEquals("checking %s - %s".format(s2, s1), 
    343                                         new mod.Set("789"), s2.difference(s1)); 
    344  
    345             testing.assertEquals("checking %s ^ %s".format(s1, s2), 
    346                                         new mod.Set("012789"),s1.symmDifference(s2)); 
    347  
    348             testing.assertEquals("checking %s ^ %s".format(s2, s1), 
    349                                         new mod.Set("012789"),s2.symmDifference(s1)); 
    350         })); 
    351     }; 
    352310}); 
    353311 
  • trunk/jsolait/lib/testing.js

    r33 r47  
    209209            comment =''; 
    210210        } 
    211         mod.assert(comment, eq(value1, value2), "Expected %s === %s.".format(value1, value2)); 
    212     }; 
    213  
     211        mod.assert(comment, ops.eq(value1, value2), "Expected %s == %s.".format(value1, value2)); 
     212    }; 
     213         
    214214    mod.assertNotEquals=function(comment, value1, value2){ 
    215215        if(arguments.length==2){ 
     
    218218            comment =''; 
    219219        } 
    220         mod.assert(comment, ne(value1, value2), "Expected %s !== %s.".format(value1, value2)); 
    221     }; 
    222  
     220        mod.assert(comment, ops.ne(value1, value2), "Expected %s != %s.".format(value1, value2)); 
     221    }; 
     222 
     223    mod.assertIs=function(comment, value1, value2){ 
     224        if(arguments.length==2){ 
     225            value2=value1; 
     226            value1 = comment; 
     227            comment =''; 
     228        } 
     229        mod.assert(comment, ops.is(value1, value2), "Expected %s === %s.".format(value1, value2)); 
     230    }; 
     231         
     232    mod.assertIsNot=function(comment, value1, value2){ 
     233        if(arguments.length==2){ 
     234            value2=value1; 
     235            value1 = comment; 
     236            comment =''; 
     237        } 
     238        mod.assert(comment, ops.isnot(value1, value2), "Expected %s !== %s.".format(value1, value2)); 
     239    }; 
     240     
    223241    mod.assertNull=function(comment, value){ 
    224242        if(arguments.length==1){ 
     
    279297        } 
    280298        return keys; 
    281     }; 
    282  
    283     mod.__main__=function(){ 
    284         print(mod.test('assertion test', function(){ 
    285             mod.assert(true); 
    286             mod.assertTrue(true); 
    287             mod.assertFalse(false); 
    288             mod.assertNull(null); 
    289             mod.assertNotNull(undefined); 
    290             mod.assertNotNull(''); 
    291             mod.assertNotNull({}); 
    292             mod.assertNotNull(0); 
    293             mod.assertUndefined(undefined); 
    294             mod.assertNotUndefined(null); 
    295             mod.assertNaN(NaN); 
    296             mod.assertNotNaN(435); 
    297             mod.assertEquals(1,1); 
    298             mod.assertEquals("a","a"); 
    299             mod.assertEquals(null,null); 
    300             mod.assertEquals(undefined,undefined); 
    301             mod.assertEquals(mod,mod); 
    302             mod.assertNotEquals(1,2); 
    303             mod.assertNotEquals(null,undefined); 
    304             mod.assertNotEquals(mod,{}); 
    305         })); 
    306     }; 
     299    };  
     300 
    307301}); 
    308302