Updated schema.

This commit is contained in:
Michael Mathews 2010-06-09 22:55:51 +01:00
parent 1bd89d7774
commit 04bc22c2fa
4 changed files with 59 additions and 27 deletions

View File

@ -87,5 +87,16 @@ jsUnity
jsUnity is Copyright (c) 2009 Ates Goral jsUnity is Copyright (c) 2009 Ates Goral
Universal JavaScript Testing Framework v0.6 http://jsunity.com/ Universal JavaScript Testing Framework v0.6 http://jsunity.com/
http://github.com/atesgoral/jsunity
Licensed under the MIT license Licensed under the MIT license
http://www.opensource.org/licenses/mit-license.php http://www.opensource.org/licenses/mit-license.php
JSONSchema Validator
--------------------
JSONSchema is copyright (c) 2007 Kris Zyp SitePen (www.sitepen.com)
Licensed under the MIT (MIT-LICENSE.txt) license.
http://github.com/kriszyp/commonjs-utils/blob/master/lib/json-schema.js
http://www.sitepen.com/blog/2010/03/02/commonjs-utilities/

View File

@ -63,7 +63,7 @@
jsdoc.parser.parseFiles(sourceFiles); jsdoc.parser.parseFiles(sourceFiles);
if (opts.validate) { if (opts.validate) {
var jsonSchema = require('sitepen/jsonSchema').JSONSchema; var jsonSchema = require('sitepen/jsonSchema');
var jsdocSchema = require('jsdoc/schema').jsdocSchema; var jsdocSchema = require('jsdoc/schema').jsdocSchema;
var validation = jsonSchema.validate(jsdoc.parser.result.toObject(), jsdocSchema); var validation = jsonSchema.validate(jsdoc.parser.result.toObject(), jsdocSchema);
print('Validation: ' + validation.toSource()); print('Validation: ' + validation.toSource());

View File

@ -19,22 +19,30 @@ jsdoc.schema.jsdocSchema = {
"name": { "name": {
"type": "string" "type": "string"
}, },
"path": {
"type": "string"
},
"memberof": { "memberof": {
"type": "string", "type": "string",
"optional": true "optional": true
}, },
"kind": { "kind": {
"type": "string" "type": "string",
"enum": ["constructor", "module", "event", "namespace", "method", "property", "function", "variable", "enum"]
}, },
"meta": {
"file": {
"type": "string"
},
"line": {
"type": "string"
}
}
} }
} }
},
"meta": {
"optional": true,
"date": {
"type": "string"
}
} }
},
"meta": {
"type": "string",
"optional": true
} }
}; };

View File

@ -14,8 +14,17 @@ empty list will be returned. A validation error will have two properties:
"message" which indicates what the error was "message" which indicates what the error was
*/ */
var JSONSchema = { // setup primitive classes to be JSON Schema types
validate : function(/*Any*/instance,/*Object*/schema) { String.type = "string";
Boolean.type = "boolean";
Number.type = "number";
exports.Integer = {type:"integer"};
Object.type = "object";
Array.type = "array";
Date.type = "string";
Date.format = "date-time";
exports.validate = function(/*Any*/instance,/*Object*/schema) {
// Summary: // Summary:
// To use the validator call JSONSchema.validate with an instance object and an optional schema object. // To use the validator call JSONSchema.validate with an instance object and an optional schema object.
// If a schema is provided, it will be used to validate. If the instance object refers to a schema (self-validating), // If a schema is provided, it will be used to validate. If the instance object refers to a schema (self-validating),
@ -28,9 +37,9 @@ var JSONSchema = {
// property: which indicates which property had the error // property: which indicates which property had the error
// message: which indicates what the error was // message: which indicates what the error was
// //
return this._validate(instance,schema,false); return validate(instance,schema,false);
}, };
checkPropertyChange : function(/*Any*/value,/*Object*/schema, /*String*/ property) { exports.checkPropertyChange = function(/*Any*/value,/*Object*/schema, /*String*/ property) {
// Summary: // Summary:
// The checkPropertyChange method will check to see if an value can legally be in property with the given schema // 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 // This is slightly different than the validate method in that it will fail if the schema is readonly and it will
@ -38,9 +47,9 @@ var JSONSchema = {
// The checkPropertyChange method will return the same object type as validate, see JSONSchema.validate for // The checkPropertyChange method will return the same object type as validate, see JSONSchema.validate for
// information. // information.
// //
return this._validate(value,schema, property || "property"); return validate(value,schema, property || "property");
}, };
_validate : function(/*Any*/instance,/*Object*/schema,/*Boolean*/ _changing) { var validate = exports._validate = function(/*Any*/instance,/*Object*/schema,/*Boolean*/ _changing) {
var errors = []; var errors = [];
// validate a value against a property definition // validate a value against a property definition
@ -51,7 +60,7 @@ var JSONSchema = {
errors.push({property:path,message:message}); errors.push({property:path,message:message});
} }
if((typeof schema != 'object' || schema instanceof Array) && (path || typeof schema != 'function')){ if((typeof schema != 'object' || schema instanceof Array) && (path || typeof schema != 'function') && !(schema && schema.type)){
if(typeof schema == 'function'){ if(typeof schema == 'function'){
if(!(value instanceof schema)){ if(!(value instanceof schema)){
addError("is not an instance of the class/constructor " + schema.name); addError("is not an instance of the class/constructor " + schema.name);
@ -98,7 +107,7 @@ var JSONSchema = {
return []; return [];
} }
if(value === undefined){ if(value === undefined){
if(!schema.optional){ if(!schema.optional && !schema.get){
addError("is missing and it is not optional"); addError("is missing and it is not optional");
} }
}else{ }else{
@ -125,8 +134,8 @@ var JSONSchema = {
if(schema.maxItems && value.length > schema.maxItems){ if(schema.maxItems && value.length > schema.maxItems){
addError("There must be a maximum of " + schema.maxItems + " in the array"); addError("There must be a maximum of " + schema.maxItems + " in the array");
} }
}else if(schema.properties){ }else if(schema.properties || schema.additionalProperties){
errors.concat(checkObj(value,schema.properties,path,schema.additionalProperties)); errors.concat(checkObj(value, schema.properties, path, schema.additionalProperties));
} }
if(schema.pattern && typeof value == 'string' && !value.match(schema.pattern)){ if(schema.pattern && typeof value == 'string' && !value.match(schema.pattern)){
addError("does not match the regex pattern " + schema.pattern); addError("does not match the regex pattern " + schema.pattern);
@ -193,7 +202,7 @@ var JSONSchema = {
errors.push({property:path,message:"the presence of the property " + i + " requires that " + requires + " also be present"}); errors.push({property:path,message:"the presence of the property " + i + " requires that " + requires + " also be present"});
} }
value = instance[i]; value = instance[i];
if(objTypeDef && typeof objTypeDef == 'object' && !(i in objTypeDef)){ if(additionalProp && (!(objTypeDef && typeof objTypeDef == 'object') || !(i in objTypeDef))){
checkProp(value,additionalProp,path,i); checkProp(value,additionalProp,path,i);
} }
if(!_changing && value && value.$schema){ if(!_changing && value && value.$schema){
@ -209,12 +218,16 @@ var JSONSchema = {
checkProp(instance,instance.$schema,'',''); checkProp(instance,instance.$schema,'','');
} }
return {valid:!errors.length,errors:errors}; return {valid:!errors.length,errors:errors};
}, };
exports.mustBeValid = function(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){
throw new TypeError(result.errors.map(function(error){return "for property " + error.property + ': ' + error.message;}).join(", \n"));
}
}
/* will add this later /* will add this later
newFromSchema : function() { newFromSchema : function() {
} }
*/ */
}
// Added
if (exports) exports.JSONSchema = JSONSchema;