[KSS-checkins] r50397 - in kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes: . kukit tests

reebalazs at codespeak.net reebalazs at codespeak.net
Sun Jan 6 17:19:33 CET 2008


Author: reebalazs
Date: Sun Jan  6 17:19:33 2008
New Revision: 50397

Modified:
   kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/   (props changed)
   kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/kssparser.js
   kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/resourcedata.js
   kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/tests/test_kssparser.js
Log:
Implement handling of MultoPropValue in action lines and normal parameters.
Add and adjust ecma tests.
Work in progress.

Modified: kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/kssparser.js
==============================================================================
--- kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/kssparser.js	(original)
+++ kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/kssparser.js	Sun Jan  6 17:19:33 2008
@@ -91,7 +91,8 @@
 */
 kukit.kssp.Block = kukit.tk.mkParser('block', {
     ";": 'new kukit.kssp.semicolon(this.cursor)',
-    ":": '[new kukit.kssp.colon(this.cursor), new kukit.kssp.PropValue(this.cursor)]',
+    // XXX Merging hint: next line has changed.
+    ":": '[new kukit.kssp.colon(this.cursor), new kukit.kssp.MultiPropValue(this.cursor)]',
     "}": 'this.emitAndReturn(new kukit.kssp.closeBrace(this.cursor))'
     });
 kukit.kssp.Block.prototype.process = function() {
@@ -107,9 +108,9 @@
             break;
         }
         this.expectToken(context, kukit.kssp.colon);
-        this.expectToken(context, kukit.kssp.PropValue);
+        this.expectToken(context, kukit.kssp.MultiPropValue);
         // store the wrapped prop
-        this.addDeclaration(key, context.token.value);
+        this.addDeclaration(key, context.token.values);
         if (context.nextTokenIndex == this.result.length-1) break;
         this.expectToken(context, kukit.kssp.semicolon);
     }
@@ -165,7 +166,7 @@
     return results;
 }
 
-kukit.kssp.Block.prototype.addEventDeclaration = function(key, splitkey, value) {
+kukit.kssp.Block.prototype.addEventDeclaration = function(key, splitkey, values) {
 
     // evt-<EVTNAME>-<PARAMETER>: <VALUE>
     // evt-<NAMESPACE>-<EVTNAME>-<PARAMETER>: <VALUE>
@@ -193,6 +194,11 @@
         eventKey = splitkey[3];
         eventFullName = eventNamespace + '-' + eventName;
     }
+    // preprocess values
+    var allowedReturnTypes;
+;;; allowedReturnTypes = {string: true};
+;;; kukit.E = 'event parameter [' + key + ']';
+    var value = this.preprocessValues(values, allowedReturnTypes, kukit.E).string;
 ;;; if (value.isMethod != false) {
 ;;;     kukit.E = 'Wrong value for key [' + key + '] : ';
 ;;;     kukit.E += 'value providers are not ';
@@ -206,9 +212,9 @@
         eventParameters = this.eventFullNames[eventFullName];
     }
     eventParameters[eventKey] = value.txt;
-}
+};
 
