diff --git a/README.md b/README.md index 0e8e9ca..46a8704 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,17 @@ var count = normalize('number', function(a, b) { }, 1, 2); // count === 3 +// Values one of multiple types are returned +var isEnabled = normalize(['string', 'boolean'], true); +// isEnabled === true + +// Values matching predicate are returned +var now = new Date(); +var enabledSince = normalize(function(value) { + return value.constructor === Date; +}, now); +// enabledSince === now + // Convenience methods are available var result = normalize.object({}); var result = normalize.number(1); @@ -47,15 +58,19 @@ var result = normalize.undefined(undefined); ## API -### `normalize(type, value[, ...appliedArguments])` +### `normalize(predicate, value[, ...appliedArguments])` + +Takes a predicate function `predicate` to test against `value`. Also optionally takes any extra arguments to apply to `value` if `value` is a function. + +If the result of `predicate(value)` is true, the value is returned. If false and `value` is a function, the function is called with any extra arguments supplied to `normalize`. -Takes a string of the `type` to match and a `value` to compare with `typeof`. Also optionally takes any extra arguments to apply to `value` if `value` is a function. +If `value` is neither match for the predicate or a function, `null` is returned. -If the results of `typeof value === type` is true, the value is returned. If false and `value` is a function, the function is called with any extra arguments supplied to `normalize`. +If `value` is a function and the result of calling the function does not match the predicate, `null` is returned. -If `value` is neither a type match or a function, `null` is returned. +If `predicate` is a string, the applied predicate is `typeof value === predicate`. -If `value` is a function and the result of calling the function does not match the type, `null` is returned. +If `predicate` is an array, `normalized` is called with each element in turn until one matches or none matches. #### `normalize.object(value[, ...appliedArguments])` diff --git a/index.js b/index.js index a68ed95..3561d97 100644 --- a/index.js +++ b/index.js @@ -13,7 +13,7 @@ var types = [ function normalize(type, value) { var args = Array.prototype.slice.call(arguments, 2); - var isType = typeof value === type; + var isType = conforms(type, value); var isFunction = typeof value === 'function'; if (!isType && !isFunction) { @@ -33,6 +33,18 @@ function normalize(type, value) { return result; } +function conforms(type, value) { + if (typeof type === 'string') { + return typeof value === type; + } + if (typeof type === 'function') { + return !!type(value); + } + return type.some(function(type) { + return conforms(type, value); + }); +} + // Add methods for each type types.forEach(function(type) { normalize[type] = normalize.bind(null, type); diff --git a/package.json b/package.json index 93cbfc3..83755a2 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "lint": "eslint . && jscs index.js test/", "pretest": "npm run lint", "test": "mocha --async-only", - "cover": "istanbul cover _mocha --report lcovonly", + "cover": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly", "coveralls": "npm run cover && istanbul-coveralls" }, "dependencies": {}, diff --git a/test/index.js b/test/index.js index 73f8e36..c695756 100644 --- a/test/index.js +++ b/test/index.js @@ -22,6 +22,53 @@ describe('normalize', function() { done(); }); + it('supports arrays for the type parameter', function(done) { + var type = ['string']; + var value = 'test string'; + var result = normalize(type, value); + expect(result).toEqual(value); + done(); + }); + + it('compares each type and the type of the value', function(done) { + var type = ['number', 'string', 'object']; + var value = 'test string'; + var result = normalize(type, value); + expect(result).toEqual(value); + done(); + }); + + it('returns null if value does not match any type', function(done) { + var type = ['string', 'undefined']; + var value = 1; + var result = normalize(type, value); + expect(result).toEqual(null); + done(); + }); + + it('supports functions for the type parameter', function(done) { + var type = function() { + return true; + }; + var value = 1; + var result = normalize(type, value); + expect(result).toEqual(value); + done(); + }); + + it('calls the type function to check validity', function(done) { + var called = false; + var type = function() { + called = true; + return false; + }; + var value = 1; + var result = normalize(type, value); + expect(result).toEqual(null); + expect(called).toEqual(true); + done(); + }); + it('calls the value if it is a function', function(done) { var type = 'string'; var expected = 'test string';