[Dojo-checkins] kzyp - r17672 - in dojox/trunk: json lang lang/tests

dojo-checkins-admin at dojotoolkit.org dojo-checkins-admin at dojotoolkit.org
Mon Jun 1 23:58:32 EDT 2009


Author: kzyp
Date: Mon Jun  1 20:58:29 2009
New Revision: 17672

Modified:
   dojox/trunk/json/schema.js
   dojox/trunk/lang/tests/typed.js
   dojox/trunk/lang/typed.js
Log:
Fixes property changes check in JSON Schema for class instances
Allows typed to work standalone
Changes typed checking to use typeCheckAllClasses as a Dojo configuration
Auto resets the class name after adding type checking

Modified: dojox/trunk/json/schema.js
==============================================================================
--- dojox/trunk/json/schema.js	(original)
+++ dojox/trunk/json/schema.js	Mon Jun  1 20:58:29 2009
@@ -21,7 +21,7 @@
 	//
 	return this._validate(instance,schema,false);
 };
-dojox.json.schema.checkPropertyChange = function(/*Any*/value,/*Object*/schema){
+dojox.json.schema.checkPropertyChange = function(/*Any*/value,/*Object*/schema, /*String*/ property){
 	// summary:
 	// 		The checkPropertyChange method will check to see if an value can legally be in property with the given schema
 	// 		This is slightly different than the validate method in that it will fail if the schema is readonly and it will
@@ -35,7 +35,7 @@
 	// return: 
 	// 		see dojox.validate.jsonSchema.validate
 	//
-	return this._validate(value,schema,true);
+	return this._validate(value,schema, property || "property");
 };
 dojox.json.schema.mustBeValid = function(result){
 	//	summary:
@@ -58,7 +58,7 @@
 		
 		if((typeof schema != 'object' || schema instanceof Array) && (path || typeof schema != 'function')){
 			if(typeof schema == 'function'){
-				if(!(instance instanceof schema)){
+				if(!(value instanceof schema)){
 					addError("is not an instance of the class/constructor " + schema.name);
 				}
 			}else if(schema){
@@ -208,7 +208,7 @@
 		return errors;
 	}
 	if(schema){
-		checkProp(instance,schema,'','');
+		checkProp(instance,schema,'',_changing || '');
 	}
 	if(!_changing && instance && instance.$schema){
 		checkProp(instance,instance.$schema,'','');

Modified: dojox/trunk/lang/tests/typed.js
==============================================================================
--- dojox/trunk/lang/tests/typed.js	(original)
+++ dojox/trunk/lang/tests/typed.js	Mon Jun  1 20:58:29 2009
@@ -1,8 +1,9 @@
 dojo.provide("dojox.lang.tests.typed");
-
+dojo.typeCheckAllClasses = true;
 dojo.require("dojox.lang.typed");
 (function(){
-	var TypedClass = dojox.lang.typed(
+	
+	dojox.lang.typed(
 		dojo.declare("dojox.lang.tests.TypedClass", null, {
 			constructor: function(makeDefaults){
 				if(makeDefaults){
@@ -14,6 +15,7 @@
 				return a + b;
 			}
 	}));
+	var TypedClass = dojox.lang.tests.TypedClass;
 	TypedClass.properties = {
 		aString:{type:"string"}, 
 		self: TypedClass, 
@@ -29,6 +31,9 @@
 		}
 	}
 	var hasGetters = {}.__defineGetter__;
+	if(!hasGetters){
+		console.warn("This platform does not support getters, property type checking will not be tested");
+	}
 	function mustThrow(testFunc){
 		try{
 			testFunc();
@@ -87,7 +92,6 @@
 			typedInstance.add(22,33);
 		},
 		function typedDeclares(){
-			dojox.lang.typed.typeCheckAllClasses();			
 			dojo.declare("dojox.lang.tests.AutoTypedClass", null, {
 				constructor: function(){
 					this.foo = "bar";

Modified: dojox/trunk/lang/typed.js
==============================================================================
--- dojox/trunk/lang/typed.js	(original)
+++ dojox/trunk/lang/typed.js	Mon Jun  1 20:58:29 2009
@@ -1,11 +1,36 @@
-dojo.provide("dojox.lang.typed");
-dojo.require("dojox.json.schema");
 (function(){
-	var jsonSchema = dojox.json.schema;
+	var jsonSchema, inDojo = typeof dojo != "undefined";
+	if(inDojo){
+		dojo.provide("dojox.lang.typed");
+		dojo.require("dojox.json.schema");
+		jsonSchema = dojox.json.schema;
+	}else{
+		if(typeof JSONSchema == "undefined"){
+			throw new Error("Dojo or JSON Schema library must be present");
+		}
+		jsonSchema = JSONSchema;
+	}
+	function mustBeValid(result){
+		//	summary:
+		//		This checks to ensure that the result is valid and will throw an appropriate error message if it is not
+		// result: the result returned from checkPropertyChange or validate
+		if(!result.valid){
+			var errorMessage = ""
+			var errors = result.errors;
+			for(var i = 0; i < errors.length; i++){
+				errorMessage += errors[i].property + ' ' + errors[i].message + '\n';				
+			}
+			throw new TypeError(errorMessage);
+		}	
+	}
 	var hasGetters = jsonSchema.__defineGetter__;
-	dojox.lang.typed = function(Class){
+	var typedFunction = function(Class){
 		// summary:
 		//		Adds type checking to a class, returning a new class with typing enabled
+		if(Class.__typedClass__){
+			// type checking has already been added
+			return Class; 
+		}
 		var Wrapper = function(){
 			var i, value, properties = Wrapper.properties;
 			var methods = Wrapper.methods;	
@@ -13,32 +38,40 @@
 			this.__props__ = {};
 			for(i in methods){
 				value = this[i];
-				if(value && !value.__typedMethod__){
-					// add typing checking to the method, going up the proto chain to find the right one
-					var proto = this;
-					while(!proto.hasOwnProperty(i) && proto.__proto__){
-						proto = proto.__proto__;
					}
-					(function(i){
-						var func = value;
-						(proto[i] = function(){
-							var methodDef = methods[i];
-							if(methodDef && methodDef.parameters){
-								var params = methodDef.parameters;
-								for(var j = 0; j < params.length; j++){
-									jsonSchema.mustBeValid(jsonSchema.validate(arguments[j], params[j]));					
-								}
-								if(methodDef.additionalParameters){
-									for(;j < arguments.length; j++){
-										jsonSchema.mustBeValid(jsonSchema.validate(arguments[j], methodDef.additionalParameters));
+				if(value){
+					if(!value.__typedMethod__){
+						// add typing checking to the method, going up the proto chain to find the right one
+						var proto = this;
+						while(!proto.hasOwnProperty(i) && proto.__proto__){
+							proto = proto.__proto__;
						}
+						(function(i){
+							var func = value;
+							(proto[i] = function(){
+								var methodDef = methods[i];
+								if(methodDef && methodDef.parameters){
+									var params = methodDef.parameters;
+									for(var j = 0; j < params.length; j++){
+										mustBeValid(jsonSchema.validate(arguments[j], params[j]));					
 									}
+									if(methodDef.additionalParameters){
+										for(;j < arguments.length; j++){
+											mustBeValid(jsonSchema.validate(arguments[j], methodDef.additionalParameters));
+										}
+									}
+								}
+								var returns = func.apply(this, arguments);
+								if(methodDef.returns){
+									mustBeValid(jsonSchema.validate(returns, methodDef.returns));
 								}
-							}
-							var returns = func.apply(this, arguments);
-							if(methodDef.returns){
-								jsonSchema.mustBeValid(jsonSchema.validate(returns, methodDef.returns));
-							}
-							return returns;
-						}).__typedMethod__ = true;
+								return returns;
+							}).__typedMethod__ = true;
+						})(i);
+					}
+				}else{
+					(function(i){
+						this[i] = function(){
+							throw new TypeError("The method " + i + " is defined but not implemented");
+						};
 					})(i);
 				}
 			}
@@ -55,30 +88,40 @@
 							return i in this.__props__ ? this.__props__[i] : this.__proto__[i];
 						});
 						self.__defineSetter__(i, function(value){
-							jsonSchema.mustBeValid(jsonSchema.checkPropertyChange(value, properties[i]));
+							mustBeValid(jsonSchema.checkPropertyChange(value, properties[i], i));
 							return this.__props__[i] = value;
 						});
 					})(i);
 				}
 			}
-			jsonSchema.mustBeValid(jsonSchema.validate(this, Wrapper));
+			mustBeValid(jsonSchema.validate(this, Wrapper));
 		};
 		Wrapper.prototype = Class.prototype;
-		return dojo.mixin(Wrapper, Class);
-	};
-	dojox.lang.typed.typeCheckAllClasses = function(){
-		// summary:
-		//		This will add type checking to all classes that will be declared via dojo.declare
-		//		(only ones to be declared in the future)
-		
-		// hook into all declared classes
-		var defaultDeclare = dojo.declare;
-		dojo.declare = function(name){
-			var clazz = defaultDeclare.apply(this, arguments);
-			clazz = dojox.lang.typed(clazz);
-			dojo.setObject(name, clazz);
-			return clazz;
-		};
-		dojo.mixin(dojo.declare, defaultDeclare);
+		for(var i in Class){
+			Wrapper[i] = Class[i];
+		}
+		if(Class.prototype.declaredClass && inDojo){
+			dojo.setObject(Class.prototype.declaredClass, Wrapper);
+		}
+		Wrapper.__typedClass__ = true;
+		return Wrapper;
 	};
+	if(inDojo){
+		dojox.lang.typed = typedFunction;
+		if(dojo.typeCheckAllClasses){
+			//	This will add type checking to all classes that will be declared via dojo.declare
+			//	(only ones to be declared in the future)
+			
+			// hook into all declared classes
+			var defaultDeclare = dojo.declare;
+			dojo.declare = function(name){
+				var clazz = defaultDeclare.apply(this, arguments);
+				clazz = typedFunction(clazz);
+				return clazz;
+			};
+			dojo.mixin(dojo.declare, defaultDeclare);
+		}
+	}else{
+		typed = typedFunction;
+	}
 })();


More information about the Dojo-checkins mailing list