Test coverage for is(value) (#86)
This commit is contained in:
parent
120f74ab63
commit
373605e40d
2 changed files with 116 additions and 56 deletions
|
|
@ -16,6 +16,7 @@ export const enum TypeName {
|
||||||
number = 'number',
|
number = 'number',
|
||||||
symbol = 'symbol',
|
symbol = 'symbol',
|
||||||
Function = 'Function',
|
Function = 'Function',
|
||||||
|
Generator = 'Generator',
|
||||||
GeneratorFunction = 'GeneratorFunction',
|
GeneratorFunction = 'GeneratorFunction',
|
||||||
AsyncFunction = 'AsyncFunction',
|
AsyncFunction = 'AsyncFunction',
|
||||||
Observable = 'Observable',
|
Observable = 'Observable',
|
||||||
|
|
|
||||||
171
test/test.ts
171
test/test.ts
|
|
@ -8,7 +8,7 @@ import test, {ExecutionContext} from 'ava';
|
||||||
import {JSDOM} from 'jsdom';
|
import {JSDOM} from 'jsdom';
|
||||||
import {Subject, Observable} from 'rxjs';
|
import {Subject, Observable} from 'rxjs';
|
||||||
import ZenObservable from 'zen-observable';
|
import ZenObservable from 'zen-observable';
|
||||||
import is from '../source';
|
import is, {TypeName} from '../source';
|
||||||
|
|
||||||
const isNode10orHigher = Number(process.versions.node.split('.')[0]) >= 10;
|
const isNode10orHigher = Number(process.versions.node.split('.')[0]) >= 10;
|
||||||
|
|
||||||
|
|
@ -21,6 +21,7 @@ const createDomElement = (element: string) => document.createElement(element);
|
||||||
|
|
||||||
interface Test {
|
interface Test {
|
||||||
fixtures: unknown[];
|
fixtures: unknown[];
|
||||||
|
typename?: TypeName;
|
||||||
is(value: unknown): boolean;
|
is(value: unknown): boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -29,13 +30,15 @@ const types = new Map<string, Test>([
|
||||||
is: is.undefined,
|
is: is.undefined,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
undefined
|
undefined
|
||||||
]
|
],
|
||||||
|
typename: TypeName.undefined
|
||||||
}],
|
}],
|
||||||
['null', {
|
['null', {
|
||||||
is: is.null_,
|
is: is.null_,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
null
|
null
|
||||||
]
|
],
|
||||||
|
typename: TypeName.null
|
||||||
}],
|
}],
|
||||||
['string', {
|
['string', {
|
||||||
is: is.string,
|
is: is.string,
|
||||||
|
|
@ -43,14 +46,16 @@ const types = new Map<string, Test>([
|
||||||
'🦄',
|
'🦄',
|
||||||
'hello world',
|
'hello world',
|
||||||
''
|
''
|
||||||
]
|
],
|
||||||
|
typename: TypeName.string
|
||||||
}],
|
}],
|
||||||
['emptyString', {
|
['emptyString', {
|
||||||
is: is.emptyString,
|
is: is.emptyString,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
'',
|
'',
|
||||||
String()
|
String()
|
||||||
]
|
],
|
||||||
|
typename: TypeName.string
|
||||||
}],
|
}],
|
||||||
['number', {
|
['number', {
|
||||||
is: is.number,
|
is: is.number,
|
||||||
|
|
@ -61,19 +66,22 @@ const types = new Map<string, Test>([
|
||||||
-0,
|
-0,
|
||||||
Infinity,
|
Infinity,
|
||||||
-Infinity
|
-Infinity
|
||||||
]
|
],
|
||||||
|
typename: TypeName.number
|
||||||
}],
|
}],
|
||||||
['boolean', {
|
['boolean', {
|
||||||
is: is.boolean,
|
is: is.boolean,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
true, false
|
true, false
|
||||||
]
|
],
|
||||||
|
typename: TypeName.boolean
|
||||||
}],
|
}],
|
||||||
['symbol', {
|
['symbol', {
|
||||||
is: is.symbol,
|
is: is.symbol,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
Symbol('🦄')
|
Symbol('🦄')
|
||||||
]
|
],
|
||||||
|
typename: TypeName.symbol
|
||||||
}],
|
}],
|
||||||
['numericString', {
|
['numericString', {
|
||||||
is: is.numericString,
|
is: is.numericString,
|
||||||
|
|
@ -81,21 +89,24 @@ const types = new Map<string, Test>([
|
||||||
'5',
|
'5',
|
||||||
'-3.2',
|
'-3.2',
|
||||||
'Infinity'
|
'Infinity'
|
||||||
]
|
],
|
||||||
|
typename: TypeName.string
|
||||||
}],
|
}],
|
||||||
['array', {
|
['array', {
|
||||||
is: is.array,
|
is: is.array,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
[1, 2],
|
[1, 2],
|
||||||
new Array(2)
|
new Array(2)
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Array
|
||||||
}],
|
}],
|
||||||
['emptyArray', {
|
['emptyArray', {
|
||||||
is: is.emptyArray,
|
is: is.emptyArray,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
[],
|
[],
|
||||||
new Array() // eslint-disable-line @typescript-eslint/no-array-constructor
|
new Array() // eslint-disable-line @typescript-eslint/no-array-constructor
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Array
|
||||||
}],
|
}],
|
||||||
['function', {
|
['function', {
|
||||||
is: is.function_,
|
is: is.function_,
|
||||||
|
|
@ -105,53 +116,61 @@ const types = new Map<string, Test>([
|
||||||
() => {},
|
() => {},
|
||||||
async function () {},
|
async function () {},
|
||||||
function * (): unknown {}
|
function * (): unknown {}
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Function
|
||||||
}],
|
}],
|
||||||
['buffer', {
|
['buffer', {
|
||||||
is: is.buffer,
|
is: is.buffer,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
Buffer.from('🦄')
|
Buffer.from('🦄')
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Buffer
|
||||||
}],
|
}],
|
||||||
['object', {
|
['object', {
|
||||||
is: is.object,
|
is: is.object,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
{x: 1},
|
{x: 1},
|
||||||
Object.create({x: 1})
|
Object.create({x: 1})
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Object
|
||||||
}],
|
}],
|
||||||
['regExp', {
|
['regExp', {
|
||||||
is: is.regExp,
|
is: is.regExp,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
/\w/,
|
/\w/,
|
||||||
new RegExp('\\w')
|
new RegExp('\\w')
|
||||||
]
|
],
|
||||||
|
typename: TypeName.RegExp
|
||||||
}],
|
}],
|
||||||
['date', {
|
['date', {
|
||||||
is: is.date,
|
is: is.date,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
new Date()
|
new Date()
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Date
|
||||||
}],
|
}],
|
||||||
['error', {
|
['error', {
|
||||||
is: is.error,
|
is: is.error,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
new Error('🦄'),
|
new Error('🦄'),
|
||||||
new ErrorSubclassFixture()
|
new ErrorSubclassFixture()
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Error
|
||||||
}],
|
}],
|
||||||
['nativePromise', {
|
['nativePromise', {
|
||||||
is: is.nativePromise,
|
is: is.nativePromise,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
Promise.resolve(),
|
Promise.resolve(),
|
||||||
PromiseSubclassFixture.resolve()
|
PromiseSubclassFixture.resolve()
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Promise
|
||||||
}],
|
}],
|
||||||
['promise', {
|
['promise', {
|
||||||
is: is.promise,
|
is: is.promise,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
{then() {}, catch() {}}
|
{then() {}, catch() {}}
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Object
|
||||||
}],
|
}],
|
||||||
['generator', {
|
['generator', {
|
||||||
is: is.generator,
|
is: is.generator,
|
||||||
|
|
@ -159,7 +178,8 @@ const types = new Map<string, Test>([
|
||||||
(function * () {
|
(function * () {
|
||||||
yield 4;
|
yield 4;
|
||||||
})()
|
})()
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Generator
|
||||||
}],
|
}],
|
||||||
['generatorFunction', {
|
['generatorFunction', {
|
||||||
is: is.generatorFunction,
|
is: is.generatorFunction,
|
||||||
|
|
@ -167,130 +187,151 @@ const types = new Map<string, Test>([
|
||||||
function * () {
|
function * () {
|
||||||
yield 4;
|
yield 4;
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Function
|
||||||
}],
|
}],
|
||||||
['asyncFunction', {
|
['asyncFunction', {
|
||||||
is: is.asyncFunction,
|
is: is.asyncFunction,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
async function () {},
|
async function () {},
|
||||||
async () => {}
|
async () => {}
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Function
|
||||||
}],
|
}],
|
||||||
['boundFunction', {
|
['boundFunction', {
|
||||||
is: is.boundFunction,
|
is: is.boundFunction,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
() => {},
|
() => {},
|
||||||
function () {}.bind(null) // eslint-disable-line no-extra-bind
|
function () {}.bind(null) // eslint-disable-line no-extra-bind
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Function
|
||||||
}],
|
}],
|
||||||
['map', {
|
['map', {
|
||||||
is: is.map,
|
is: is.map,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
new Map([['one', '1']])
|
new Map([['one', '1']])
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Map
|
||||||
}],
|
}],
|
||||||
['emptyMap', {
|
['emptyMap', {
|
||||||
is: is.emptyMap,
|
is: is.emptyMap,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
new Map()
|
new Map()
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Map
|
||||||
}],
|
}],
|
||||||
['set', {
|
['set', {
|
||||||
is: is.set,
|
is: is.set,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
new Set(['one'])
|
new Set(['one'])
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Set
|
||||||
}],
|
}],
|
||||||
['emptySet', {
|
['emptySet', {
|
||||||
is: is.emptySet,
|
is: is.emptySet,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
new Set()
|
new Set()
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Set
|
||||||
}],
|
}],
|
||||||
['weakSet', {
|
['weakSet', {
|
||||||
is: is.weakSet,
|
is: is.weakSet,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
new WeakSet()
|
new WeakSet()
|
||||||
]
|
],
|
||||||
|
typename: TypeName.WeakSet
|
||||||
}],
|
}],
|
||||||
['weakMap', {
|
['weakMap', {
|
||||||
is: is.weakMap,
|
is: is.weakMap,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
new WeakMap()
|
new WeakMap()
|
||||||
]
|
],
|
||||||
|
typename: TypeName.WeakMap
|
||||||
}],
|
}],
|
||||||
['int8Array', {
|
['int8Array', {
|
||||||
is: is.int8Array,
|
is: is.int8Array,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
new Int8Array()
|
new Int8Array()
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Int8Array
|
||||||
}],
|
}],
|
||||||
['uint8Array', {
|
['uint8Array', {
|
||||||
is: is.uint8Array,
|
is: is.uint8Array,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
new Uint8Array()
|
new Uint8Array()
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Uint8Array
|
||||||
}],
|
}],
|
||||||
['uint8ClampedArray', {
|
['uint8ClampedArray', {
|
||||||
is: is.uint8ClampedArray,
|
is: is.uint8ClampedArray,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
new Uint8ClampedArray()
|
new Uint8ClampedArray()
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Uint8ClampedArray
|
||||||
}],
|
}],
|
||||||
['int16Array', {
|
['int16Array', {
|
||||||
is: is.int16Array,
|
is: is.int16Array,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
new Int16Array()
|
new Int16Array()
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Int16Array
|
||||||
}],
|
}],
|
||||||
['uint16Array', {
|
['uint16Array', {
|
||||||
is: is.uint16Array,
|
is: is.uint16Array,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
new Uint16Array()
|
new Uint16Array()
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Uint16Array
|
||||||
}],
|
}],
|
||||||
['int32Array', {
|
['int32Array', {
|
||||||
is: is.int32Array,
|
is: is.int32Array,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
new Int32Array()
|
new Int32Array()
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Int32Array
|
||||||
}],
|
}],
|
||||||
['uint32Array', {
|
['uint32Array', {
|
||||||
is: is.uint32Array,
|
is: is.uint32Array,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
new Uint32Array()
|
new Uint32Array()
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Uint32Array
|
||||||
}],
|
}],
|
||||||
['float32Array', {
|
['float32Array', {
|
||||||
is: is.float32Array,
|
is: is.float32Array,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
new Float32Array()
|
new Float32Array()
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Float32Array
|
||||||
}],
|
}],
|
||||||
['float64Array', {
|
['float64Array', {
|
||||||
is: is.float64Array,
|
is: is.float64Array,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
new Float64Array()
|
new Float64Array()
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Float64Array
|
||||||
}],
|
}],
|
||||||
['arrayBuffer', {
|
['arrayBuffer', {
|
||||||
is: is.arrayBuffer,
|
is: is.arrayBuffer,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
new ArrayBuffer(10)
|
new ArrayBuffer(10)
|
||||||
]
|
],
|
||||||
|
typename: TypeName.ArrayBuffer
|
||||||
}],
|
}],
|
||||||
['dataView', {
|
['dataView', {
|
||||||
is: is.dataView,
|
is: is.dataView,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
new DataView(new ArrayBuffer(10))
|
new DataView(new ArrayBuffer(10))
|
||||||
]
|
],
|
||||||
|
typename: TypeName.DataView
|
||||||
}],
|
}],
|
||||||
['nan', {
|
['nan', {
|
||||||
is: is.nan,
|
is: is.nan,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
NaN,
|
NaN,
|
||||||
Number.NaN
|
Number.NaN
|
||||||
]
|
],
|
||||||
|
typename: TypeName.number
|
||||||
}],
|
}],
|
||||||
['nullOrUndefined', {
|
['nullOrUndefined', {
|
||||||
is: is.nullOrUndefined,
|
is: is.nullOrUndefined,
|
||||||
|
|
@ -305,20 +346,23 @@ const types = new Map<string, Test>([
|
||||||
{x: 1},
|
{x: 1},
|
||||||
Object.create(null),
|
Object.create(null),
|
||||||
new Object() // eslint-disable-line no-new-object
|
new Object() // eslint-disable-line no-new-object
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Object
|
||||||
}],
|
}],
|
||||||
['integer', {
|
['integer', {
|
||||||
is: is.integer,
|
is: is.integer,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
6
|
6
|
||||||
]
|
],
|
||||||
|
typename: TypeName.number
|
||||||
}],
|
}],
|
||||||
['safeInteger', {
|
['safeInteger', {
|
||||||
is: is.safeInteger,
|
is: is.safeInteger,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
(2 ** 53) - 1,
|
(2 ** 53) - 1,
|
||||||
-(2 ** 53) + 1
|
-(2 ** 53) + 1
|
||||||
]
|
],
|
||||||
|
typename: TypeName.number
|
||||||
}],
|
}],
|
||||||
['domElement', {
|
['domElement', {
|
||||||
is: is.domElement,
|
is: is.domElement,
|
||||||
|
|
@ -348,7 +392,8 @@ const types = new Map<string, Test>([
|
||||||
new Observable(),
|
new Observable(),
|
||||||
new Subject(),
|
new Subject(),
|
||||||
new ZenObservable(() => {})
|
new ZenObservable(() => {})
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Observable
|
||||||
}],
|
}],
|
||||||
['nodeStream', {
|
['nodeStream', {
|
||||||
is: is.nodeStream,
|
is: is.nodeStream,
|
||||||
|
|
@ -362,14 +407,16 @@ const types = new Map<string, Test>([
|
||||||
new Stream.Transform(),
|
new Stream.Transform(),
|
||||||
new Stream.Stream(),
|
new Stream.Stream(),
|
||||||
new Stream.Writable()
|
new Stream.Writable()
|
||||||
]
|
],
|
||||||
|
typename: TypeName.Object
|
||||||
}],
|
}],
|
||||||
['infinite', {
|
['infinite', {
|
||||||
is: is.infinite,
|
is: is.infinite,
|
||||||
fixtures: [
|
fixtures: [
|
||||||
Infinity,
|
Infinity,
|
||||||
-Infinity
|
-Infinity
|
||||||
]
|
],
|
||||||
|
typename: TypeName.number
|
||||||
}]
|
}]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
@ -383,7 +430,7 @@ const testType = (t: ExecutionContext, type: string, exclude?: string[]) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const {is: testIs} = testData;
|
const {is: testIs, typename} = testData;
|
||||||
|
|
||||||
for (const [key, {fixtures}] of types) {
|
for (const [key, {fixtures}] of types) {
|
||||||
// TODO: Automatically exclude value types in other tests that we have in the current one.
|
// TODO: Automatically exclude value types in other tests that we have in the current one.
|
||||||
|
|
@ -392,21 +439,19 @@ const testType = (t: ExecutionContext, type: string, exclude?: string[]) => {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const assert = key === type ? t.true.bind(t) : t.false.bind(t);
|
const isTypeUnderTest = key === type;
|
||||||
|
const assert = isTypeUnderTest ? t.true.bind(t) : t.false.bind(t);
|
||||||
|
|
||||||
for (const fixture of fixtures) {
|
for (const fixture of fixtures) {
|
||||||
assert(testIs(fixture), `Value: ${util.inspect(fixture)}`);
|
assert(testIs(fixture), `Value: ${util.inspect(fixture)}`);
|
||||||
|
|
||||||
|
if (isTypeUnderTest && typename) {
|
||||||
|
t.is(is(fixture), typename);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
test('is', t => {
|
|
||||||
t.is(is(null), 'null');
|
|
||||||
t.is(is(undefined), 'undefined');
|
|
||||||
|
|
||||||
// TODO: Expand this to all the supported types. Maybe reuse `testType()` somehow.
|
|
||||||
});
|
|
||||||
|
|
||||||
test('is.undefined', t => {
|
test('is.undefined', t => {
|
||||||
testType(t, 'undefined', ['nullOrUndefined']);
|
testType(t, 'undefined', ['nullOrUndefined']);
|
||||||
});
|
});
|
||||||
|
|
@ -753,6 +798,20 @@ test('is.inRange', t => {
|
||||||
test('is.domElement', t => {
|
test('is.domElement', t => {
|
||||||
testType(t, 'domElement');
|
testType(t, 'domElement');
|
||||||
t.false(is.domElement({nodeType: 1, nodeName: 'div'}));
|
t.false(is.domElement({nodeType: 1, nodeName: 'div'}));
|
||||||
|
|
||||||
|
const htmlTagNameToTypeName = {
|
||||||
|
div: 'HTMLDivElement',
|
||||||
|
input: 'HTMLInputElement',
|
||||||
|
span: 'HTMLSpanElement',
|
||||||
|
img: 'HTMLImageElement',
|
||||||
|
canvas: 'HTMLCanvasElement',
|
||||||
|
script: 'HTMLScriptElement'
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const [tagName, typeName] of Object.entries(htmlTagNameToTypeName)) {
|
||||||
|
const domElement = createDomElement(tagName);
|
||||||
|
t.is(is(domElement), typeName);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('is.observable', t => {
|
test('is.observable', t => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue