Author: reebalazs
Date: Tue Dec 25 12:58:12 2007
New Revision: 50071

Added:
   kukit/kukit.js/branch/ree-service-layer-and-refactoring/kukit/interfaces.js
   kukit/kukit.js/branch/ree-service-layer-and-refactoring/kukit/service.js
   
kukit/kukit.js/branch/ree-service-layer-and-refactoring/tests/test_interfaces.js
Modified:
   kukit/kukit.js/branch/ree-service-layer-and-refactoring/   (props changed)
   kukit/kukit.js/branch/ree-service-layer-and-refactoring/kukit/dom.js
   kukit/kukit.js/branch/ree-service-layer-and-refactoring/kukit/eventreg.js
   kukit/kukit.js/branch/ree-service-layer-and-refactoring/kukit/kukit.js
   kukit/kukit.js/branch/ree-service-layer-and-refactoring/tests/runner.html
   kukit/kukit.js/branch/ree-service-layer-and-refactoring/tests/runtests.js
   kukit/kukit.js/branch/ree-service-layer-and-refactoring/tests/runtests.sh
Log:
End of first changes - done before I created this repo.

Modified: kukit/kukit.js/branch/ree-service-layer-and-refactoring/kukit/dom.js
==============================================================================
--- kukit/kukit.js/branch/ree-service-layer-and-refactoring/kukit/dom.js        
(original)
+++ kukit/kukit.js/branch/ree-service-layer-and-refactoring/kukit/dom.js        
Tue Dec 25 12:58:12 2007
@@ -77,42 +77,13 @@
 ;;;    kukit.E = 'Selection error in kukit.dom.cssQuery';
         throw new Error(kukit.E);
     }
-    return _cssQuery(selector, inNodes);
+    return kukit.engine.coreinterface.cssQuery(selector, inNodes);
 };
 
 /*
- * Decide which query to use
+ * Helper for focusing
  */
 
-var _USE_BASE2 = (typeof(base2) != 'undefined');
-if (_USE_BASE2) {
-;;;kukit.log('Using cssQuery from base2.');
-    var _cssQuery = function(selector, inNodes) {
-        // global scope, always.
-        // This is very bad. However the binding makes sure that
-        // nodes once bound will never be bound again
-        // (also, noticed the following issue: cssQuery, when called
-        // on an element, does not check the element itself.)
-        var results = base2.DOM.Document.matchAll(document, selector);
-        var nodes = [];
-        for(var i = 0; i < results.length; i++) {
-            nodes.push(results.item(i));
-        }
-        return nodes;
-    };
-} else {
-;;;kukit.log('Using original cssQuery.');
-    var _cssQuery = function(selector, inNodes) {
-        // global scope, always.
-        // This is very bad. However the binding makes sure that
-        // nodes once bound will never be bound again
-        // (also, noticed the following issue: cssQuery, when called
-        // on an element, does not check the element itself.)
-        var results = cssQuery(selector);
-        return results;
-    };
-};
-
 dom.focus = function(node) {
     tagName = node.tagName.toLowerCase();
     if ((tagName == 'input') || (tagName == 'select')

Modified: 
kukit/kukit.js/branch/ree-service-layer-and-refactoring/kukit/eventreg.js
==============================================================================
--- kukit/kukit.js/branch/ree-service-layer-and-refactoring/kukit/eventreg.js   
(original)
+++ kukit/kukit.js/branch/ree-service-layer-and-refactoring/kukit/eventreg.js   
Tue Dec 25 12:58:12 2007
@@ -693,6 +693,10 @@
 
 // XXX This will need refactoring.
 /// We would only want to lookup from our registry and not the other way 
around.
+//
+// own registry means eventsets need to be registered in the instance. (klass)
+//
+//
 _OperRegistry.prototype.processBindingEvents = 
     function (binder) {
     var eventRegistry = kukit.eventsGlobalRegistry;

Added: 
kukit/kukit.js/branch/ree-service-layer-and-refactoring/kukit/interfaces.js
==============================================================================
--- (empty file)
+++ kukit/kukit.js/branch/ree-service-layer-and-refactoring/kukit/interfaces.js 
Tue Dec 25 12:58:12 2007
@@ -0,0 +1,262 @@
+
+kukit.interfaces = new function() {  /* BEGIN CLOSURE kukit.interfaces */
+
+var InterfaceDescriptor = function(name, MethodDescriptor) {
+    // A parameters are the name of the interface, and 
+    // the method descriptor class it uses.
+    //
+    this.name = name;
+    this.finalized = false;
+    this.registry = {};
+    this.klass;
+    this.MethodDescriptor = MethodDescriptor;
+
+    this.getMethodDescriptor = function(methodName) {
+        // assert prohibited names
+        if (methodName == 'Interfaces' || methodName.substr(0, 3) == 'get' || 
methodName == '_interface') {
+;;;         kukit.E = 'Method name "' + methodName + '" is prohibited, in 
interface [';
+;;;         kukit.E += this.name + ']';
+            throw new Error(kukit.E);
+        }
+        // create the descriptor on demand
+        var methodDescriptor;
+        methodDescriptor = this.registry[methodName];
+        if (typeof(methodDescriptor) == 'undefined') {
+            // Use the registry in the instance, to look up the 
MethodDescriptor class
+            // for this method name
+
+            // instantiate the descriptor
+            methodDescriptor = this.registry[methodName] = new 
this.MethodDescriptor(this, methodName);
+        }
+        return methodDescriptor;
+    };
+
+    /* Apply functions on method descriptors of the interface */
+
+    var _applyFunc = function(f, methodName, methodDescriptor, argArray, 
nextArg) {
+        var newArray = [];
+        newArray.push(methodName);
+        newArray.push(methodDescriptor);
+        for ( ;nextArg < argArray.length; nextArg++) {
+            newArray.push(argArray[nextArg]);
+        }
+        f.apply(null, newArray);
+    };
+
+    this.forEachMethod = function(f) {
+        // Execute f for the designated method.
+        // methodName and MethodDescriptor will be passed to f as parameters.
+        // Extra arguments will be passed in addition.
+        for (var methodName in this.registry) {
+            var methodDescriptor = this.registry[methodName];
+            _applyFunc(f,  methodName, methodDescriptor, arguments, 1);
+        }
+    };
+
+    this.finalize = function(klass, loader) {
+        // Check if we are finalized.        
+        if (this.finalized) {
+;;;         kukit.E = 'Attempt to finalize already finalized plugin interface 
[';
+;;;         kukit.E += this.name + ']';
+            throw new Error(kukit.E);
+        }
+        // Finalize all methods.
+        this.forEachMethod(function(methodName, methodDescriptor) {
+            // Finalize them
+            var methodFunc = methodDescriptor.finalize(loader);
+            // store the functions on the class's prototype
+            klass.prototype[methodName] = methodFunc;
+            });
+        // store myself (the interface descriptor) on the class
+        klass.prototype.interface = this;
+        // Set finalized state.
+        // We are finalized if the loader has no items to load.
+        // If there is no loader, we are finalized always.
+        this.finalized = ! loader || loader.empty();
+;;;     if (this.finalized) {
+;;;         kukit.E = 'Finalizing interface [' + this.name + ']';
+;;;         kukit.logDebug(kukit.E);
+;;;    } else {
+;;;         kukit.E = 'Postpone finalization of interface [' + this.name + 
'],';
+;;;         kukit.E = ' and request sources [', loader.getSources() + ']';
+;;;         kukit.logDebug(kukit.E);
+;;;    }
+    };
+ 
+}; /* end InterfaceDescriptor */
+
+this.Interfaces = function() {
+    
+    this.registry = {};
+
+    this.get = function(name, MethodDescriptor) {
+        // create the descriptor on demand
+        var interfaceDescriptor;
+        interfaceDescriptor = this.registry[name];
+        if (typeof(interfaceDescriptor) == 'undefined') {
+            interfaceDescriptor = this.registry[name] = new 
InterfaceDescriptor(name, MethodDescriptor);
+        } else {
+            if (interfaceDescriptor.MethodDescriptor != MethodDescriptor) {
+;;;             kukit.E = 'Interface "' + name + '" already has a different 
method descriptor specified earlier.';
+                throw new Error(kukit.E);
+            }
+        }
+        return interfaceDescriptor;
+    };
+
+}; /* end Interfaces */
+
+/*
+ * KSS service layer registry
+ */
+
+this.ServiceMethodDescriptor = function(iface, methodName) {
+
+    this.iface = iface;
+    this.methodName = methodName;
+    this.registry = {};
+    this.preferredProviders = null;
+
+    this.define = function(preferredProviders, checker, fallbackProvider) {
+        if (this.preferredProviders) {
+;;;         kukit.E = 'Attempt to double define method [';
+;;;         kukit.E += this.methodName + '] on interface [';
+;;;         kukit.E += this.iface.name + ']';
+            throw new Error(kukit.E);
+        };
+        this.preferredProviders = preferredProviders;
+        this.checker = checker;
+        this.fallbackProvider = fallbackProvider;
+    };
+
+    this.provide = function(providerName, providerVersion, getter) {
+        if (this.iface.finalized) {
+;;;         kukit.E = 'Attempt to provide implementation to method [';
+;;;         kukit.E += this.methodName + '] on already finalized interface [';
+;;;         kukit.E += this.iface.name + ']';
+            throw new Error(kukit.E);
+        } else if (typeof(this.registry[providerName]) != 'undefined') {
+;;;         kukit.E = 'Double registration by [' + providerName + '][';
+;;;         kukit.E += providerVersion; 
+;;;         kukit.E += '] of method [' + this.methodName;
+;;;         kukit.E += '] in interface [' + this.iface.name + ']';
+            throw new Error(kukit.E);
+        }
+        this.registry[providerName] = {
+            methodName: this.methodName,
+            providerName: providerName,
+            providerVersion: providerVersion,
+            getter: getter};
+    };
+
+    this.finalize = function(loader) {
+        var func;
+        if (! this.preferredProviders) {
+;;;         kukit.E = 'Undefined method [';
+;;;         kukit.E += this.methodName + '] on interface [';
+;;;         kukit.E += this.iface.name + '], ';
+;;;         kukit.E += 'but the following were provided:';
+;;;         kukit.E += this.registry + ']';
+            throw new Error(kukit.E);
+        }
+        // loop through all preferred providers
+        for (var i = 0; i < this.preferredProviders.length; i++) {
+            var item = this.registry[this.preferredProviders[i]];
+            // Did we have an item?
+            if (typeof(item) == 'undefined') {
+                continue;
+            }
+            // Execute the item's getter
+            func = item.getter();
+            // Did it return the function?
+            if (func) {
+                // found it
+                break;
+            }
+            // if not, we continue with the next best choice.
+        }
+        if (! func) {
+            if (typeof(loader) != 'undefined') {
+                // We have a loading method. Let's add our needs.
+                loader.add(this.fallbackProvider);
+                // ... and simply go on.
+            } else {
+                // We raise an error.
+;;;             kukit.E = 'Could not finalize method [';
+;;;             kukit.E += this.methodName + '] on interface [';
+;;;             kukit.E += this.iface.name + '], because no provider found ';
+;;;             kukit.E += 'of the following preferences: [';
+;;;             kukit.E += this.preferredProviders + ']';
+                throw new Error(kukit.E);
+            }
+        }
+        if (this.checker) {
+            // if there is a checker, merge them together
+            var self = this;
+            return function() {
+                self.checker(null, arguments);
+                return func(null, arguments);
+            };
+        } else {
+            // else, just store the function
+            return func;
+        }
+    };
+
+}; /* end ServiceMethodDescriptor */
+
+
+/*
+ * KSS plugin registry
+ */
+
+this.PluginMethodDescriptor = function(iface, methodName) {
+
+    this.iface = iface;
+    this.methodName = methodName;
+    this.config = null;
+
+    this.register = function(config) {
+        if (this.config != null) {
+;;;         kukit.E = 'Double registration by [' + providerName + '][';
+;;;         kukit.E += providerVersion; 
+;;;         kukit.E += '] of method [' + this.methodName;
+;;;         kukit.E += '] in plugin interface [' + this.iface.name + ']';
+            throw new Error(kukit.E);
+        }
+        this.config = config;
+    };
+
+    this.finalize = function(loader) {
+        if (! this.config) {
+            return;
+        }
+        // Just return the registered value.
+        return this.config;
+    };
+
+}; /* end PluginMethodDescriptor */
+
+
+/*
+ * Instantiation
+ */
+
+// create singleton for interfaces
+var _interfaces = new this.Interfaces();
+
+// The following methods can acquire a given interface
+
+// wrap the function, since there are no bound methods in JS
+this.get = function(name, MethodDescriptor) {
+    return _interfaces.get(name, MethodDescriptor);
+};
+this.getService = function(name) {
+    return _interfaces.get(name, this.ServiceMethodDescriptor);
+};
+this.getPlugin = function(name) {
+    return _interfaces.get(name, this.PluginMethodDescriptor);
+};
+
+
+}(); /* END CLOSURE kukit.interfaces */

Modified: kukit/kukit.js/branch/ree-service-layer-and-refactoring/kukit/kukit.js
==============================================================================
--- kukit/kukit.js/branch/ree-service-layer-and-refactoring/kukit/kukit.js      
(original)
+++ kukit/kukit.js/branch/ree-service-layer-and-refactoring/kukit/kukit.js      
Tue Dec 25 12:58:12 2007
@@ -243,6 +243,12 @@
 ;;;     kukit.log('[initializeRules] is called twice.');
         return;
     }
+;;; kukit.log('Initializing interfaces.');
+    // We finalize the core interface.
+    var klass = function() {};
+    kukit.interfaces.get('core').finalize(klass);
+    var obj = new klass();
+    this.coreinterface = obj
 ;;; kukit.log('Initializing kinetic stylesheets.');
     // Succesful initialization. At the moment the engine is kept
     // as a global variable, but this needs refinement in the future.

Added: kukit/kukit.js/branch/ree-service-layer-and-refactoring/kukit/service.js
==============================================================================
--- (empty file)
+++ kukit/kukit.js/branch/ree-service-layer-and-refactoring/kukit/service.js    
Tue Dec 25 12:58:12 2007
@@ -0,0 +1,63 @@
+
+
+
+new function() {  // BEGIN CLOSURE service
+
+    var core = kukit.interfaces.getService('core');
+    core.getMethodDescriptor('cssQuery').define(['base2', 'cssQuery'], 
+            // a parameter checker common for each implementation
+            function(selector, inNodes) {
+                // to eliminate possible errors
+                if (typeof(inNodes) != 'undefined' && inNodes == null) {
+;;;                 kukit.E = 'Selection error in kukit.dom.cssQuery';
+                    throw new Error(kukit.E);
+                }
+            });
+
+    // providers are also here now
+
+    core.getMethodDescriptor('cssQuery').provide('cssQuery', '1.1', 
+            function() {
+                // Detect if cssQuery is present
+                //
+                if (typeof(cssQuery) == 'undefined') {
+                    return;
+                }
+                // return the method plug
+;;;             kukit.log('Using original cssQuery.');
+                return function(selector, inNodes) {
+                    // global scope, always.
+                    // This is very bad. However the binding makes sure that
+                    // nodes once bound will never be bound again
+                    // (also, noticed the following issue: cssQuery, when 
called
+                    // on an element, does not check the element itself.)
+                    var results = cssQuery(selector);
+                    return results;
+                };
+            });
+
+
+    core.getMethodDescriptor('cssQuery').provide('base2', '1.1', 
+            function() {
+                // Detect if base2 is present
+                //
+                if (typeof(base2) == 'undefined') {
+                    return;
+                }
+                // return the method plug
+;;;             kukit.log('Using cssQuery from base2.');
+                return function(selector, inNodes) {
+                    // global scope, always.
+                    // This is very bad. However the binding makes sure that
+                    // nodes once bound will never be bound again
+                    var results = base2.DOM.Document.matchAll(document, 
selector);
+                    var nodes = [];
+                    for(var i = 0; i < results.length; i++) {
+                        nodes.push(results.item(i));
+                    }
+                    return nodes;
+                };
+            });
+
+
+}()         // END CLOSURE service

Modified: 
kukit/kukit.js/branch/ree-service-layer-and-refactoring/tests/runner.html
==============================================================================
--- kukit/kukit.js/branch/ree-service-layer-and-refactoring/tests/runner.html   
(original)
+++ kukit/kukit.js/branch/ree-service-layer-and-refactoring/tests/runner.html   
Tue Dec 25 12:58:12 2007
@@ -48,6 +48,8 @@
                 src="../kukit/utils.js">
         </script>
 
+        <script type="text/javascript" src="../kukit/interfaces.js"
+            tal:replace="nothing"> </script>
         <script type="text/javascript" src="../kukit/errors.js"
             tal:replace="nothing"> </script>
         <script type="text/javascript" src="../kukit/oper.js"
@@ -78,12 +80,15 @@
             tal:replace="nothing"> </script>
         <script type="text/javascript" src="../kukit/forms.js"
             tal:replace="nothing"> </script>
+        <script type="text/javascript" src="../kukit/service.js"
+            tal:replace="nothing"> </script>
         <script type="text/javascript" src="../kukit/plugin.js"
             tal:replace="nothing"> </script>
         <script type="text/javascript" src="test_utils.js"> </script>
         <script type="text/javascript" src="test_requestmanager.js"> </script>
         <script type="text/javascript" src="test_tokenizer.js"> </script>
         <script type="text/javascript" src="test_kssparser.js"> </script>
+        <script type="text/javascript" src="test_interfaces.js"> </script>
       </head>
 
 <body>

Modified: 
kukit/kukit.js/branch/ree-service-layer-and-refactoring/tests/runtests.js
==============================================================================
--- kukit/kukit.js/branch/ree-service-layer-and-refactoring/tests/runtests.js   
(original)
+++ kukit/kukit.js/branch/ree-service-layer-and-refactoring/tests/runtests.js   
Tue Dec 25 12:58:12 2007
@@ -23,6 +23,9 @@
     testsuite.registerTest(kukit.KssParserTestCase);
     testsuite.registerTest(kukit.KssParserSelectorsTestCase);
     testsuite.registerTest(kukit.KssParserSelectorTestCase);
+    testsuite.registerTest(kukit.InterfacesTestCase);
+    testsuite.registerTest(kukit.ServiceInterfacesTestCase);
+    testsuite.registerTest(kukit.PluginInterfacesTestCase);
     testsuite.runSuite();
 };
 

Modified: 
kukit/kukit.js/branch/ree-service-layer-and-refactoring/tests/runtests.sh
==============================================================================
--- kukit/kukit.js/branch/ree-service-layer-and-refactoring/tests/runtests.sh   
(original)
+++ kukit/kukit.js/branch/ree-service-layer-and-refactoring/tests/runtests.sh   
Tue Dec 25 12:58:12 2007
@@ -5,6 +5,7 @@
     -f ../3rd_party/base2-dom-fp.js \
     -f ../kukit/kukit.js \
     -f ../kukit/utils.js \
+    -f ../kukit/interfaces.js \
     -f ../kukit/errors.js \
     -f ../kukit/oper.js \
     -f ../kukit/tokenizer.js \
@@ -20,9 +21,11 @@
     -f ../kukit/commandprocessor.js \
     -f ../kukit/selectorreg.js \
     -f ../kukit/forms.js \
+    -f ../kukit/service.js \
     -f ../kukit/plugin.js \
     -f test_utils.js \
     -f test_requestmanager.js \
     -f test_tokenizer.js \
     -f test_kssparser.js \
+    -f test_interfaces.js \
     runtests.js

Added: 
kukit/kukit.js/branch/ree-service-layer-and-refactoring/tests/test_interfaces.js
==============================================================================
--- (empty file)
+++ 
kukit/kukit.js/branch/ree-service-layer-and-refactoring/tests/test_interfaces.js
    Tue Dec 25 12:58:12 2007
@@ -0,0 +1,465 @@
+/*
+* Copyright (c) 2005-2007
+* Authors: KSS Project Contributors (see doc/CREDITS.txt)
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as published
+* by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+* 02111-1307, USA.
+*/
+
+if (typeof(kukit) == "undefined") {
+    var kukit = {};
+}
+
+kukit.InterfacesTestCaseBase = function() {
+    this.setUp = function() {
+        // work with our own object, not interfering
+        // kukit.interfaces
+        this.interfaces = new kukit.interfaces.Interfaces();
+    };
+}; /* end InterfacesTestCase */
+kukit.InterfacesTestCaseBase.prototype = new kukit.UtilsTestCaseBase();
+
+kukit.InterfacesTestCase = function() {
+    /*
+     * Plugin interfaces
+     */
+   
+   var called = [];
+
+   var MethodDescriptor = function(iface, methodName) {
+        this.iface = iface;
+        this.methodName = methodName;
+        this.doThis = function() {
+            called.push("doThis");
+        }
+        this.doThat = function() {
+            called.push("doThat");
+        }
+        this.finalize = function(loader) {
+            var signature = "FUNC " + this.methodName;
+            called.push(signature);
+            return signature;
+        }
+    };
+
+    this.testInterfaces = function() {
+        // We have a class, called C.
+        var C = function() {};
+        // We can create a simple method descriptor for an interface we want.
+        // The method descriptor is managing the method's registration state 
+        called = [];
+        // Let's create a TestDummy interface.
+        var iface = this.interfaces.get('dummytest', MethodDescriptor);
+        // Let's get two methods
+        iface.getMethodDescriptor('fooMethod').doThis()
+        iface.getMethodDescriptor('barMethod').doThat()
+        // Check
+        this.assertListEquals(called, ['doThis', 'doThat']);
+        called = [];
+        // Ok. Now get the descriptors again...
+        iface.getMethodDescriptor('fooMethod').doThis()
+        iface.getMethodDescriptor('barMethod').doThat()
+        // Check
+        this.assertListEquals(called, ['doThis', 'doThat']);
+        called = [];
+        //
+        // Now let's iterate on all instantiated methods:
+        iface.forEachMethod(function(methodName, methodDescriptor) {
+            methodDescriptor.doThis()
+        });
+        // Check
+        this.assertListEquals(called, ['doThis', 'doThis']);
+        called = [];
+    };
+
+    this.testFinalizeInterfaces = function() {
+        // We have a class, called C.
+        var C = function() {};
+        // We can create a simple method descriptor for an interface we want.
+        // The method descriptor is managing the method's registration state 
+        called = [];
+        // Let's create a TestDummy interface.
+        var iface = this.interfaces.get('dummytest', MethodDescriptor);
+        // Let's get two methods
+        iface.getMethodDescriptor('fooMethod').doThis()
+        iface.getMethodDescriptor('barMethod').doThat()
+        // Check
+        this.assertListEquals(called, ['doThis', 'doThat']);
+        called = [];
+        //
+        // At this point we are also ready to finalize the interface.
+        iface.finalize(C)
+        // This calls finalize on all method descriptors.
+        this.assertListEquals(called, ['FUNC fooMethod', 'FUNC barMethod']);
+        called = [];
+        // At the same time it also set up these on the class prototype.
+        var o = new C();
+        this.assert(o.fooMethod, 'FUNC fooMethod');
+        this.assert(o.barMethod, 'FUNC barMethod');
+        // ... so if the descriptor sets methodFunc on the 
+    };
+
+    this.testTwoInterfaces = function() {
+       // Let's have a second method descriptor class
+       var MethodDescriptor2 = function(iface, methodName) {
+            this.iface = iface;
+            this.methodName = methodName;
+            this.finalize = function(loader) {
+                var signature = "IFACE2 " + this.methodName;
+                return signature;
+            }
+        };
+        // We have a class, called C.
+        var C = function() {};
+        // Let's create a TestDummy interface.
+        var iface = this.interfaces.get('dummytest', MethodDescriptor);
+        // We can get the same interface again...
+        this.interfaces.get('dummytest', MethodDescriptor);
+        // however not with a different descriptor class!
+        var self = this;
+        this.assertThrows(function() {
+            self.interfaces.get('dummytest', MethodDescriptor2);
+            },
+            Error);
+        //
+        // On the other hand setting up a second interface is no problem.
+        var iface2 = this.interfaces.get('dummytest2', MethodDescriptor2);
+    };
+
+}; /* end InterfacesTestCase */
+kukit.InterfacesTestCase.prototype = new kukit.InterfacesTestCaseBase();
+
+
+kukit.ServiceInterfacesTestCase = function() {
+    this.name = 'kukit.ServiceInterfacesTestCase';
+    /*
+     * Service interfaces
+     */
+
+    this.testServiceInterfaces = function() {
+        // We have a class, called C.
+        var C = function() {};
+        // Let's create a TestDummy interface.
+        var iface = this.interfaces.get('dummytest', 
kukit.interfaces.ServiceMethodDescriptor);
+        // Define four methods, thie defines their necessity and preferred 
providers
+        iface.getMethodDescriptor('first').define(['corelib', 'extralib']);
+        iface.getMethodDescriptor('second').define(['extralib', 'corelib']);
+        iface.getMethodDescriptor('third').define(['corelib']);
+        iface.getMethodDescriptor('fourth').define(['extralib']);
+        //
+        // somewhere else, provider "core" provides the methods:
+        iface.getMethodDescriptor('first').provide('corelib', '1.1', 
+                function() {return function() {return 'first/core';}});
+        iface.getMethodDescriptor('second').provide('corelib', '1.1', 
+                function() {return function() {return 'second/core';}});
+        iface.getMethodDescriptor('third').provide('corelib', '1.1', 
+                function() {return function() {return 'third/core';}});
+        //
+        // somewhere else, provider "extras" provides the methods:
+        iface.getMethodDescriptor('first').provide('extralib', '12.4', 
+                function() {return function() {return 'first/extra';}});
+        iface.getMethodDescriptor('second').provide('extralib', '12.4', 
+                function() {return function() {return 'second/extra';}});
+        iface.getMethodDescriptor('fourth').provide('extralib', '12.4', 
+                function() {return function() {return 'fourth/extra';}});
+        //
+        // Now finalize it.
+        iface.finalize(C);
+        // Create an instance...
+        var o = new C();
+        // We can call the methods on it,
+        this.assert(o.first(), 'first/core');
+        this.assert(o.second(), 'second/extra');
+        this.assert(o.third(), 'third/core');
+        this.assert(o.fourth(), 'fourth/extra');
+    };
+
+    this.testChecker = function() {
+        // Test with a checker function.
+        // We have a class, called C.
+        var C = function() {};
+        // Let's create a TestDummy interface.
+        var iface = this.interfaces.get('dummytest', 
kukit.interfaces.ServiceMethodDescriptor);
+        // and a counter for the checker
+        var checker_counter = 0;
+        // Define three methods
+        iface.getMethodDescriptor('first').define(['corelib', 'extralib'],
+                function() {checker_counter++;});
+        //
+        // somewhere else, core provides the methods:
+        iface.getMethodDescriptor('first').provide('corelib', '1.1', 
+                function() {return function() {return 'first/core';}});
+        //
+        // somewhere else, extras provides the methods:
+        iface.getMethodDescriptor('first').provide('extralib', '12.4', 
+                function() {return function() {return 'first/extra';}});
+        //
+        // Now finalize it.
+        iface.finalize(C);
+        var o = new C();
+        // call it
+        this.assert(o.first(), 'first/core');
+        // Check that the checker has been called.
+        this.assert(checker_counter, 1);
+    };
+
+    this.testReverseOrder = function() {
+        // Method creation also works in reverse order:
+        // a plugin first provides a method that another plugin later defines.
+        // We have a class, called C.
+        var C = function() {};
+        var iface = this.interfaces.get('dummytest', 
kukit.interfaces.ServiceMethodDescriptor);
+        // Provide the method first
+        iface.getMethodDescriptor('first').provide('corelib', '1.1', 
+                function() {return function() {return 'first/core';}});
+        // Define the method later
+        iface.getMethodDescriptor('first').define(['corelib', 'extralib']);
+        // Now finalize it.
+        var C = function() {};
+        iface.finalize(C);
+        // Create an instance...
+        var o = new C();
+        // We can call the methods on it,
+        this.assert(o.first(), 'first/core');
+    };
+
+    this.testFinalizeTwice = function() {
+        // An interface can only be finalized once.
+        var C = function() {};
+        var iface = this.interfaces.get('dummytest', 
kukit.interfaces.ServiceMethodDescriptor);
+        // Provide the method first
+        iface.getMethodDescriptor('first').provide('corelib', '1.1', 
+                function() {return function() {return 'first/core';}});
+        // Define the method later
+        iface.getMethodDescriptor('first').define(['corelib', 'extralib']);
+        // Now finalize it.
+        var C = function() {};
+        iface.finalize(C);
+        // Finalize it again.
+        this.assertThrows(function() {
+            iface.finalize(C);
+            },
+            Error);
+    };
+
+    this.testNotDefined = function() {
+        // A method is provided but not defined.
+        var C = function() {};
+        var iface = this.interfaces.get('dummytest', 
kukit.interfaces.ServiceMethodDescriptor);
+        // Provide the method first
+        iface.getMethodDescriptor('first').provide('corelib', '1.1', 
+                function() {return function() {return 'first/core';}});
+        // Now finalize it.
+        var C = function() {};
+        this.assertThrows(function() {
+            iface.finalize(C);
+            },
+            Error)
+    };
+
+    this.testDoubleProvided = function() {
+        // A method cannot be provided twice by the same provider.
+        var C = function() {};
+        var iface = this.interfaces.get('dummytest', 
kukit.interfaces.ServiceMethodDescriptor);
+        // Provide the method first
+        iface.getMethodDescriptor('first').provide('corelib', '1.1', 
+                function() {return function() {return 'first/core';}});
+        // Now provide it for the second time.
+        this.assertThrows(function() {
+            iface.getMethodDescriptor('first').provide('corelib', '1.1', 
+                    function() {return function() {return 'first/core';}})
+            },
+            Error);
+    };
+
+    this.testDoubleDefined = function() {
+        // A method can only be defined once.
+        var C = function() {};
+        var iface = this.interfaces.get('dummytest', 
kukit.interfaces.ServiceMethodDescriptor);
+        // Define the method first
+        iface.getMethodDescriptor('first').define(['corelib', 'extralib']);
+        // define it again.
+        this.assertThrows(function() {
+            iface.getMethodDescriptor('first').defineMethod(['corelib', 
'extralib'])
+            },
+            Error);
+    };
+
+    this.testNotProvided = function() {
+        // No preferred provider can be found for a method.
+        var C = function() {};
+        var iface = this.interfaces.get('dummytest', 
kukit.interfaces.ServiceMethodDescriptor);
+        // Define the method first
+        iface.getMethodDescriptor('first').define(['corelib', 'extralib']);
+        // Someone provides the method, but it's not good.
+        iface.getMethodDescriptor('first').provide('craplib', '1.1', 
+                function() {return function() {return 'first/crap';}});
+        // Now finalize it.
+        var C = function() {};
+        this.assertThrows(function() {
+            iface.finalize(C);
+            },
+            Error);
+    };
+
+    this.testWithLoader = function() {
+        // If no preferred providers are found, loaders will
+        // call up.
+        // Make a simple loader
+        var loader = new function() {
+            this.loaded = [];
+            this.add = function(src) {
+                this.loaded.push(src);
+            };
+            this.empty = function(src) {
+                return ! this.loaded;
+            };
+            this.getSources = function(src) {
+                return this.loaded;
+            };
+        }();
+        // Now, for the interface part
+        var C = function() {};
+        var iface = this.interfaces.get('dummytest', 
kukit.interfaces.ServiceMethodDescriptor);
+        // Define the method with loader and fallback script
+        iface.getMethodDescriptor('first').define(['corelib', 'extralib'], 
null, '++resource++one');
+        iface.getMethodDescriptor('second').define(['corelib', 'extralib'], 
null, '++resource++two');
+        iface.getMethodDescriptor('third').define(['corelib', 'extralib'], 
null, '++resource++thr');
+        // Someone provides the method, but it's not good.
+        iface.getMethodDescriptor('first').provide('craplib', '1.1', 
+                function() {return function() {return 'first/crap';}});
+        // Third will be satisfied.
+        iface.getMethodDescriptor('third').provide('extralib', '1.1', 
+                function() {return function() {return 'third/extra';}});
+        // Now finalize it. It goes without error.
+        iface.finalize(C, loader);
+        // We see the contents of the loader. Third is not in there.
+        this.assertListEquals(loader.loaded, ['++resource++one', 
'++resource++two'], 'Loaded contents differs.');
+        // Third is actually working.
+        var o = new C();
+        this.assert(o.third(), 'third/extra');
+        // First and second are undefined.
+        this.assert(typeof(o.first), 'undefined');
+        this.assert(typeof(o.second), 'undefined');
+        // Now the loader can go to load the needed files...
+        // then it is supposed to re-finalize with and without a loader. Check 
if this is possible:
+        iface.finalize(C, loader);
+        // If we re-finalize without a loader, and the sources are still not 
loaded,
+        // we get an error:
+        this.assertThrows(function() {
+            iface.finalize(C);
+            },
+            Error);
+    };
+
+}; /* end ServiceInterfacesTestCase */
+kukit.ServiceInterfacesTestCase.prototype = new kukit.InterfacesTestCaseBase();
+
+
+kukit.PluginInterfacesTestCase = function() {
+    this.name = 'kukit.PluginInterfacesTestCase';
+    /*
+     * Plugin interfaces
+     */
+
+    var M = function() {
+        this.bind = function(oper) {};
+    };
+    this.testPluginInterfaces = function() {
+        // We have a class, called C.
+        var C = function() {};
+        // Let's create a TestDummy interface.
+        var iface = this.interfaces.get('dummyevent', 
kukit.interfaces.PluginMethodDescriptor);
+        // somewhere else, core registers the methods:
+        iface.getMethodDescriptor('click').register({
+            namespace: null,
+            name: 'click',
+            defaultMethod: null,
+            parmtypes: [
+                ['preventDefault', 'bool', true],
+                ['allowBubbling', 'bool', false]]});
+        iface.getMethodDescriptor('keydown').register({
+            namespace: null,
+            name: 'keydown',
+            defaultMethod: null,
+            parmtypes: [
+                ['preventDefault', 'bool', true],
+                ['allowBubbling', 'bool', false]]});
+        iface.getMethodDescriptor('click').registerBindIteration({
+            namespace: null,
+            names: ['click', 'timeout'],
+            iterName: 'Each',
+            binderClass: M;
+            bindMethodName: 'bind';
+        //
+        // somewhere else, extras registers the methods:
+        iface.getMethodDescriptor('timeout').register({
+            name: 'timeout',
+            defaultMethod: null,
+            parmtypes: [
+                ['millis', 'int'],
+                ['renew', 'bool', false]]});
+        // It needs a bind iterator even though it is a single
+        // group.
+        iface.getMethodDescriptor('timeout').registerBindIteration({
+            namespace: null,
+            names: ['click', 'timeout'],
+            iterName: 'each',
+            bindMethodName:
+
+        //
+        // Now finalize it.
+        iface.finalize(C);
+        // Create an instance...
+        var o = new C();
+        // We can call the methods on it,
+        this.assert(o.click.binderMethod(), 'Binding click event.');
+        this.assert(typeof(o.keydown.binderMethod()), 'undefined');
+        this.assert(typeof(o.timeout.binderMethod()), 'undefined');
+    };
+
+    this.testPluginNoDoubleReg = function() {
+        // No double registration for test plugins.
+        var C = function() {};
+        // Let's create a TestDummy interface.
+        var iface = this.interfaces.get('dummyevent', 
kukit.interfaces.PluginMethodDescriptor);
+        // somewhere else, core registers the methods:
+        iface.getMethodDescriptor('click').register({
+            name: 'click',
+            binderMethod: function() {return "Binding click event.";},
+            defaultMethod: function() {},
+            parmtypes: [
+                ['preventDefault', 'bool', true],
+                ['allowBubbling', 'bool', false]]});
+        // But another providing attempt is punished by an Error.
+        this.assertThrows(function() {
+            iface.getMethodDescriptor('click').register({
+                name: 'click',
+                binderMethod: function() {return "Binding click event.";},
+                defaultMethod: function() {},
+                parmtypes: [
+                    ['preventDefault', 'bool', true],
+                    ['allowBubbling', 'bool', false]]});
+            },
+            Error);
+    };
+
+}; /* end PluginInterfacesTestCase */
+kukit.PluginInterfacesTestCase.prototype = new kukit.InterfacesTestCaseBase();
+
+if (typeof(testcase_registry) != 'undefined') {
+    testcase_registry.registerTestCase(kukit.InterfacesTestCase, 
'kukit.InterfacesTestCase');
+    testcase_registry.registerTestCase(kukit.ServiceInterfacesTestCase, 
'kukit.ServiceInterfacesTestCase');
+    testcase_registry.registerTestCase(kukit.PluginInterfacesTestCase, 
'kukit.PluginInterfacesTestCase');
+}
_______________________________________________
Kukit-checkins mailing list
[email protected]
http://codespeak.net/mailman/listinfo/kukit-checkins

Reply via email to