Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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])`

Expand Down
14 changes: 13 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -33,6 +33,18 @@ function normalize(type, value) {
return result;
}

function conforms(type, value) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it best to support all 3 types (string, array, function) or should it just support function and the utility methods like string(), boolean(), etc can just have the predicates applied?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think multiple types is common enough and more clearly conveyed by an array than by a function (function(value) { return typeof value === "string" || typeof ...). I also like supporting the string, because if I have the type in a variable, I would prefer normalize(type, ...) to normalize[type](...).

I don't go for flexibility at all cost however I think the overhead of supporting the 3 case is quite light here.

if (typeof type === 'string') {
return typeof value === type;
}
if (typeof type === 'function') {
return !!type(value);
}
return type.some(function(type) {
Copy link
Member

@phated phated Jun 6, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need an array test around this so it doesn't throw strange errors ("some is not a function")?

Copy link
Contributor Author

@hgwood hgwood Jun 7, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some is part of ES 5.1, which Node 0.10 fully supports as far as I know. I'll check to be 100% sure.

return conforms(type, value);
});
}

// Add methods for each type
types.forEach(function(type) {
normalize[type] = normalize.bind(null, type);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weird that this would be needed, the _mocha command should be hoisted

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"coveralls": "npm run cover && istanbul-coveralls"
},
"dependencies": {},
Expand Down
47 changes: 47 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down