Skip to content

Commit

Permalink
Merge 9b495d0 into 2e4071c
Browse files Browse the repository at this point in the history
  • Loading branch information
sttk committed Jan 30, 2022
2 parents 2e4071c + 9b495d0 commit 7b2659b
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 16 deletions.
35 changes: 21 additions & 14 deletions index.js
Expand Up @@ -12,13 +12,27 @@ var types = [
];

function normalize(coercer, value) {
if (typeof value === 'function') {
if (coercer === 'function') {
return value;
}
value = value.apply(this, slice(arguments, 2));
var coercers = coercer;
if (!Array.isArray(coercers)) {
coercers = [coercer];
}
return coerce(this, coercer, value);

var ctx = this;
var args = slice(arguments, 2);

// Try in order until one returns a non-undefined value
var result;
coercers.some(function (coercer) {
var val = value;
if (typeof value === 'function' && coercer !== 'function') {
val = value.apply(ctx, args);
}

result = coerce(ctx, coercer, val);
return result !== undefined;
});

return result;
}

function coerce(ctx, coercer, value) {
Expand All @@ -35,14 +49,7 @@ function coerce(ctx, coercer, value) {
return coercer.call(ctx, value);
}

// Array of coercers, try in order until one returns a non-null value
var result;
coercer.some(function (coercer) {
result = coerce(ctx, coercer, value);
return result != null;
});

return result;
throw new Error('Invalid coercer. Can only be a string or function.');
}

coerce.string = function (value) {
Expand Down
126 changes: 124 additions & 2 deletions test/index.js
Expand Up @@ -30,14 +30,127 @@ describe('normalize', function () {
done();
});

it('compares each type and the type of the value', function (done) {
it('runs coercers in array order', function (done) {
var type = ['string', 'object'];
var value = {};
var result = normalize(type, value);
expect(result).toBe('[object Object]');
done();
});

it('compares each type and the type of the value (string)', function (done) {
var type = ['number', 'string', 'object'];
var value = 'test string';
var result = normalize(type, value);
expect(result).toBe(value);
done();
});

it('compares each type and the type of the value (function)', function (done) {
var type = ['function', 'string'];
var value = function () { };
var result = normalize(type, value);
expect(result).toBe(value);
done();
});

it('handles function properly if the first condition is not satisfied', function (done) {
var type = ['string', 'function'];
var value = function () { };
var result = normalize(type, value);
expect(result).toBe(value);
done();
});

it('compares each type and the type of the value (number)', function (done) {
var type = ['string', 'number'];
var value = 123;
var result = normalize(type, value);
expect(result).toBe(value);
done();
});

it('compares each type and the type of the value (boolean)', function (done) {
var type = ['string', 'boolean'];
var value = true;
var result = normalize(type, value);
expect(result).toBe(value);
done();
});

it('compares each type and the type of the value (object)', function (done) {
var type = ['object', 'string'];
var value = { a: 1 };
var result = normalize(type, value);
expect(result).toBe(value);
done();
});

it('calls `toString` on object if string coercer is first', function (done) {
var type = ['string', 'object'];
var value = { a: 1 };
var result = normalize(type, value);
expect(result).toBe('[object Object]');
done();
});

it('does not fallback to `toString` if created with `Object.create(null)`', function (done) {
var type = ['string', 'object'];
var value = Object.create(null);
value.a = 1;
var result = normalize(type, value);
expect(result).toBe(value);
done();
});

it('compares each type and the type of the value (timestamp)', function (done) {
var type = ['date', 'string'];
var value = Date.now();
var result = normalize(type, value);
expect(result).toEqual(new Date(value));
done();
});

it('calls `toString` on date if string coercer is first', function (done) {
var type = ['string', 'object'];
var value = new Date();
var result = normalize(type, value);
expect(result).toBe(value.toString());
done();
});

it('returns date if object coercer is first', function (done) {
var type = ['object', 'string'];
var value = new Date();
var result = normalize(type, value);
expect(result).toBe(value);
done();
});

it('handles `null` via the object coercer', function (done) {
var type = ['string', 'object', 'number'];
var value = null;
var result = normalize(type, value);
expect(result).toBe(value);
done();
});

it('compares each type and the type of the value (undefined)', function (done) {
var type = ['string', 'undefined'];
var value = undefined;
var result = normalize(type, value);
expect(result).toBe(value);
done();
});

it('compares each type and the type of the value (symbol)', function (done) {
var type = ['string', 'symbol'];
var value = Symbol('foo');
var result = normalize(type, value);
expect(result).toBe(value);
done();
});

it('returns undefined if value does not match any type', function (done) {
var type = ['string', 'undefined'];
var value = 1;
Expand All @@ -56,6 +169,15 @@ describe('normalize', function () {
done();
});

it('throws if a coercer is not a string or function', function (done) {
var type = 123;
var value = 1;
expect(function () {
normalize(type, value);
}).toThrow('Invalid coercer. Can only be a string or function.');
done();
});

it('calls the coercer function to attempt coercion', function (done) {
var expected = 1;
var type = sinon.fake(function (value) {
Expand Down Expand Up @@ -365,7 +487,7 @@ describe('normalize.boolean', function () {

describe('normalize.function', function () {
it('accepts value if typeof function', function (done) {
var value = function () {};
var value = function () { };
var result = normalize.function(value);
expect(result).toBe(value);
done();
Expand Down

0 comments on commit 7b2659b

Please sign in to comment.