Changeset 33

Show
Ignore:
Timestamp:
01/10/06 18:12:52 (3 years ago)
Author:
Jan-Klaas Kollhof
Message:

added hash() and bind() function, fixed sets and added a name argument to testing.test()

Files:

Legend:

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

    r32 r33  
    6363                         __name__ : name, 
    6464                         __bases__: bases, 
    65                          __id__:classID, 
     65                         __id__: '@' + classID, 
    6666                         __hash__: function(){ 
    6767                            return this.__id__; 
     
    115115        proto.__hash__=function(){ 
    116116            if(this.__id__ === undefined){ 
    117                 this.__id__ = Class.__idcount__++
     117                this.__id__ = '@' + (Class.__idcount__++)
    118118            } 
    119119            return this.__id__; 
     
    197197        }; 
    198198    } 
    199      
    200199 
    201200    //reset the constructor for new objects to the actual constructor. 
     
    234233str = function(obj){ 
    235234    return "" + obj; 
     235}; 
     236 
     237/** 
     238    Returns a hash value for an object. 
     239    The same object will always return the same hash.  
     240    Most objects are hashable. The following steps are taken to find a hash value: 
     241    If the obj has an __id__ property that id will be returned. (all jsolait classes have an __id__ property) 
     242    If the obj has a __hash__ method the return value of that method will be returned.(all jsolait objects have a __hash__ method which sets an __id__ property) 
     243    If the obj is a String  the string prefixed with $ is returned. 
     244    If the obj is a Number the number prefixed with a # is returned as a string. 
     245    All other objects are not safely hashable and an exception is thrown unless forceId is true. In that case the object will get a unique __id__ property applied which is returned. 
     246     
     247    @param obj The object to hash. 
     248    @param forceId=false if true it forces hash() to set an __id__ property onto a non hashable object, making it hashable. 
     249    @return A String containing a hash value for the obj. 
     250**/ 
     251hash = function(obj, forceId){ 
     252    if(obj.__id__){ 
     253        return obj.__id__; 
     254    }else  if(obj.__hash__){ 
     255        return obj.__hash__(); 
     256    }else if(obj instanceof String || typeof obj == 'string'){ 
     257        return '$' + obj; 
     258    }else if(obj instanceof Number || typeof obj == 'number'){ 
     259        return '#' + obj; 
     260    }else if(forceId){ 
     261        obj.__id__ = '@' + (Class.__idcount__++); 
     262        return obj.__id__; 
     263    }else{ 
     264        throw new jsolait.Exception('Objec cannot be hashed: %s'.format(obj)); 
     265    }; 
     266}; 
     267 
     268/** 
     269    Returns a bound method. 
     270    A bound method is a function which is bound to a specific object. 
     271    Calling the bound method will call the given function with the this-object inside that function's scope being the object specified. 
     272     
     273    @param obj  The object the function should be bound to. 
     274    @param fn   A function object the obj will be bound to. 
     275    @return A method which when run executes the function with the this-object being the obj specified. 
     276**/ 
     277bind = function(obj, fn){ 
     278    return function(){ 
     279        return fn.apply(obj, arguments); 
     280    }; 
    236281}; 
    237282 
     
    261306 
    262307/** 
    263     Returns is a cls is a direct or indirect subclass of another. 
     308    Returns if a cls is a direct or indirect subclass of another. 
    264309     
    265310    A class is always a subclass of itself and Object is the base for all classes. 
     
    304349**/ 
    305350Module=function(name, version, moduleScope){ 
    306     var newMod = {}; 
    307     newMod.name = name; 
    308     newMod.version = version; 
    309     newMod.__sourceURI__ = Module.currentURI; 
    310  
    311     newMod.toString=function(){ 
    312         //todo:SVN adaption 
    313         return "[module '%s' version: %s]".format(this.name, (this.version+'').replace(/\$Revision:\s(\d+) \$/, "rev.$1")); 
    314     }; 
    315  
    316     //give a module it's own exception class which makes debugging easier 
    317     newMod.Exception=Class(Module.Exception, function(publ, supr){ 
    318         publ.module = newMod; 
    319     }); 
    320  
     351    var newMod = new Module.ModuleClass(name, version, Module.currentURI); 
     352     
    321353    try{//to execute the scope of the module 
    322354        moduleScope.call(newMod, newMod); 
     
    324356        throw new Module.ModuleScopeExecFailed(newMod, e); 
    325357    } 
    326  
     358     
    327359    //set __name__  for methods and classes 
    328360    for(var n in newMod){ 
     
    332364        } 
    333365    } 
     366     
    334367    jsolait.registerModule(newMod); 
    335368    return newMod; 
    336369}; 
     370 
     371Module.ModuleClass=Class(function(publ){ 
     372    publ.name; 
     373    publ.version; 
     374    publ.__sourceURI__; 
     375    publ.Exception; 
     376     
     377    publ.__init__=function(name,version,sourceURI){ 
     378        this.name=name; 
     379        this.version=version; 
     380        this.__sourceURI__ = sourceURI; 
     381        this.Exception = Class(Module.Exception, function(){}); 
     382        this.Exception.prototype.module = this; 
     383    }; 
     384     
     385    publ.__str__=function(){ 
     386        //todo:SVN adaption 
     387        return "[module '%s' version: %s]".format(this.name, (this.version+'').replace(/\$Revision:\s(\d+) \$/, "rev.$1")); 
     388    }; 
     389}); 
     390 
    337391 
    338392Module.toString=function(){ 
  • trunk/jsolait/lib/sets.js

    r21 r33  
    8585        /** 
    8686            Adds an item to the set if it does not exist yet. 
    87             @param item The item to add. 
     87            @param item A hashable item to add. 
    8888            @return        The item added. 
    8989        **/ 
    9090        publ.add=function(item){ 
    91             var h; 
    92             if(item.__hash__){ 
    93                 h='@' +item.__hash__(); 
    94             }else{ 
    95                 h='#' +item; 
    96             } 
    97             this.items[h] = item; 
     91            this.items[hash(item)] = item; 
    9892            return item; 
    9993        }; 
     
    108102        **/ 
    109103        publ.remove=function(item){ 
    110             var h; 
    111             if(item.__hash__){ 
    112                 h='@' +item.__hash__(); 
    113             }else{ 
    114                 h='#' +item; 
    115             } 
     104            var h = hash(item); 
    116105            if(this.items[h] === undefined){ 
    117106                throw new mod.ItemNotFoundInSet(this, item); 
     
    129118        **/ 
    130119        publ.discard=function(item){ 
    131             var h; 
    132             if(item.__hash__){ 
    133                 h='@' +item.__hash__(); 
    134             }else{ 
    135                 h='#' +item; 
    136             } 
     120            var h = hash(item); 
    137121            item = this.items[h]; 
    138122            delete this.items[h]; 
     
    146130        **/ 
    147131        publ.contains=function(item){ 
    148             var h; 
    149             if(item.__hash__){ 
    150                 h='@' +item.__hash__(); 
    151             }else{ 
    152                 h='#' +item; 
    153             } 
    154             return (this.items[h] !== undefined); 
     132            return (this.items[hash(item)] !== undefined); 
    155133        }; 
    156134        /** 
     
    346324        var testing=imprt('testing'); 
    347325 
    348         print(testing.test(function(){ 
     326        print(testing.test('sets', function(){ 
    349327            testing.assertEquals("checking %s | %s".format(s1, s2), 
    350328                                        new mod.Set("0123456789"), s1.union(s2)); 
  • trunk/jsolait/lib/testing.js

    r27 r33  
    116116        publ.report=function(){ 
    117117            if(this.error){ 
    118                 return "Test %s has failed after %s ms due to:\n\n%s".format(this.name, this.duration, this.error.toTraceString().indent(4)); 
     118                return "Test '%s' has failed after %s ms due to:\n\n%s".format(this.name, this.duration, this.error.toTraceString().indent(4)); 
    119119            }else{ 
    120                 return "Test %s completed in %s ms".format( this.name, this.duration); 
     120                return "Test '%s' completed in %s ms".format( this.name, this.duration); 
    121121            } 
    122122        }; 
     
    130130    /** 
    131131        Runs a test on the given function. 
     132        @param name='anonymous' The name for the test. 
    132133        @param testScope  A function to test. 
    133134    **/ 
    134     mod.test=function(testScope){ 
    135         var t= new mod.Test(testScope); 
     135    mod.test=function(name, testScope){ 
     136        if(arguments.length == 1){ 
     137            testScope = name; 
     138            name = 'anonymous'; 
     139        } 
     140        var t= new mod.Test(name, testScope); 
    136141        t.run(); 
    137142        return t.report(); 
     
    277282 
    278283    mod.__main__=function(){ 
    279         print(mod.test(function(){ 
     284        print(mod.test('assertion test', function(){ 
    280285            mod.assert(true); 
    281286            mod.assertTrue(true);