Commits

Anonymous committed d6824bb

add tests for fox.util.cache; add fox.util.hash function

  • Participants
  • Parent commits df01ae8

Comments (0)

Files changed (2)

File src/fox.util.js

 *       A simple light-weight library for production JavaScript.
 *
 * NOTES
-*       - A major goal of this library is to make cross-browser 
+*       - A major goal of this library is to make cross-browser
 * compatible, reviewed, production code.
 *
 * SEE ALSO
 *
 * COPYRIGHT
 * The MIT License (MIT)
-* 
+*
 * Copyright (c) 2013 Bradley Workman
-* 
+*
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * THE SOFTWARE.
 *******/
 
-if(typeof fox == "undefined" || !fox) fox = {};
-if(typeof fox.util == "undefined" || !fox.util) fox.util = {};
+if (typeof fox == 'undefined' || !fox) fox = {};
+if (typeof fox.util == 'undefined' || !fox.util) fox.util = {};
 
-(function(){
-        if(fox.util.uuid) return;
+(function() {
+        if (fox.util.uuid) return;
 
         /****f* fox.util/tmp
         * DESCRIPTION
-        *       private -- this function produces a random hexadecimal digit, 
+        *       private -- this function produces a random hexadecimal digit,
         * for use in a call to String.replace
         *
         * PARAMETERS
         * RESULT
         *       a random hexadecimal digit
         *
+        * NOTES
+        *       Dependency Math.random() prevents this function
+        * from producing cryptographically random digits. Any function
+        * relying on this method should not be used for security purposes.
+        *
         * TODO
         *       - rewrite this function for clarity
-        *       - rewrite this function to generate UUIDs according to spec
+        *       - remove dependency on Math.random()
         *
         * SOURCE
         */
-        var tmp = function(c){
-                var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
+        var tmp = function(c) {
+                var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
                 return v.toString(16);
         };
         /*******/
         * RESULT
         *       length 36 string
         *
+        * NOTES
+        *       This function does not produce UUIDs to specification, see tmp
+        *
         * TODO
         *       - rewrite this function for clarity
+        *       - rewrite this function to generate UUIDs according to spec
         *
         * SOURCE
         */
-        fox.util.uuid = function(){
+        fox.util.uuid = function() {
                 return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, tmp);
         };
         /*******/
 *       https://bitbucket.org/bworkman/js-util
 *
 *******/
-if(typeof fox.util.cache == "undefined" || !fox.util.cache)
+if (typeof fox.util.cache == 'undefined' || !fox.util.cache)
 {
-        if(window.localStorage)
+        if (window.localStorage)
         {
                 fox.util.cache = {
                         /****f* cache/read
                         *       public -- reads a value from client cache (localStorage)
                         *
                         * PARAMETERS
-                        *       (string) key -- unique identifier used when 
+                        *       (string) key -- unique identifier used when
                         * writing the cache
                         *
                         * SIDE EFFECTS
                         * it is deleted
                         *
                         * RESULT
-                        *       null -- key was not found in cache or value 
-                        * has expired 
+                        *       null -- key was not found in cache or value
+                        * has expired
                         *
                         * SOURCE
                         */
-                        read:function(key)
+                        read: function(key)
                         {
-                                if(typeof key === "undefined" || !key)
+                                if (typeof key === 'undefined' || !key)
                                         return null;
 
                                 var parcel = JSON.parse(localStorage.getItem(key));
-                                if(!parcel || !parcel.expires)
+
+                                if (!parcel)
+                                        return parcel;
+
+                                if (!parcel.expires)
                                         return parcel.value;
 
                                 var today = new Date();
                                 var expires = new Date(parcel.expires);
-                                if(today <= expires)
+                                if (today <= expires)
                                         return parcel.value;
 
-                                erase(key);
+                                fox.util.cache.erase(key);
                                 return null;
                         },
                         /*******/
                         * PARAMETERS
                         *       (string) key - key to store the value under
                         *       (object) val - value to store in the cache
-                        *       (Number) ttl - time to live, in seconds; cache is 
+                        *       (Number) ttl - time to live, in seconds; cache is
                         * invalidated after this much time
                         *
                         * SIDE EFFECTS
                         *       returns key
                         *
                         * NOTES
-                        *       - relies on JSON.stringify; val should be 
+                        *       - relies on JSON.stringify; val should be
                         * stringable
                         *
                         * SOURCE
                         */
-                        write:function(key,val,ttl)
+                        write: function(key,val,ttl)
                         {
-                                var parcel = {value:val};
-                                if(!key) key = cf.util.uuid();
-                                if(typeof ttl === "number")
+                                var parcel = {value: val};
+                                if (!key) key = fox.util.uuid();
+                                if (typeof ttl === 'number')
                                 {
                                         var expires = new Date();
                                         expires.setTime(expires.getTime() + 1000 * ttl);
                         *
                         * SOURCE
                         */
-                        erase:function(key)
+                        erase: function(key)
                         {
-                                if(typeof key === "undefined") return;
+                                if (typeof key === 'undefined') return;
                                 localStorage.removeItem(key);
                         }
                         /*******/
                 };
         }
-}
+}
+
+(function() {
+        if (fox.util.hash) return;
+
+        /****f* hash/tmp
+        * DESCRIPTION
+        *       private -- constructs a hash from a string
+        *
+        * PARAMETERS
+        *       (string) str - string to hash
+        *
+        * SIDE EFFECTS
+        *       none
+        *
+        * NOTES
+        *       - code is the same used in the Java language
+        * core for default Object.hash()
+        *
+        * RESULT
+        *       32bit integer
+        *
+        * SOURCE
+        */
+        var tmp = function(str) {
+            var hash = 0, i, char;
+            if (str.length == 0) return hash;
+            for (i = 0, l = str.length; i < l; i++) {
+                char = str.charCodeAt(i);
+                hash = ((hash << 5) - hash) + char;
+                hash |= 0; // Convert to 32bit integer
+            }
+            return hash;
+        };
+        /*******/
+
+        /****f* fox.util/hash
+        * DESCRIPTION
+        *       public -- constructs a hash from an object
+        *
+        * PARAMETERS
+        *       (Object) obj - Object to hash
+        *
+        * SIDE EFFECTS
+        *       none
+        *
+        * RESULT
+        *       32bit integer
+        *
+        * NOTES
+        *       - depends on JSON.stringify to produce a hash
+        *
+        * SOURCE
+        */
+        fox.util.hash = function(obj) {
+                return tmp(JSON.stringify(obj));
+        };
+        /*******/
+})();

File test/index.html

                 <h3>Test Page [fox.util.js]</h3>
                 <div class="bevel">
                 <script type="text/javascript">
-                        /****h* fox.util.uuid/test
+                        /****h* uuid/test
                         * DESCRIPTION
                         *       unit test
                         *
                         *       https://bitbucket.org/bworkman/js-util
                         *
                         * TODO
-                        *       - write more comprhensive tests
+                        *       - write more comprehensive tests
                         *
                         * SOURCE
                         */
                                 }
                         }, true);
                         /*******/
+
+                        /****h* cache/test
+                        * DESCRIPTION
+                        *       unit test
+                        *
+                        * NOTES
+                        *       none
+                        *
+                        * SEE ALSO
+                        *       https://bitbucket.org/bworkman/js-util
+                        *
+                        * TODO
+                        *       - write more comprehensive tests
+                        *
+                        * SOURCE
+                        */
+                        fox.test.run({
+                                __TITLE__:"fox.util.cache",
+                                __DOC__:"verifies cache write,read,erase and expires",
+                                _init:function(){
+                                        return{
+                                                key:fox.util.uuid(),
+                                                cache:fox.util.cache,
+                                                hash:fox.util.hash
+                                        };
+                                },
+                                test1:function(){
+                                        var obj = {property:"value"};
+                                        this.cache.write(this.key, obj);
+                                        assert(this.hash(obj) == this.hash(this.cache.read(this.key)));
+                                },
+                                test2:function(){
+                                        this.cache.erase(this.key);
+                                        assert(null == this.cache.read(this.key));
+                                },
+                                test3:function(){
+                                        var obj = {property:"value"};
+
+                                        // set expiration to a minute ago
+                                        this.cache.write(this.key, obj, -60);
+                                        assert(null == this.cache.read(this.key));
+                                }
+                        }, true);
+                        /*******/
                 </script>
                 </div>
         </body>