forked from orbit-oss/is
Fix some type guards
This commit is contained in:
parent
cb4ee0e92c
commit
13febb6b01
8 changed files with 715 additions and 205 deletions
447
test/test.ts
447
test/test.ts
|
|
@ -15,6 +15,7 @@ import is, {
|
|||
assert as isAssert,
|
||||
assertPropertyKey,
|
||||
type AssertionTypeDescription,
|
||||
type NaN as NaNType,
|
||||
type Predicate,
|
||||
type Primitive,
|
||||
type TypedArray,
|
||||
|
|
@ -156,7 +157,7 @@ const primitiveTypes = {
|
|||
safeInteger: {
|
||||
fixtures: [...reusableFixtures.integer, ...reusableFixtures.safeInteger],
|
||||
typename: 'number',
|
||||
typeDescription: 'integer',
|
||||
typeDescription: 'safe integer',
|
||||
},
|
||||
infinite: {
|
||||
fixtures: [...reusableFixtures.infinite],
|
||||
|
|
@ -208,6 +209,7 @@ const objectTypes = {
|
|||
object: {
|
||||
fixtures: [
|
||||
Object.create({x: 1}),
|
||||
{[Symbol.toStringTag]: 'String'},
|
||||
...reusableFixtures.plainObject,
|
||||
],
|
||||
typename: 'Object',
|
||||
|
|
@ -280,6 +282,7 @@ const objectTypes = {
|
|||
boundFunction: {
|
||||
fixtures: [...reusableFixtures.boundFunction, ...reusableFixtures.asyncFunction],
|
||||
typename: 'Function',
|
||||
typeDescription: 'bound Function',
|
||||
},
|
||||
map: {
|
||||
fixtures: [
|
||||
|
|
@ -526,6 +529,7 @@ test('is.positiveNumber', () => {
|
|||
assert.strictEqual(is.positiveNumber(-6), false);
|
||||
assert.strictEqual(is.positiveNumber(-1.4), false);
|
||||
assert.strictEqual(is.positiveNumber(Number.NEGATIVE_INFINITY), false);
|
||||
assert.strictEqual(is.positiveNumber(Number.NaN), false);
|
||||
|
||||
assert.throws(() => {
|
||||
isAssert.positiveNumber(0);
|
||||
|
|
@ -544,6 +548,33 @@ test('is.positiveNumber', () => {
|
|||
});
|
||||
});
|
||||
|
||||
test('is.nan', () => {
|
||||
assert.ok(is.nan(Number.NaN));
|
||||
assert.ok(is.nan(NaN)); // eslint-disable-line unicorn/prefer-number-properties
|
||||
|
||||
assert.doesNotThrow(() => {
|
||||
isAssert.nan(Number.NaN);
|
||||
});
|
||||
|
||||
assert.strictEqual(is.nan(0), false);
|
||||
assert.strictEqual(is.nan(-0), false);
|
||||
assert.strictEqual(is.nan(1), false);
|
||||
assert.strictEqual(is.nan(Number.POSITIVE_INFINITY), false);
|
||||
assert.strictEqual(is.nan(Number.NEGATIVE_INFINITY), false);
|
||||
assert.strictEqual(is.nan('NaN'), false);
|
||||
assert.strictEqual(is.nan(undefined), false);
|
||||
|
||||
assert.throws(() => {
|
||||
isAssert.nan(0);
|
||||
});
|
||||
assert.throws(() => {
|
||||
isAssert.nan(1);
|
||||
});
|
||||
assert.throws(() => {
|
||||
isAssert.nan('NaN');
|
||||
});
|
||||
});
|
||||
|
||||
test('is.finiteNumber', () => {
|
||||
assert.ok(is.finiteNumber(6));
|
||||
assert.ok(is.finiteNumber(-6));
|
||||
|
|
@ -592,6 +623,7 @@ test('is.negativeNumber', () => {
|
|||
assert.strictEqual(is.negativeNumber(6), false);
|
||||
assert.strictEqual(is.negativeNumber(1.4), false);
|
||||
assert.strictEqual(is.negativeNumber(Number.POSITIVE_INFINITY), false);
|
||||
assert.strictEqual(is.negativeNumber(Number.NaN), false);
|
||||
|
||||
assert.throws(() => {
|
||||
isAssert.negativeNumber(0);
|
||||
|
|
@ -729,6 +761,32 @@ test('is.nonNegativeInteger', () => {
|
|||
});
|
||||
});
|
||||
|
||||
test('is.infinite', () => {
|
||||
assert.ok(is.infinite(Number.POSITIVE_INFINITY));
|
||||
assert.ok(is.infinite(Number.NEGATIVE_INFINITY));
|
||||
|
||||
assert.doesNotThrow(() => {
|
||||
isAssert.infinite(Number.POSITIVE_INFINITY);
|
||||
});
|
||||
assert.doesNotThrow(() => {
|
||||
isAssert.infinite(Number.NEGATIVE_INFINITY);
|
||||
});
|
||||
|
||||
assert.strictEqual(is.infinite(0), false);
|
||||
assert.strictEqual(is.infinite(1), false);
|
||||
assert.strictEqual(is.infinite(-1), false);
|
||||
assert.strictEqual(is.infinite(Number.NaN), false);
|
||||
assert.strictEqual(is.infinite(Number.MAX_VALUE), false);
|
||||
assert.strictEqual(is.infinite('Infinity'), false);
|
||||
|
||||
assert.throws(() => {
|
||||
isAssert.infinite(0);
|
||||
});
|
||||
assert.throws(() => {
|
||||
isAssert.infinite(Number.NaN);
|
||||
});
|
||||
});
|
||||
|
||||
test('is.numericString supplemental', () => {
|
||||
assert.strictEqual(is.numericString(''), false);
|
||||
assert.strictEqual(is.numericString(' '), false);
|
||||
|
|
@ -998,6 +1056,20 @@ test('is.urlString', () => {
|
|||
}
|
||||
})();
|
||||
|
||||
// Type test for is.nan branded-type narrowing
|
||||
(() => {
|
||||
const value: unknown = Number.NaN;
|
||||
|
||||
if (is.nan(value)) {
|
||||
// ✅ In true branch: value is narrowed to the branded NaN type
|
||||
expectTypeOf(value).toEqualTypeOf<NaNType>();
|
||||
expectTypeOf(value).toMatchTypeOf<number>();
|
||||
} else {
|
||||
// ✅ In false branch: value remains unknown (not incorrectly narrowed)
|
||||
expectTypeOf(value).toEqualTypeOf<unknown>();
|
||||
}
|
||||
})();
|
||||
|
||||
test('is.truthy', () => {
|
||||
assert.ok(is.truthy('unicorn'));
|
||||
assert.ok(is.truthy('🦄'));
|
||||
|
|
@ -2268,370 +2340,379 @@ test('assert', () => {
|
|||
test('custom assertion message', () => {
|
||||
const message = 'Custom error message';
|
||||
|
||||
assert.throws(() => {
|
||||
const assertThrowsTypeErrorWithMessage = (assertion: () => void) => {
|
||||
// `node:assert` does not verify the error class when matching only on `{message}`.
|
||||
assert.throws(assertion, error => {
|
||||
assert.ok(error instanceof TypeError);
|
||||
assert.strictEqual(error.message, message);
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.array(undefined, undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.arrayBuffer(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.arrayLike(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.asyncFunction(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.asyncGenerator(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.asyncGeneratorFunction(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.asyncIterable(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.bigInt64Array(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.bigUint64Array(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.bigint(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.blob(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.boolean(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.boundFunction(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.buffer(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.class(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.dataView(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.date(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.directInstanceOf(undefined, Error, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.emptyArray(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.emptyMap(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.emptyObject(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.emptySet(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.emptyString(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.emptyStringOrWhitespace(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
enum Enum {}
|
||||
isAssert.enumCase('invalid', Enum, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.error(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.evenInteger(33, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.falsy(true, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.finiteNumber(Number.POSITIVE_INFINITY, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.float32Array(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.float64Array(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.formData(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.function(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.generator(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.generatorFunction(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.htmlElement(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.inRange(5, [1, 2], message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.infinite(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.int16Array(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.int32Array(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.int8Array(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.integer(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.iterable(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.map(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.nan(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.nativePromise(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.negativeNumber(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.nodeStream(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.nonEmptyArray(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.nonEmptyMap(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.nonEmptyObject(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.nonEmptySet(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.nonEmptyString(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.nonEmptyStringAndNotWhitespace(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.nonNegativeNumber(-1, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.null(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.nullOrUndefined(false, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.number(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.numericString(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.object(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.observable(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.oddInteger(42, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.plainObject(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.positiveInteger(0, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.positiveNumber(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.primitive([], message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.promise(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.propertyKey(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.regExp(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.safeInteger(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.set(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.sharedArrayBuffer(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.string(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.symbol(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.truthy(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.tupleLike(undefined, [], message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.typedArray(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.uint16Array(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.uint32Array(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.uint8Array(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.uint8ClampedArray(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.undefined(false, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.urlInstance(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.urlSearchParams(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.urlString(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.validDate(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.validLength(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.weakMap(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.weakRef(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.weakSet(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
assertThrowsTypeErrorWithMessage(() => {
|
||||
isAssert.whitespaceString(undefined, message);
|
||||
}, {message});
|
||||
});
|
||||
});
|
||||
|
||||
test('is.optional', () => {
|
||||
|
|
|
|||
12
test/tsconfig.json
Normal file
12
test/tsconfig.json
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "..",
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false
|
||||
},
|
||||
"include": [
|
||||
"../source",
|
||||
"type-tests.ts"
|
||||
]
|
||||
}
|
||||
220
test/type-tests.ts
Normal file
220
test/type-tests.ts
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
import is, {
|
||||
type EvenInteger,
|
||||
type FiniteNumber,
|
||||
type Integer,
|
||||
type NaN as NaNType,
|
||||
type NegativeInfinity,
|
||||
type NegativeInteger,
|
||||
type NegativeNumber,
|
||||
type NonNegativeInteger,
|
||||
type NonNegativeNumber,
|
||||
type OddInteger,
|
||||
type PositiveInfinity,
|
||||
type PositiveInteger,
|
||||
type PositiveNumber,
|
||||
type SafeInteger,
|
||||
type ValidLength,
|
||||
} from '../source/index.ts';
|
||||
|
||||
// For each predicate, verify two things:
|
||||
// 1. True branch narrows to the branded type.
|
||||
// 2. False branch on a `number` input stays `number` (not `never`).
|
||||
// Without the branded types, `Exclude<number, number>` = `never` would break
|
||||
// the common validation-guard pattern: if (!is.X(n)) throw; use(n).
|
||||
|
||||
const nanCheck = (value: number) => {
|
||||
if (is.nan(value)) {
|
||||
const _: NaNType = value;
|
||||
} else {
|
||||
const _: number = value;
|
||||
}
|
||||
};
|
||||
|
||||
const finiteNumberCheck = (value: number) => {
|
||||
if (is.finiteNumber(value)) {
|
||||
const _: FiniteNumber = value;
|
||||
} else {
|
||||
const _: number = value;
|
||||
}
|
||||
};
|
||||
|
||||
const nonNegativeNumberCheck = (value: number) => {
|
||||
if (is.nonNegativeNumber(value)) {
|
||||
const _: NonNegativeNumber = value;
|
||||
} else {
|
||||
const _: number = value;
|
||||
}
|
||||
};
|
||||
|
||||
const positiveIntegerCheck = (value: number) => {
|
||||
if (is.positiveInteger(value)) {
|
||||
const _: PositiveInteger = value;
|
||||
const __: Integer = value;
|
||||
const ___: NonNegativeInteger = value;
|
||||
} else {
|
||||
const _: number = value;
|
||||
}
|
||||
};
|
||||
|
||||
const negativeIntegerCheck = (value: number) => {
|
||||
if (is.negativeInteger(value)) {
|
||||
const _: NegativeInteger = value;
|
||||
const __: Integer = value;
|
||||
} else {
|
||||
const _: number = value;
|
||||
}
|
||||
};
|
||||
|
||||
const nonNegativeIntegerCheck = (value: number) => {
|
||||
if (is.nonNegativeInteger(value)) {
|
||||
const _: NonNegativeInteger = value;
|
||||
const __: Integer = value;
|
||||
} else {
|
||||
const _: number = value;
|
||||
}
|
||||
};
|
||||
|
||||
const infiniteCheck = (value: number) => {
|
||||
if (is.infinite(value)) {
|
||||
const _: PositiveInfinity | NegativeInfinity = value;
|
||||
const __: PositiveNumber | NegativeNumber = value;
|
||||
} else {
|
||||
const _: number = value;
|
||||
}
|
||||
};
|
||||
|
||||
const integerCheck = (value: number) => {
|
||||
if (is.integer(value)) {
|
||||
const _: Integer = value;
|
||||
const __: FiniteNumber = value;
|
||||
} else {
|
||||
const _: number = value;
|
||||
}
|
||||
};
|
||||
|
||||
const safeIntegerCheck = (value: number) => {
|
||||
if (is.safeInteger(value)) {
|
||||
const _: SafeInteger = value;
|
||||
const __: Integer = value;
|
||||
} else {
|
||||
const _: number = value;
|
||||
}
|
||||
};
|
||||
|
||||
const evenIntegerCheck = (value: number) => {
|
||||
if (is.evenInteger(value)) {
|
||||
const _: EvenInteger = value;
|
||||
const __: Integer = value;
|
||||
} else {
|
||||
const _: number = value;
|
||||
}
|
||||
};
|
||||
|
||||
const oddIntegerCheck = (value: number) => {
|
||||
if (is.oddInteger(value)) {
|
||||
const _: OddInteger = value;
|
||||
const __: Integer = value;
|
||||
} else {
|
||||
const _: number = value;
|
||||
}
|
||||
};
|
||||
|
||||
const positiveNumberCheck = (value: number) => {
|
||||
if (is.positiveNumber(value)) {
|
||||
const _: PositiveNumber = value;
|
||||
const __: NonNegativeNumber = value;
|
||||
} else {
|
||||
const _: number = value;
|
||||
}
|
||||
};
|
||||
|
||||
const negativeNumberCheck = (value: number) => {
|
||||
if (is.negativeNumber(value)) {
|
||||
const _: NegativeNumber = value;
|
||||
} else {
|
||||
const _: number = value;
|
||||
}
|
||||
};
|
||||
|
||||
const validLengthCheck = (value: number) => {
|
||||
if (is.validLength(value)) {
|
||||
const _: ValidLength = value;
|
||||
const __: SafeInteger = value;
|
||||
const ___: NonNegativeInteger = value;
|
||||
} else {
|
||||
const _: number = value;
|
||||
}
|
||||
};
|
||||
|
||||
const integerUnknownCheck = (value: unknown) => {
|
||||
if (is.integer(value)) {
|
||||
const _: Integer = value;
|
||||
const __: FiniteNumber = value;
|
||||
}
|
||||
};
|
||||
|
||||
const positiveIntegerUnknownCheck = (value: unknown) => {
|
||||
if (is.positiveInteger(value)) {
|
||||
const _: PositiveInteger = value;
|
||||
const __: NonNegativeInteger = value;
|
||||
}
|
||||
};
|
||||
|
||||
const integerMixedUnionCheck = (value: string | number) => {
|
||||
if (is.integer(value)) {
|
||||
const _: number = value;
|
||||
} else {
|
||||
const _: string = value;
|
||||
}
|
||||
};
|
||||
|
||||
const positiveNumberMixedUnionCheck = (value: string | number) => {
|
||||
if (is.positiveNumber(value)) {
|
||||
const _: number = value;
|
||||
} else {
|
||||
const _: string = value;
|
||||
}
|
||||
};
|
||||
|
||||
const chainedNumericGuardCheck = (value: number) => {
|
||||
if (is.positiveNumber(value) && is.integer(value)) {
|
||||
const _: PositiveNumber = value;
|
||||
const __: Integer = value;
|
||||
const ___: FiniteNumber = value;
|
||||
}
|
||||
};
|
||||
|
||||
const distinctNumericBrandsStayDistinct = (
|
||||
positiveInteger: PositiveInteger,
|
||||
negativeInteger: NegativeInteger,
|
||||
validLength: ValidLength,
|
||||
) => {
|
||||
// @ts-expect-error -- Distinct numeric refinements must not collapse into each other.
|
||||
const _: NegativeInteger = positiveInteger;
|
||||
// @ts-expect-error -- ValidLength is non-negative and must not become a signed integer refinement.
|
||||
const __: NegativeInteger = validLength;
|
||||
|
||||
return negativeInteger;
|
||||
};
|
||||
|
||||
// Suppress unused variable warnings
|
||||
nanCheck(42);
|
||||
finiteNumberCheck(42);
|
||||
nonNegativeNumberCheck(42);
|
||||
positiveIntegerCheck(42);
|
||||
negativeIntegerCheck(-1);
|
||||
nonNegativeIntegerCheck(0);
|
||||
infiniteCheck(Number.POSITIVE_INFINITY);
|
||||
integerCheck(1);
|
||||
safeIntegerCheck(1);
|
||||
evenIntegerCheck(2);
|
||||
oddIntegerCheck(1);
|
||||
positiveNumberCheck(1);
|
||||
negativeNumberCheck(-1);
|
||||
validLengthCheck(0);
|
||||
integerUnknownCheck(1);
|
||||
positiveIntegerUnknownCheck(1);
|
||||
integerMixedUnionCheck(1);
|
||||
positiveNumberMixedUnionCheck(1);
|
||||
chainedNumericGuardCheck(1);
|
||||
distinctNumericBrandsStayDistinct(42 as PositiveInteger, -1 as NegativeInteger, 0 as ValidLength);
|
||||
Loading…
Add table
Add a link
Reference in a new issue