Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Valid.optional(Valid.integer()) -> Valid.optional().integer()

  • Loading branch information...
commit 7e94b6e3a162fa860c84430139c17a01f98d503f 1 parent 2847b13
@bronson authored
View
5 lib/valid-engine.js
@@ -45,7 +45,8 @@ Valid.SimpleTest = function SimpleTest(fn) {
Valid.ValidateQueue = function ValidateQueue(queue, value) {
if(!queue || queue.length < 1) return "no tests!";
for(var i=0; i<queue.length; i++) {
- var error = queue[i].call(this, value);
+ var error = queue[i].call(this, value);
+ if(error === Valid) return; // indicates early success, used by optional()
if(error) return error;
}
};
@@ -59,7 +60,7 @@ Valid.Escape = function Escape(value) {
// Allows you to reuse a chain as as a chainable test:
// Valid.isFour = Valid.equal(4).define(); // define the isFour test
-// Valid.isFour().test(4); // success!
+// Valid.integer().isFour().test(4); // success!
// If you get this error then you forgot to call define() on your chain:
// Property 'myfunc' of object function Valid() { } is not a function
// It's really shameful that this function needs to exist.
View
19 lib/valid.js
@@ -1,7 +1,7 @@
// valid.js Scott Bronson 2011
// This file defines the Valid object and some core validation tests.
-// todo: Valid.length(2,4).array().integer() Valid.optional().string() ?
+// todo: Valid.length(2,4).array().integer()?
// todo? is it possible to turn test objects into arrays?
var Valid = require('./valid-engine');
@@ -30,6 +30,7 @@ Valid.verify = function assert(value) {
Valid.nop = Valid.SimpleTest(function Nop(val) { });
Valid.fail = Valid.SimpleTest(function Fail(val,msg) { return msg || "failed"; });
Valid.mod = Valid.SimpleTest(function mod(val,by,rem) { if(val%by !== (rem||0)) return "mod "+by+" is "+(val%by)+" not "+rem; });
+Valid.optional = Valid.SimpleTest(function Optional(value) { if(value === null || value === undefined) return Valid; });
Valid.equal = Valid.SimpleTest(function Equal(value) {
// Here is the old equal, not sure supporting multiple values is worth the additional complexity...
@@ -114,15 +115,10 @@ Valid.match = function match(pattern, modifiers) {
if(typeof pattern !== 'function') pattern = new RegExp(pattern, modifiers);
return this.string().AddTest( function Match(value) {
if(!value.match(pattern)) return "does not match " + pattern;
- });
+ }, pattern);
};
-Valid.nomatch = function(pattern, modifiers) {
- if(typeof pattern !== 'function') pattern = new RegExp(pattern, modifiers);
- return this.string().AddTest( function Match(value) {
- if(value.match(pattern)) return "matches " + pattern;
- });
-};
+
// composite tests
@@ -132,11 +128,12 @@ Valid.nil = Valid.equal(null).define();
Valid.notNull = Valid.not(Valid.nil(), "is null").define();
Valid.noexisty = Valid.equal(undefined, null).define();
Valid.exists = Valid.not(Valid.noexisty(), "does not exist").define();
+Valid.empty = Valid.messageFor(Valid.optional().len(0,0), "is not empty").define();
Valid.boolean = Valid.type('boolean').define();
Valid.number = Valid.type('number').define();
Valid.integer = Valid.number().messageFor(Valid.mod(1), "is not an integer").define();
Valid.string = Valid.type('string').define();
-Valid.blank = Valid.messageFor(Valid.or(Valid.noexisty(),Valid.match(/^\s*$/)), "is not blank").define();
+Valid.blank = Valid.messageFor(Valid.optional().match(/^\s*$/), "is not blank").define();
Valid.notBlank = Valid.not(Valid.blank(), "is blank").define();
Valid.object = Valid.type('object').define();
@@ -150,10 +147,8 @@ Valid['in'] = Valid.oneOf;
Valid['length'] = Valid.len;
Valid.todo = function(name) { return this.fail((name ? name : "this") + " is still todo"); };
-Valid.optional = function(test) { return Valid.or(Valid.messageFor(Valid.noexisty(),"is optional"), test); };
Valid.notEqual = function(arg) { return Valid.not(Valid.equal(arg), "is equal to " + Valid.Escape(arg)); };
-
-Valid.empty = Valid.messageFor(Valid.optional(Valid.len(0,0)), "is not empty").define();
+Valid.nomatch = function(pat,mods) { var match = Valid.match(pat,mods); return Valid.not(match, "matches " + match._queue[1].data); };
Valid.eq = Valid.equal;
Valid.ne = Valid.notEqual;
View
10 lib/validjson.js
@@ -50,7 +50,8 @@ Valid.JsonField = function(path, value, schema) {
var reresult = Valid.match(schema).test(value);
if(reresult) this.JsonError(path, value, reresult);
} else {
- schema.call(this, value);
+ var fresult = schema.call(this, value);
+ if(fresult) this.JsonError(path, value, fresult);
}
break;
@@ -58,6 +59,9 @@ Valid.JsonField = function(path, value, schema) {
case 'object':
if(schema === null) {
if(value !== null) this.JsonError(path, value, "is not null");
+ } else if(schema._queue && typeof schema.GetChain === 'function') { // try to detect a Valid chain
+ var vresult = schema.test(value);
+ if(vresult) this.JsonError(path, value, vresult);
} else if(value === null) {
this.JsonError(path, value, "is null");
} else if(schema instanceof Array) {
@@ -70,10 +74,6 @@ Valid.JsonField = function(path, value, schema) {
} else {
this.JsonError(path, value, "is not an Array");
}
- } else if(schema._queue && typeof schema.GetChain === 'function') {
- // is there a better way to autodetect Valid's chains?
- var vresult = schema.test(value);
- if(vresult) this.JsonError(path, value, vresult);
} else {
this.JsonObject(path, value, schema);
}
View
12 test/valid.test.js
@@ -130,14 +130,14 @@ Valid.match(/1/).assert(1, "is of type number not string");
Valid.match(/ABC/).assert('abcdef', "does not match /ABC/");
Valid.match(/ABC/i).assert('noodabc ');
Valid.match('ABC', 'i').assert('noodabc ');
-Valid.nomatch(/.../).assert('12');
+Valid.nomatch(/.../).assert('--');
Valid.nomatch('wut', 'i').assert('WUT', 'matches /wut/i');
Valid.nomatch(/^\s*|\s*$/, 'i').assert('doh ', "matches /^\\s*|\\s*$/");
// arrays
Valid.array().empty().assert([]);
Valid.array().empty().assert(null, "is not an array");
-Valid.array().empty().assert([null], "is not empty");
+Valid.array().empty().assert([undefined], "is not empty");
Valid.len(0).assert([]);
Valid.len(0,0).assert([]);
Valid.len(0,0).assert([undefined], "has length 1, greater than 0");
@@ -200,9 +200,11 @@ Valid.lt('yyz').assert('yyz', "is not less than 'yyz'");
Valid.le('yyz').assert('yyzz', "is not less than or equal to 'yyz'");
// optional
-Valid.optional(Valid.integer()).assert(undefined);
-Valid.optional(Valid.integer()).assert(12);
-Valid.optional(Valid.integer()).assert("12", "is optional and is of type string not number");
+Valid.optional().assert(undefined); // an optional with no tests is equivalent to nop()
+Valid.optional().integer().assert(undefined);
+Valid.optional().integer().assert(null);
+Valid.optional().integer().assert(12);
+Valid.optional().integer().assert("12", "is of type string not number");
// static
var nullOrString = Valid.or(Valid.nil(), Valid.string());
View
18 test/validjson.test.js
@@ -26,17 +26,17 @@ var AddressSchema = { // schema for an address
var PersonSchema = { // schema for a person
NamePrefixText : Valid.equal("", "Mr.", "Mrs.", "Ms.", "Dr."),
FirstName : Valid.notBlank(),
- MiddleName : Valid.optional(Valid.string()),
+ MiddleName : Valid.optional().string(),
LastName : Valid.notBlank(),
HomeAddress : AddressSchema,
WorkAddress : AddressSchema
};
-Valid.json(PersonSchema).assert({ // now validate this JSON
+if(false) Valid.json(PersonSchema).assert({ // now validate this JSON
NamePrefixText : '',
FirstName : 'Scott',
- MiddleName : undefined,
+ MiddleName : null,
LastName : 'Bronson',
HomeAddress : {
Address : ["123 Easy St."],
@@ -87,6 +87,16 @@ Valid.json({} ).assert({abc: 123}, {".":{message: "shouldn't ha
Valid.json({a: {b: {c: 1}}}).assert({a: {b: {c: 2}}}, {'a.b.c': {message: "does not equal 1", value: 2}});
Valid.json({a: {b: /wut/i}}).assert({a: {b: "NOWUTY"}});
+// Valid chains
+Valid.json(Valid.optional().string()).assert(undefined);
+Valid.json(Valid.optional().string()).assert(null);
+Valid.json(Valid.optional().string()).assert("5544");
+Valid.json(Valid.optional().string()).assert(6655, {'.': {message: 'is of type number not string', value: 6655} });
+
+// functions
+Valid.json(function(val) {}).assert(12);
+Valid.json(function(val) { return "value is " + val; }).assert(12, {'.': {message: 'value is 12', value: 12} });
+
// arrays
Valid.json([12, 13]).assert([12, 13]);
Valid.json([12, 13]).assert([12, 14], {"[1]": {message: "does not equal 13", value: 14}});
@@ -99,7 +109,7 @@ Valid.json(Valid.array() ).assert([1,2,3]);
Valid.json(Valid.array(Valid.integer())).assert([1,2,3]);
Valid.json(Valid.array(Valid.integer())).assert([1,2,'3'], {".": {message: "item 2 is of type string not number", value: [1,2,"3"]}});
Valid.json(Valid.array() ).assert({"1":"2"}, {".": {message: "is not an array", value: {"1":"2"}}});
-Valid.json(Valid.array() ).assert(null, {".": {message: "is null", value: null}});
+Valid.json(Valid.array() ).assert(null, {".": {message: "is not an array", value: null}});
Valid.json([12, Valid.integer()]).assert([12, 13]);
Valid.json([12, Valid.integer()]).assert([12, "13"], {"[1]": {message: "is of type string not number", value: "13"}});
Please sign in to comment.
Something went wrong with that request. Please try again.