diff --git a/README.md b/README.md index 47fce1d..22c0de6 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,9 @@ The `boolean` function considers the following values to be equivalent to `true` - `'1'` (string) - `1` (number) -_Please note that if you provide a string, it will be trimmed._ +In addition to the primitive types mentioned above, boolean also supports their object wrappers `Boolean`, `String`, and `Number`. + +_Please note that if you provide a `string` or `String` object, it will be trimmed._ All other values, including `undefined` and `null` are considered to be `false`. diff --git a/lib/boolean.ts b/lib/boolean.ts index ea3d92f..2cbdc2d 100644 --- a/lib/boolean.ts +++ b/lib/boolean.ts @@ -1,17 +1,17 @@ const boolean = function (value: any): boolean { - if (typeof value === 'string') { - return [ 'true', 't', 'yes', 'y', 'on', '1' ].includes(value.trim().toLowerCase()); - } + switch (Object.prototype.toString.call(value)) { + case '[object String]': + return [ 'true', 't', 'yes', 'y', 'on', '1' ].includes(value.trim().toLowerCase()); - if (typeof value === 'number') { - return value === 1; - } + case '[object Number]': + return value.valueOf() === 1; - if (typeof value === 'boolean') { - return value; - } + case '[object Boolean]': + return value.valueOf(); - return false; + default: + return false; + } }; export { boolean }; diff --git a/package.json b/package.json index da51b12..92f66eb 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,10 @@ { "name": "Thomas Schaaf", "email": "schaaf@komola.de" + }, + { + "name": "Sebastian Mares", + "email": "camil.sebastian@mares.email" } ], "main": "build/lib/boolean.js", diff --git a/test/unit/booleanTests.ts b/test/unit/booleanTests.ts index fb29c2f..363f074 100644 --- a/test/unit/booleanTests.ts +++ b/test/unit/booleanTests.ts @@ -31,6 +31,16 @@ suite('boolean', (): void => { test('false returns false.', async (): Promise => { assert.that(boolean(false)).is.false(); }); + + test('Boolean(true) returns true.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new Boolean(true))).is.true(); + }); + + test('Boolean(false) returns false.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new Boolean(false))).is.false(); + }); }); suite('string', (): void => { @@ -129,6 +139,126 @@ suite('boolean', (): void => { test('trims whitespace.', async (): Promise => { assert.that(boolean(' true ')).is.true(); }); + + test('String("true") returns true.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new String('true'))).is.true(); + }); + + test('String("false") returns false.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new String('false'))).is.false(); + }); + + test('String("TRUE") returns true.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new String('TRUE'))).is.true(); + }); + + test('String("FALSE") returns false.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new String('FALSE'))).is.false(); + }); + + test('String("t") returns true.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new String('t'))).is.true(); + }); + + test('String("f") returns false.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new String('f'))).is.false(); + }); + + test('String("T") returns true.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new String('T'))).is.true(); + }); + + test('String("F") returns false.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new String('F'))).is.false(); + }); + + test('String("yes") returns true.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new String('yes'))).is.true(); + }); + + test('String("no") returns false.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new String('no'))).is.false(); + }); + + test('String("YES") returns true.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new String('YES'))).is.true(); + }); + + test('String("NO") returns false.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new String('NO'))).is.false(); + }); + + test('String("y") returns true.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new String('y'))).is.true(); + }); + + test('String("n") returns false.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new String('n'))).is.false(); + }); + + test('String("Y") returns true.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new String('Y'))).is.true(); + }); + + test('String("N") returns false.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new String('N'))).is.false(); + }); + + test('String("on") returns true.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new String('on'))).is.true(); + }); + + test('String("ON") returns true.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new String('ON'))).is.true(); + }); + + test('String("1") returns true.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new String('1'))).is.true(); + }); + + test('String("0") returns false.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new String('0'))).is.false(); + }); + + test('String("contains-the-letter-t") returns false.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new String('contains-the-letter-t'))).is.false(); + }); + + test('String("contains-the-word-yes") returns false.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new String('noyesno'))).is.false(); + }); + + test('arbitrary string object wrapper string returns false.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new String('123'))).is.false(); + }); + + test('trims whitespace in string object wrapper.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new String(' true '))).is.true(); + }); }); suite('number', (): void => { @@ -143,5 +273,20 @@ suite('boolean', (): void => { test('123 returns false.', async (): Promise => { assert.that(boolean(123)).is.false(); }); + + test('Number(1) returns true.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new Number(1))).is.true(); + }); + + test('Number(0) returns false.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new Number(0))).is.false(); + }); + + test('Number(123) returns false.', async (): Promise => { + // eslint-disable-next-line no-new-wrappers, unicorn/new-for-builtins + assert.that(boolean(new Number(123))).is.false(); + }); }); });