-kukit.kssp.Block.prototype.addActionDeclaration = function(key, splitkey, value) {
+kukit.kssp.Block.prototype.addActionDeclaration = function(key, splitkey, values) {
     // action-server: <ACTIONNAME>
     // action-client: <ACTIONNAME>
     // action-client: <NAMESPACE>-<ACTIONNAME>
@@ -219,12 +225,6 @@
 ;;;     kukit.E += 'action-<QUALIFIER> keys can have only one dash.';
 ;;;     this.emitError(kukit.E);
 ;;;     }
-;;; if (value.isMethod != false) {
-;;;     kukit.E = 'Wrong value for key [' + key + '] : ';
-;;;     kukit.E += 'value providers are not ';
-;;;     kukit.E += 'allowed for action-<QUALIFIER> keys.';
-;;;     this.emitError(kukit.E);
-;;;     }
     var atab = {'server': 'S', 'client': 'C', 'cancel': 'X'};
     var actionType = atab[splitkey[1]];
 ;;; if (! actionType) {
@@ -233,6 +233,23 @@
 ;;;     kukit.E += '"server" or "client" or "cancel".'; 
 ;;;     this.emitError(kukit.E);
 ;;;     }    
+    // preprocess values
+    var allowedReturnTypes;
+;;; if (actionType == 'S') {
+;;;     allowedReturnTypes = {string: true, formquery: true, url: true};
+;;; } else {
+;;;     allowedReturnTypes = {string: true, selection: true};
+;;; }
+;;; kukit.E = 'action definition [' + key + ']';
+    var valuesByReturnType = this.preprocessValues(values, allowedReturnTypes, kukit.E);
+    var value = valuesByReturnType.string;
+    //
+;;; if (value.isMethod != false) {
+;;;     kukit.E = 'Wrong value for key [' + key + '] : ';
+;;;     kukit.E += 'value providers are not ';
+;;;     kukit.E += 'allowed for action-<QUALIFIER> keys.';
+;;;     this.emitError(kukit.E);
+;;;     }
 ;;; // force value to be <ACTIONNAME> or <NAMESPACE>-<ACTIONNAME>
 ;;; var splitvalue = value.txt.split('-');
 ;;; if (splitvalue.length > 2) {
@@ -242,17 +259,28 @@
 ;;;     this.emitError(kukit.E);
 ;;;     }
     // set it
-    var action = this.actions.getOrCreateAction(value.txt);
-    if (actionType != 'X' || action.type == null) {
-        action.setType(actionType);
+    if (actionType != 'X') {
+        // any other qualifier then delete
+        var action = this.actions.getOrCreateAction(value.txt, valuesByReturnType);
+        if (action.type == null) {
+            action.setType(actionType);
+        }
     } else {
+        // action-cancel
         this.actions.deleteAction(value.txt);
     }
-}
+};
 
-kukit.kssp.Block.prototype.addActionError = function(action, key, value) {
+kukit.kssp.Block.prototype.addActionError = function(action, key, values) {
     // <ACTIONNAME>-error: <VALUE>
     // default-error: <VALUE>
+    //
+    // This can only accept string. 
+    var allowedReturnTypes;
+;;; allowedReturnTypes = {string: true};
+;;; kukit.E = 'action error parameter [' + key + ']';
+    var value = this.preprocessValues(values, allowedReturnTypes, kukit.E).string;
+;;; // It cannot be a provider, it must be a real string.
 ;;; if (value.isMethod == true) {
 ;;;     kukit.E = 'Wrong value for key [' + key + '] : ';
 ;;;     kukit.E += 'value providers are not ';
@@ -261,11 +289,11 @@
 ;;; }
     action.setError(value.txt);
     // also create the action for the error itself.
-    var err_action = this.actions.getOrCreateAction(value.txt);
+    var err_action = this.actions.getOrCreateAction(value.txt, {});
     err_action.setType('E');
-}
+};
 
-kukit.kssp.Block.prototype.addActionParameter = function(action, key, value) {
+kukit.kssp.Block.prototype.addActionParameter = function(action, key, values) {
     // <ACTIONNAME>-<KEY>: <VALUE>
     // default-<KEY>: <VALUE>
     // 
@@ -276,46 +304,52 @@
     // This will also set the value providers on the value
     // (from check).
     //
-    try {
-        // Check also sets the value provider on the value.
-        value.check();
-    } catch(e) {
-;;;     kukit.E = 'Error in value : ' + e + '.';
-        this.emitError(kukit.E);
-    }
-;;; // Check return type
-;;; // strings are currently unwrapped and will have
-;;; // returnType == undefined, so we check for that.
-;;; var returnType = value.pprovider.returnType;
-;;; if (key == 'kssSelector') {
-;;;     // for kssSelector, string or formquery expected
-;;;     if (returnType && returnType != 'string' && returnType != 'selection') {
-;;;         kukit.E = 'Expected string or a selection result and got [' + returnType;
-;;;         kukit.E += '] in the kss action parameter [kssSelector].';
+    var value;
+    if (key.substr(0, 3) == 'kss') {
+;;;     // Special selector types can have only one value
+;;;     if (values.length != 1) {
+;;;         kukit.E = 'Must have exactly one value, and got [' + values.length;
+;;;         kukit.E += '] in the kss action parameter [' + key + '].';
 ;;;         this.emitError(kukit.E);
 ;;;     }
-;;; } else if (key == 'kssSubmitForm') {
-;;;     // for kssSelector, string or formquery expected
-;;;     if (returnType && returnType != 'string' && returnType != 'formquery') {
-;;;         kukit.E = 'Expected string or a formquery result and got [' + returnType;
-;;;         kukit.E += '] in the kss action parameter [kssSubmitForm].';
-;;;         this.emitError(kukit.E);
-;;;     }
-;;; } else {
-;;;     // for all other cases, string is expected
-;;;     if (returnType && returnType != 'string') {
-;;;         kukit.E = 'Expected string and got [' + returnType;
-;;;         kukit.E += '] in the action parameter [' + key + '].';
-;;;         this.emitError(kukit.E);
+        value = values[0];
+;;;     // kss special parameter need special checking of the strings.
+;;;     // (not needed in production mode, since we have the value already)
+;;;     var allowedReturnTypes = {};
+;;;     if (key == 'kssSelector') {
+;;;         // for kssSelector, one of string or formquery expected
+;;;         allowedReturnTypes = {string: true, selection: true};
+;;;     } else if (key == 'kssSubmitForm') {
+;;;         // for kssSubmitForm string or formquery expected
+;;;         allowedReturnTypes = {string: true, formquery: true};
+;;;     } else if (key == 'kssUrl') {
+;;;         // for kssSubmitForm string or url expected
+;;;         allowedReturnTypes = {string: true, url: true};
 ;;;     }
-;;; }
-    // store the value
+;;;     // We ignore actual results here, and just check. 
+;;;     kukit.E = 'kss action parameter [' + key + ']';
+;;;     // last parameter is true: means we do _not_ require the existence
+;;;     // of a string type.
+;;;     this.preprocessValues(values, allowedReturnTypes, kukit.E, true);
+    } else {
+        // Normal selectors: can have more values
+        // check its return types
+        var allowedReturnTypes;
+;;;     allowedReturnTypes = {string: true, selection: true};
+;;;     kukit.E = 'action parameter [' + key + ']';
+        var valuesByReturnType = this.preprocessValues(values, allowedReturnTypes, kukit.E);
+        value = valuesByReturnType.string;
+        // Store the selector on the value.
+        value.selectorProvider = valuesByReturnType.selection;
+    }
+    // store the (main, string) value
     action.parms[key] = value;
 };
 
-kukit.kssp.Block.prototype.addDeclaration = function(key, value) {
-    // p.s. value is here a KssXxParm. In most cases we check and unwrap it.
-    // the keys look like this:
+kukit.kssp.Block.prototype.addDeclaration = function(key, values) {
+    // values contains a list of arguments (KssTextValue or KssMethodValue)
+    //
+    // the key looks like this:
     //
     // evt-<EVTNAME>-<KEY>: <VALUE>
     // evt-<NAMESPACE>-<EVTNAME>-<KEY>: <VALUE>
@@ -343,11 +377,13 @@
 ;;;     kukit.E += '"evt-<NAMESPACE>-<EVENTNAME>-<PARAMETER>".';
 ;;;     this.emitError(kukit.E);
 ;;; }
+    // Preprocess the values
+    //
     var name = splitkey[0];
     if (name == 'evt') {
-        this.addEventDeclaration(key, splitkey, value);
+        this.addEventDeclaration(key, splitkey, values);
     } else if (name == 'action') {
-        this.addActionDeclaration(key, splitkey, value);
+        this.addActionDeclaration(key, splitkey, values);
     } else {
         // <ACTIONNAME>-<KEY>: <VALUE>
         // <NAMESPACE>-<ACTIONNAME>-<KEY>: <VALUE>
@@ -370,15 +406,75 @@
             actionName = splitkey[0] + '-' + splitkey[1];
             actionKey = splitkey[2];
         }
-        var action = this.actions.getOrCreateAction(actionName);
+        var action = this.actions.getOrCreateAction(actionName, {});
         if (actionKey == 'error') {
-            this.addActionError(action, key, value);
+            this.addActionError(action, key, values);
         } else {
-            this.addActionParameter(action, actionKey, value);
+            this.addActionParameter(action, actionKey, values);
         }
     }
 };
 
+kukit.kssp.Block.prototype.preprocessValues = function(values, allowedReturnTypes, 
+        errInfo, noStringRequired) {
+    // allowedReturnTypes is a dict keyed by the returnType, containing true as value.
+    // key is only used for the error reporting
+    // This will also call check on all the value names!
+    // noStringRequired is set to true at the kss special parameters. All other
+    // occasions require at least a string to be present, so we check for that too.
+    var valuesByReturnType = {};
+
+    for (var i=0; i<values.length; i++) {
+        var value = values[i];
+        // Checking the value
+        // this is needed for later evaluation.
+        try {
+            // Check also sets the value provider on the value.
+            value.check();
+        } catch(e) {
+;;;         kukit.E = 'Error in value for ' + errInfo + ' : ' + e + '.';
+            this.emitError(kukit.E);
+        }
+        // XXX text values are not wrapped. So we need to check for the
+        // pprovider....
+        var returnType = (typeof(value.pprovider) != 'undefined') && value.pprovider.returnType;
+        //for(var xx in value) {print (xx, value[xx]);}
+        // Default return type is "string".
+        if (! returnType) {
+            returnType = 'string';
+        }
+;;;     // Check if return type is allowed.
+;;;     if (! allowedReturnTypes[returnType]){
+;;;         kukit.E = 'Provider result type [' + returnType;
+;;;         kukit.E += '] not allowed in the ' + errInfo +  '.';
+;;;         this.emitError(kukit.E);
+;;;     }
+;;;     // Check duplicate type. Only one provider is allowed
+;;;     // from each return type, ie. maximum one string,
+;;;     // one selector, etc.
+;;;     if (typeof(valuesByReturnType[returnType]) != 'undefined') {
+;;;         if (returnType == 'string') {
+;;;             // Give a more sensible message for strings.
+;;;             kukit.E = 'Only one string or one value provider with result type ';
+;;;             kukit.E += '[string] is allowed in the ' + errInfo +  '.';
+;;;         } else {
+;;;             kukit.E = 'Only one provider with result type [' + returnType;
+;;;             kukit.E += '] is allowed in the ' + errInfo +  '.';
+;;;         }
+;;;         this.emitError(kukit.E);
+;;;     }
+        // store it
+        valuesByReturnType[returnType] = value;
+    }
+;;; // Check we have at least a string type. (unless asked otherwise)
+;;; if (! noStringRequired && typeof(valuesByReturnType.string) == 'undefined') {
+;;;     kukit.E = 'One string or one value provider with the result type [string] ';
+;;;     kukit.E += 'is needed in the ' + errInfo +  '.';
+;;;     this.emitError(kukit.E);
+;;; }
+    return valuesByReturnType;
+};
+
 /*
 * class PropValue
 */
@@ -789,7 +885,7 @@
             } break;
         }
     }
