diff --git a/packages/converters/src/boolean-to-number/index.test.ts b/packages/converters/src/boolean-to-number/index.test.ts index 02a66a97..243eaadf 100644 --- a/packages/converters/src/boolean-to-number/index.test.ts +++ b/packages/converters/src/boolean-to-number/index.test.ts @@ -13,15 +13,12 @@ import { describe, expect, it } from 'vitest'; import { booleanToNumber } from './'; -const testPairs: [boolean, number][] = [ - [true, 1], - [false, 0], -]; - describe('bool to number', () => { - for (const [input, result] of testPairs) { - it(`should convert ${input} to ${result}`, () => { - expect(booleanToNumber(input)).toEqual(result); - }); - } + it('should convert true to 1', () => { + expect(booleanToNumber(true)).toEqual(1); + }); + + it('should convert false to 0', () => { + expect(booleanToNumber(false)).toEqual(0); + }); }); diff --git a/packages/predicates/src/is-number/index.test.ts b/packages/predicates/src/is-number/index.test.ts index 0408e757..6405e884 100644 --- a/packages/predicates/src/is-number/index.test.ts +++ b/packages/predicates/src/is-number/index.test.ts @@ -12,152 +12,69 @@ import { expect, it, describe } from 'vitest'; import { isFiniteNumber, isFiniteNumeric, isNumber, isNumeric } from './'; -import { - floatingPointPairs, - floatingPointStringPairs, - nonFinitePairs, - nonFiniteStringPairs, - nonNumericPairs, - numberLikeStringPairs, - numberLiteralPairs, -} from './__fixtures__'; -describe('number validators', () => { - for (const pairs of numberLiteralPairs) { - it(`isFiniteNumber: ${pairs[0]}`, () => { - expect(isFiniteNumber(pairs[1])).toBeTruthy(); - }); - - it(`isFiniteNumeric: ${pairs[0]}`, () => { - expect(isFiniteNumeric(pairs[1])).toBeTruthy(); - }); - - it(`isNumber: ${pairs[0]}`, () => { - expect(isNumber(pairs[1])).toBeTruthy(); - }); - - it(`isNumeric: ${pairs[0]}`, () => { - expect(isNumeric(pairs[1])).toBeTruthy(); - }); - } - - for (const pairs of floatingPointPairs) { - it(`isFiniteNumber: ${pairs[0]}`, () => { - expect(isFiniteNumber(pairs[1])).toBeTruthy(); - }); - - it(`isFiniteNumeric: ${pairs[0]}`, () => { - expect(isFiniteNumeric(pairs[1])).toBeTruthy(); - }); - - it(`isNumber: ${pairs[0]}`, () => { - expect(isNumber(pairs[1])).toBeTruthy(); - }); - - it(`isNumeric: ${pairs[0]}`, () => { - expect(isNumeric(pairs[1])).toBeTruthy(); - }); - } - - for (const pairs of numberLikeStringPairs) { - it(`isFiniteNumber: ${pairs[0]}`, () => { - expect(isFiniteNumber(pairs[1])).toBeFalsy(); - }); - - it(`isFiniteNumeric: ${pairs[0]}`, () => { - expect(isFiniteNumeric(pairs[1])).toBeTruthy(); - }); - - it(`isNumber: ${pairs[0]}`, () => { - expect(isNumber(pairs[1])).toBeFalsy(); - }); - - it(`isNumeric: ${pairs[0]}`, () => { - expect(isNumeric(pairs[1])).toBeTruthy(); - }); - } - - for (const pairs of floatingPointStringPairs) { - it(`isFiniteNumber: ${pairs[0]}`, () => { - expect(isFiniteNumber(pairs[1])).toBeFalsy(); - }); - - it(`isFiniteNumeric: ${pairs[0]}`, () => { - expect(isFiniteNumeric(pairs[1])).toBeTruthy(); - }); +// biome-ignore lint/style/useNumberNamespace: want to diff against Number.NEGATIVE_INFINITY +const INFINITY = Infinity; +const { POSITIVE_INFINITY, NEGATIVE_INFINITY } = Number; - it(`isNumber: ${pairs[0]}`, () => { - expect(isNumber(pairs[1])).toBeFalsy(); - }); - - it(`isNumeric: ${pairs[0]}`, () => { - expect(isNumeric(pairs[1])).toBeTruthy(); - }); - } - - for (const pairs of nonFinitePairs) { - it(`isFiniteNumber: ${pairs[0]}`, () => { - expect(isFiniteNumber(pairs[1])).toBeFalsy(); - }); - - it(`isFiniteNumeric: ${pairs[0]}`, () => { - expect(isFiniteNumeric(pairs[1])).toBeFalsy(); - }); - - it(`isNumber: ${pairs[0]}`, () => { - expect(isNumber(pairs[1])).toBeTruthy(); - }); - - it(`isNumeric: ${pairs[0]}`, () => { - expect(isNumeric(pairs[1])).toBeTruthy(); - }); - } - - for (const pairs of nonFiniteStringPairs) { - it(`isFiniteNumber: ${pairs[0]}`, () => { - expect(isFiniteNumber(pairs[1])).toBeFalsy(); - }); - - it(`isFiniteNumeric: ${pairs[0]}`, () => { - expect(isFiniteNumeric(pairs[1])).toBeFalsy(); - }); - - it(`isNumber: ${pairs[0]}`, () => { - expect(isNumber(pairs[1])).toBeFalsy(); - }); - - it(`isNumeric: ${pairs[0]}`, () => { - expect(isNumeric(pairs[1])).toBeTruthy(); - }); - } - - for (const pairs of nonNumericPairs) { - it(`isFiniteNumber: ${pairs[0]}`, () => { - expect(isFiniteNumber(pairs[1])).toBeFalsy(); - }); - - it(`isFiniteNumeric: ${pairs[0]}`, () => { - // TODO: find a cleaner way to do this - // NOTE: parseFloat will convert 7.2acdgs to 7.2 - if (pairs[0].includes('trailing non-numeric')) { - expect(isFiniteNumeric(pairs[1])).toBeTruthy(); - } else { - expect(isFiniteNumeric(pairs[1])).toBeFalsy(); - } - }); - - it(`isNumber: ${pairs[0]}`, () => { - expect(isNumber(pairs[1])).toBeFalsy(); - }); - - it(`isNumeric: ${pairs[0]}`, () => { - // TODO: find a cleaner way to do this - // NOTE: parseFloat will convert 7.2acdgs to 7.2 - if (pairs[0].includes('trailing non-numeric')) { - expect(isFiniteNumeric(pairs[1])).toBeTruthy(); - } else { - expect(isFiniteNumeric(pairs[1])).toBeFalsy(); - } - }); - } +describe('number validators', () => { + it.each` + label | value | isFiniteNumber | isFiniteNumeric | isNumber | isNumeric + ${'integer literal: negative'} | ${-1} | ${true} | ${true} | ${true} | ${true} + ${'integer literal: zero'} | ${0} | ${true} | ${true} | ${true} | ${true} + ${'integer literal: positive'} | ${1} | ${true} | ${true} | ${true} | ${true} + ${'integer literal: octal'} | ${0o0144} | ${true} | ${true} | ${true} | ${true} + ${'integer literal: hexadecimal'} | ${0xfff} | ${true} | ${true} | ${true} | ${true} + ${'floating point: nagative'} | ${-1.1234} | ${true} | ${true} | ${true} | ${true} + ${'floating point: positive'} | ${1.1234} | ${true} | ${true} | ${true} | ${true} + ${'floating point: exponential notation'} | ${8e5} | ${true} | ${true} | ${true} | ${true} + ${'number-like string: negative'} | ${'-1'} | ${false} | ${true} | ${false} | ${true} + ${'number-like string: zero'} | ${'0'} | ${false} | ${true} | ${false} | ${true} + ${'number-like string: positive'} | ${'1'} | ${false} | ${true} | ${false} | ${true} + ${'number-like string: octal'} | ${'040'} | ${false} | ${true} | ${false} | ${true} + ${'number-like string: hexadecimal'} | ${'0xFF'} | ${false} | ${true} | ${false} | ${true} + ${'number-like string: zero padded'} | ${'05'} | ${false} | ${true} | ${false} | ${true} + ${'float string: negative'} | ${'-1.1234'} | ${false} | ${true} | ${false} | ${true} + ${'float string: positive'} | ${'1.1234'} | ${false} | ${true} | ${false} | ${true} + ${'float string: exponential notation'} | ${'123e-2'} | ${false} | ${true} | ${false} | ${true} + ${'float string: zero padded'} | ${'01.1234'} | ${false} | ${true} | ${false} | ${true} + ${'non-finite number: NaN'} | ${Number.NaN} | ${false} | ${false} | ${true} | ${true} + ${'non-finite number: positive'} | ${POSITIVE_INFINITY} | ${false} | ${false} | ${true} | ${true} + ${'non-finite number: negative'} | ${NEGATIVE_INFINITY} | ${false} | ${false} | ${true} | ${true} + ${'non-finite number: positive primitive'} | ${INFINITY} | ${false} | ${false} | ${true} | ${true} + ${'non-finite number: negative primitive'} | ${-INFINITY} | ${false} | ${false} | ${true} | ${true} + ${'non-finite string: NaN string'} | ${'NaN'} | ${false} | ${false} | ${false} | ${true} + ${'non-finite string: positive'} | ${'Infinity'} | ${false} | ${false} | ${false} | ${true} + ${'non-finite string: negative'} | ${'-Infinity'} | ${false} | ${false} | ${false} | ${true} + ${'non-numeric: empty'} | ${''} | ${false} | ${false} | ${false} | ${false} + ${'non-numeric: whitespace character'} | ${' '} | ${false} | ${false} | ${false} | ${false} + ${'non-numeric: tab character'} | ${'\t\t'} | ${false} | ${false} | ${false} | ${false} + ${'non-numeric: alphanumeric '} | ${'abcdefghi123456'} | ${false} | ${false} | ${false} | ${false} + ${'non-numeric: non-numeric '} | ${'xabcdefx'} | ${false} | ${false} | ${false} | ${false} + ${'non-numeric: preceding non-numeric'} | ${'bcfed5.2'} | ${false} | ${false} | ${false} | ${false} + ${'non-numeric: literal true'} | ${true} | ${false} | ${false} | ${false} | ${false} + ${'non-numeric: literal false'} | ${false} | ${false} | ${false} | ${false} | ${false} + ${'non-numeric: undefined'} | ${undefined} | ${false} | ${false} | ${false} | ${false} + ${'non-numeric: null'} | ${null} | ${false} | ${false} | ${false} | ${false} + ${'non-numeric: date object'} | ${new Date()} | ${false} | ${false} | ${false} | ${false} + ${'non-numeric: object'} | ${{}} | ${false} | ${false} | ${false} | ${false} + ${'non-numeric: function instance'} | ${() => void 0} | ${false} | ${false} | ${false} | ${false} + `('$label', ({ value, ...expected }) => { + expect(isFiniteNumber(value)).toBe(expected.isFiniteNumber); + expect(isFiniteNumeric(value)).toBe(expected.isFiniteNumeric); + expect(isNumber(value)).toBe(expected.isNumber); + expect(isNumeric(value)).toBe(expected.isNumeric); + }); + + it('should be different for number with trailing non-numeric characters', () => { + const value = '7.2abcdef'; + + expect(isFiniteNumber(value)).toBe(false); + expect(isNumber(value)).toBe(false); + + // NOTE: these differ from it.each testing above + // parseFloat will convert value to 7.2 just fine + expect(isFiniteNumeric(value)).toBe(true); + expect(isNumeric(value)).toBe(true); + }); }); diff --git a/packages/predicates/src/is-string/index.test.ts b/packages/predicates/src/is-string/index.test.ts index 8829e73d..aafb03cc 100644 --- a/packages/predicates/src/is-string/index.test.ts +++ b/packages/predicates/src/is-string/index.test.ts @@ -15,9 +15,10 @@ import { isString } from './'; import { nonStringPairs } from './__fixtures__'; describe('string validators', () => { - for (const pair of nonStringPairs) { - it(`isString: ${pair[0]}`, () => { - expect(isString(pair[1])).toBeFalsy(); - }); - } + it.each(nonStringPairs)( + 'isString(%s) should be false', + (_expected, value) => { + expect(isString(value)).toBeFalsy(); + }, + ); }); diff --git a/packages/predicates/src/is-worker/index.test.ts b/packages/predicates/src/is-worker/index.test.ts index cf706453..bec9f670 100644 --- a/packages/predicates/src/is-worker/index.test.ts +++ b/packages/predicates/src/is-worker/index.test.ts @@ -14,34 +14,18 @@ import '@vitest/web-worker'; import { describe, it, expect } from 'vitest'; import { isSharedWorker, isWorker } from './'; -const nonWorkerPairs = [ - ['array', []], - ['object', {}], - [ - 'function', - () => { - // noop - }, - ], -] as const; - const workerUrl = new URL('./__fixtures__/worker.ts', import.meta.url); -const sharedWorker = new SharedWorker(workerUrl); -const worker = new Worker(workerUrl); describe('worker validators', () => { - expect(isSharedWorker(sharedWorker)).toBeTruthy(); - expect(isSharedWorker(worker)).toBeFalsy(); - expect(isWorker(worker)).toBeTruthy(); - expect(isWorker(sharedWorker)).toBeFalsy(); - - for (const pair of nonWorkerPairs) { - it(`isSharedWorker: ${pair[0]}`, () => { - expect(isSharedWorker(pair[1])).toBeFalsy(); - }); - - it(`isWorker: ${pair[0]}`, () => { - expect(isWorker(pair[1])).toBeFalsy(); - }); - } + it.each` + label | value | isShared | isWorker + ${'array'} | ${[]} | ${false} | ${false} + ${'object'} | ${{}} | ${false} | ${false} + ${'function'} | ${() => void 0} | ${false} | ${false} + ${'SharedWorker'} | ${new SharedWorker(workerUrl)} | ${true} | ${false} + ${'Worker'} | ${new Worker(workerUrl)} | ${false} | ${true} + `('$label', ({ value, ...expected }) => { + expect(isSharedWorker(value)).toBe(expected.isShared); + expect(isWorker(value)).toBe(expected.isWorker); + }); });