-    // Now we found the token that must be <fraction> <colon> <propValue>.
+    // Now we found the token that must be <fraction> <colon> <multiPropValue>.
     tokenIndex -= 2;
     if (tokenIndex < 0
          || (this.result[tokenIndex+2].symbol !=

Modified: kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/resourcedata.js
==============================================================================
--- kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/resourcedata.js	(original)
+++ kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/resourcedata.js	Sun Jan  6 17:19:33 2008
@@ -502,13 +502,25 @@
     }
 };
 
-kukit.rd.ActionSet.prototype.getOrCreateAction = function(name) {
+kukit.rd.ActionSet.prototype.getOrCreateAction = function(name, valuesByReturnType) {
+    // kss parameters will ve set from valuesByReturnType 
     var action = this.content[name];
     if (typeof(action) == 'undefined') {
         action = new kukit.rd.Action();
         action.setName(name);
         this.content[name] = action;
     }
+    // Set other values that were given at the same line as the name.
+    // This enables individual overriding.
+    if (valuesByReturnType.selection) {
+        action.parms.kssSelector = valuesByReturnType.selection;
+    }
+    if (valuesByReturnType.formquery) {
+        action.parms.kssSubmitForm = valuesByReturnType.formquery;
+    }
+    if (valuesByReturnType.url) {
+        action.parms.kssUrl = valuesByReturnType.url;
+    }
     return action;
 };
 

Modified: kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/tests/test_kssparser.js
==============================================================================
--- kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/tests/test_kssparser.js	(original)
+++ kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/tests/test_kssparser.js	Sun Jan  6 17:19:33 2008
@@ -922,7 +922,6 @@
         // This test can only run in development mode, pass otherwise.
         if (! kukit.isDevelMode) {return;}
         //
-        var txt= "nodeAttr('id')";
         var txt= "nodeAttr(htmlid('id'))";
         var cursor = new kukit.tk.Cursor(txt);
         var parser = new kukit.kssp.PropValue(cursor, null, true);
@@ -940,7 +939,6 @@
         // This test can only run in development mode, pass otherwise.
         if (! kukit.isDevelMode) {return;}
         //
-        var txt= "nodeAttr('id')";
         var txt= "#id:click {\n"
                + "    action-client: log;\n"
                + "    log-message:   nodeAttr(htmlid('id'));\n"
@@ -948,7 +946,7 @@
         var cursor = new kukit.tk.Cursor(txt);
         this.assertParsingError(kukit.kssp.Document, cursor, null, true,
             // XXX This error message will be fixed in service-layer branch
-            'Error in value : Error: Expected string value and got [selection] in argument #[1] of provider [nodeAttr].., at row 1, column 11');
+            'Error in value for action parameter [message] : Error: Expected string value and got [selection] in argument #[1] of provider [nodeAttr].., at row 1, column 11');
     };
 
     this.testNormalProviderRejectsFormQuery = function() {
@@ -957,15 +955,11 @@
         // This test can only run in development mode, pass otherwise.
         if (! kukit.isDevelMode) {return;}
         //
-        var txt= "nodeAttr('id')";
         var txt= "nodeAttr(form('name'))";
         var cursor = new kukit.tk.Cursor(txt);
-        var parser = new kukit.kssp.PropValue(cursor, null, true);
-        var value = parser.value;
-        this.assertThrows(function() {
-            value.check();
-            },
-            Error);
+        this.assertParsingError(kukit.kssp.Document, cursor, null, true,
+            // XXX This error message will be fixed in service-layer branch
+            'Error in value for action parameter [message] : Error: Expected string value and got [selection] in argument #[1] of provider [nodeAttr].., at row 1, column 11');
     };
  
     this.testNormalProviderRejectsFormQueryFullRule = function() {
@@ -983,7 +977,7 @@
         var cursor = new kukit.tk.Cursor(txt);
         this.assertParsingError(kukit.kssp.Document, cursor, null, true,
             // XXX This error message will be fixed in service-layer branch
-            'Error in value : Error: Expected string value and got [formquery] in argument #[1] of provider [nodeAttr].., at row 1, column 11');
+            'Error in value for action parameter [message] : Error: Expected string value and got [formquery] in argument #[1] of provider [nodeAttr].., at row 1, column 11');
     };
 
     this.testNormalProviderRejectsSelector = function() {
@@ -992,7 +986,6 @@
         // This test can only run in development mode, pass otherwise.
         if (! kukit.isDevelMode) {return;}
         //
-        var txt= "nodeAttr('id')";
         var txt= "#id:click {\n"
                + "    action-client: log;\n"
                + "    log-message:   htmlid('id');\n"
@@ -1000,7 +993,7 @@
         var cursor = new kukit.tk.Cursor(txt);
         this.assertParsingError(kukit.kssp.Document, cursor, null, true,
             // XXX This error message will be fixed in service-layer branch
-            'Expected string and got [selection] in the action parameter [message]., at row 1, column 11');
+            'One string or one value provider with the result type [string] is needed in the action parameter [message]., at row 1, column 1');
     };
 
     this.testNormalProviderRejectsFormQuery = function() {
@@ -1017,7 +1010,7 @@
         var cursor = new kukit.tk.Cursor(txt);
         this.assertParsingError(kukit.kssp.Document, cursor, null, true,
             // XXX This error message will be fixed in service-layer branch
-            'Expected string and got [formquery] in the action parameter [message]., at row 1, column 11');
+            'Provider result type [formquery] not allowed in the action parameter [message]., at row 1, column 1');
     };
 
     this.testKssSelectorAcceptsSelector = function() {
@@ -1073,7 +1066,7 @@
         var cursor = new kukit.tk.Cursor(txt);
         this.assertParsingError(kukit.kssp.Document, cursor, null, true,
             // XXX This error message will be fixed in service-layer branch
-            'Expected string or a selection result and got [formquery] in the kss action parameter [kssSelector]., at row 1, column 11');
+            'Provider result type [formquery] not allowed in the kss action parameter [kssSelector]., at row 1, column 11');
     };
 
     this.testKssSubmitFormAcceptsFormQuery = function() {
@@ -1123,12 +1116,11 @@
         var cursor = new kukit.tk.Cursor(txt);
         this.assertParsingError(kukit.kssp.Document, cursor, null, true,
             // XXX This error message will be fixed in service-layer branch
-            'Expected string or a formquery result and got [selection] in the kss action parameter [kssSubmitForm]., at row 1, column 11');
+            'Provider result type [selection] not allowed in the kss action parameter [kssSubmitForm]., at row 1, column 11');
     };
 
     this.testCombinedClientAction = function() {
         // Client action accepts a list of combined providers.
-        // (it will evaluate as form(xxx), but we can't check that without a dom)
         //
         // This test can only run in development mode, pass otherwise.
         if (! kukit.isDevelMode) {return;}
@@ -1142,6 +1134,52 @@
         this.assertEquals(parser.finished, true);
     };
 
+    this.testCombinedClientActionRejectsFormQuery = function() {
+        // Client action rejects form query.
+        //
+        // This test can only run in development mode, pass otherwise.
+        if (! kukit.isDevelMode) {return;}
+        //
+        var txt= "nodeAttr('id')";
+        var txt= "#id:click {\n"
+               + "    action-client:   htmlid(id) doIt form();\n"
+               + "}\n"
+        var cursor = new kukit.tk.Cursor(txt);
+        this.assertParsingError(kukit.kssp.Document, cursor, null, true,
+            // XXX This error message will be fixed in service-layer branch
+            'Error in value for action definition [action-client] : Error: form method needs 1 arguments (formname)., at row 1, column 11');
+    };
+
+    this.testCombinedServerAction = function() {
+        // Server action accepts a list of combined providers.
+        //
+        // This test can only run in development mode, pass otherwise.
+        if (! kukit.isDevelMode) {return;}
+        //
+        var txt= "nodeAttr('id')";
+        var txt= "#id:click {\n"
+               + "    action-server:   doIt currentForm();\n"
+               + "}\n"
+        var cursor = new kukit.tk.Cursor(txt);
+        var parser = new kukit.kssp.Document(cursor, null, true);
+        this.assertEquals(parser.finished, true);
+    };
+
+    this.testCombinedServerActionRejectsSelector = function() {
+        // Server action rejects a selection provider.
+        //
+        // This test can only run in development mode, pass otherwise.
+        if (! kukit.isDevelMode) {return;}
+        //
+        var txt= "nodeAttr('id')";
+        var txt= "#id:click {\n"
+               + "    action-server:   doIt currentForm() htmlid(id);\n"
+               + "}\n"
+        var cursor = new kukit.tk.Cursor(txt);
+        this.assertParsingError(kukit.kssp.Document, cursor, null, true,
+            // XXX This error message will be fixed in service-layer branch
+            'Provider result type [selection] not allowed in the action definition [action-server]., at row 1, column 11');
+    };
 
 }; 
 


More information about the Kukit-checkins mailing list