diff --git a/source/index.ts b/source/index.ts index 8898f1f..3dd5347 100644 --- a/source/index.ts +++ b/source/index.ts @@ -43,7 +43,7 @@ export interface Ow extends Modifiers, Predicates { @param predicate - Predicate used in the validator function. */ - create(predicate: BasePredicate): (value: T) => void; + create(predicate: BasePredicate): ReusableValidator; /** Create a reusable validator. @@ -51,7 +51,21 @@ export interface Ow extends Modifiers, Predicates { @param label - Label which should be used in error messages. @param predicate - Predicate used in the validator function. */ - create(label: string, predicate: BasePredicate): (value: T) => void; + create(label: string, predicate: BasePredicate): ReusableValidator; +} + +/** +A reusable validator. +*/ +export interface ReusableValidator { + /** + Test if the value matches the predicate. Throws an `ArgumentError` if the test fails. + + @param value - Value to test. + @param label - Override the label which should be used in error messages. + */ + // eslint-disable-next-line @typescript-eslint/prefer-function-type + (value: T, label?: string): void; } const ow = (value: T, labelOrPredicate: unknown, predicate?: BasePredicate) => { @@ -83,16 +97,16 @@ Object.defineProperties(ow, { } }, create: { - value: (labelOrPredicate: BasePredicate | string | undefined, predicate?: BasePredicate) => (value: T) => { + value: (labelOrPredicate: BasePredicate | string | undefined, predicate?: BasePredicate) => (value: T, label?: string) => { if (isPredicate(labelOrPredicate)) { const stackFrames = callsites(); - test(value, () => inferLabel(stackFrames), labelOrPredicate); + test(value, label ?? (() => inferLabel(stackFrames)), labelOrPredicate); return; } - test(value, labelOrPredicate as string, predicate as BasePredicate); + test(value, label ?? (labelOrPredicate as string), predicate as BasePredicate); } } }); @@ -111,6 +125,9 @@ export { WeakMapPredicate, SetPredicate, WeakSetPredicate, + TypedArrayPredicate, + ArrayBufferPredicate, + DataViewPredicate, AnyPredicate, Shape } from './predicates'; diff --git a/source/predicates.ts b/source/predicates.ts index 22f3785..17fb456 100644 --- a/source/predicates.ts +++ b/source/predicates.ts @@ -11,6 +11,9 @@ import {MapPredicate} from './predicates/map'; import {WeakMapPredicate} from './predicates/weak-map'; import {SetPredicate} from './predicates/set'; import {WeakSetPredicate} from './predicates/weak-set'; +import {TypedArrayPredicate} from './predicates/typed-array'; +import {ArrayBufferPredicate} from './predicates/array-buffer'; +import {DataViewPredicate} from './predicates/data-view'; import {BasePredicate} from './predicates/base-predicate'; import {AnyPredicate} from './predicates/any'; @@ -118,62 +121,67 @@ export interface Predicates { /** Test the value to be a typed array. */ - readonly typedArray: Predicate; + readonly typedArray: TypedArrayPredicate; /** Test the value to be a Int8Array. */ - readonly int8Array: Predicate; + readonly int8Array: TypedArrayPredicate; /** Test the value to be a Uint8Array. */ - readonly uint8Array: Predicate; + readonly uint8Array: TypedArrayPredicate; /** Test the value to be a Uint8ClampedArray. */ - readonly uint8ClampedArray: Predicate; + readonly uint8ClampedArray: TypedArrayPredicate; /** Test the value to be a Int16Array. */ - readonly int16Array: Predicate; + readonly int16Array: TypedArrayPredicate; /** Test the value to be a Uint16Array. */ - readonly uint16Array: Predicate; + readonly uint16Array: TypedArrayPredicate; /** Test the value to be a Int32Array. */ - readonly int32Array: Predicate; + readonly int32Array: TypedArrayPredicate; /** Test the value to be a Uint32Array. */ - readonly uint32Array: Predicate; + readonly uint32Array: TypedArrayPredicate; /** Test the value to be a Float32Array. */ - readonly float32Array: Predicate; + readonly float32Array: TypedArrayPredicate; /** Test the value to be a Float64Array. */ - readonly float64Array: Predicate; + readonly float64Array: TypedArrayPredicate; /** Test the value to be a ArrayBuffer. */ - readonly arrayBuffer: Predicate; + readonly arrayBuffer: ArrayBufferPredicate; + + /** + Test the value to be a SharedArrayBuffer. + */ + readonly sharedArrayBuffer: ArrayBufferPredicate; /** Test the value to be a DataView. */ - readonly dataView: Predicate; + readonly dataView: DataViewPredicate; /** Test the value to be Iterable. @@ -259,40 +267,43 @@ export default (object: T, options?: PredicateOptions): T & Predicates => { get: () => new Predicate('Promise', options) }, typedArray: { - get: () => new Predicate('TypedArray', options) + get: () => new TypedArrayPredicate('TypedArray', options) }, int8Array: { - get: () => new Predicate('Int8Array', options) + get: () => new TypedArrayPredicate('Int8Array', options) }, uint8Array: { - get: () => new Predicate('Uint8Array', options) + get: () => new TypedArrayPredicate('Uint8Array', options) }, uint8ClampedArray: { - get: () => new Predicate('Uint8ClampedArray', options) + get: () => new TypedArrayPredicate('Uint8ClampedArray', options) }, int16Array: { - get: () => new Predicate('Int16Array', options) + get: () => new TypedArrayPredicate('Int16Array', options) }, uint16Array: { - get: () => new Predicate('Uint16Array', options) + get: () => new TypedArrayPredicate('Uint16Array', options) }, int32Array: { - get: () => new Predicate('Int32Array', options) + get: () => new TypedArrayPredicate('Int32Array', options) }, uint32Array: { - get: () => new Predicate('Uint32Array', options) + get: () => new TypedArrayPredicate('Uint32Array', options) }, float32Array: { - get: () => new Predicate('Float32Array', options) + get: () => new TypedArrayPredicate('Float32Array', options) }, float64Array: { - get: () => new Predicate('Float64Array', options) + get: () => new TypedArrayPredicate('Float64Array', options) }, arrayBuffer: { - get: () => new Predicate('ArrayBuffer', options) + get: () => new ArrayBufferPredicate('ArrayBuffer', options) + }, + sharedArrayBuffer: { + get: () => new ArrayBufferPredicate('SharedArrayBuffer', options) }, dataView: { - get: () => new Predicate('DataView', options) + get: () => new DataViewPredicate(options) }, iterable: { get: () => new Predicate('Iterable', options) @@ -317,6 +328,9 @@ export { WeakMapPredicate, SetPredicate, WeakSetPredicate, + TypedArrayPredicate, + ArrayBufferPredicate, + DataViewPredicate, AnyPredicate, Shape }; diff --git a/source/predicates/array-buffer.ts b/source/predicates/array-buffer.ts new file mode 100644 index 0000000..01b97d3 --- /dev/null +++ b/source/predicates/array-buffer.ts @@ -0,0 +1,41 @@ +import {Predicate} from './predicate'; + +export class ArrayBufferPredicate extends Predicate { + /** + Test an array buffer to have a specific byte length. + + @param byteLength - The byte length of the array buffer. + */ + byteLength(byteLength: number) { + return this.addValidator({ + message: (value, label) => `Expected ${label} to have byte length of \`${byteLength}\`, got \`${value.byteLength}\``, + validator: value => value.byteLength === byteLength + }); + } + + /** + Test an array buffer to have a minimum byte length. + + @param byteLength - The minimum byte length of the array buffer. + */ + minByteLength(byteLength: number) { + return this.addValidator({ + message: (value, label) => `Expected ${label} to have a minimum byte length of \`${byteLength}\`, got \`${value.byteLength}\``, + validator: value => value.byteLength >= byteLength, + negatedMessage: (value, label) => `Expected ${label} to have a maximum byte length of \`${byteLength - 1}\`, got \`${value.byteLength}\`` + }); + } + + /** + Test an array buffer to have a minimum byte length. + + @param length - The minimum byte length of the array buffer. + */ + maxByteLength(byteLength: number) { + return this.addValidator({ + message: (value, label) => `Expected ${label} to have a maximum byte length of \`${byteLength}\`, got \`${value.byteLength}\``, + validator: value => value.byteLength <= byteLength, + negatedMessage: (value, label) => `Expected ${label} to have a minimum byte length of \`${byteLength + 1}\`, got \`${value.byteLength}\`` + }); + } +} diff --git a/source/predicates/data-view.ts b/source/predicates/data-view.ts new file mode 100644 index 0000000..181a0e4 --- /dev/null +++ b/source/predicates/data-view.ts @@ -0,0 +1,48 @@ +import {Predicate, PredicateOptions} from './predicate'; + +export class DataViewPredicate extends Predicate { + /** + @hidden + */ + constructor(options?: PredicateOptions) { + super('DataView', options); + } + + /** + Test a DataView to have a specific byte length. + + @param byteLength - The byte length of the DataView. + */ + byteLength(byteLength: number) { + return this.addValidator({ + message: (value, label) => `Expected ${label} to have byte length of \`${byteLength}\`, got \`${value.byteLength}\``, + validator: value => value.byteLength === byteLength + }); + } + + /** + Test a DataView to have a minimum byte length. + + @param byteLength - The minimum byte length of the DataView. + */ + minByteLength(byteLength: number) { + return this.addValidator({ + message: (value, label) => `Expected ${label} to have a minimum byte length of \`${byteLength}\`, got \`${value.byteLength}\``, + validator: value => value.byteLength >= byteLength, + negatedMessage: (value, label) => `Expected ${label} to have a maximum byte length of \`${byteLength - 1}\`, got \`${value.byteLength}\`` + }); + } + + /** + Test a DataView to have a minimum byte length. + + @param length - The minimum byte length of the DataView. + */ + maxByteLength(byteLength: number) { + return this.addValidator({ + message: (value, label) => `Expected ${label} to have a maximum byte length of \`${byteLength}\`, got \`${value.byteLength}\``, + validator: value => value.byteLength <= byteLength, + negatedMessage: (value, label) => `Expected ${label} to have a minimum byte length of \`${byteLength + 1}\`, got \`${value.byteLength}\`` + }); + } +} diff --git a/source/predicates/typed-array.ts b/source/predicates/typed-array.ts new file mode 100644 index 0000000..432b426 --- /dev/null +++ b/source/predicates/typed-array.ts @@ -0,0 +1,80 @@ +import {TypedArray} from 'type-fest'; +import {Predicate} from './predicate'; + +export class TypedArrayPredicate extends Predicate { + /** + Test a typed array to have a specific byte length. + + @param byteLength - The byte length of the typed array. + */ + byteLength(byteLength: number) { + return this.addValidator({ + message: (value, label) => `Expected ${label} to have byte length of \`${byteLength}\`, got \`${value.byteLength}\``, + validator: value => value.byteLength === byteLength + }); + } + + /** + Test a typed array to have a minimum byte length. + + @param byteLength - The minimum byte length of the typed array. + */ + minByteLength(byteLength: number) { + return this.addValidator({ + message: (value, label) => `Expected ${label} to have a minimum byte length of \`${byteLength}\`, got \`${value.byteLength}\``, + validator: value => value.byteLength >= byteLength, + negatedMessage: (value, label) => `Expected ${label} to have a maximum byte length of \`${byteLength - 1}\`, got \`${value.byteLength}\`` + }); + } + + /** + Test a typed array to have a minimum byte length. + + @param length - The minimum byte length of the typed array. + */ + maxByteLength(byteLength: number) { + return this.addValidator({ + message: (value, label) => `Expected ${label} to have a maximum byte length of \`${byteLength}\`, got \`${value.byteLength}\``, + validator: value => value.byteLength <= byteLength, + negatedMessage: (value, label) => `Expected ${label} to have a minimum byte length of \`${byteLength + 1}\`, got \`${value.byteLength}\`` + }); + } + + /** + Test a typed array to have a specific length. + + @param length - The length of the typed array. + */ + length(length: number) { + return this.addValidator({ + message: (value, label) => `Expected ${label} to have length \`${length}\`, got \`${value.length}\``, + validator: value => value.length === length + }); + } + + /** + Test a typed array to have a minimum length. + + @param length - The minimum length of the typed array. + */ + minLength(length: number) { + return this.addValidator({ + message: (value, label) => `Expected ${label} to have a minimum length of \`${length}\`, got \`${value.length}\``, + validator: value => value.length >= length, + negatedMessage: (value, label) => `Expected ${label} to have a maximum length of \`${length - 1}\`, got \`${value.length}\`` + }); + } + + /** + Test a typed array to have a maximum length. + + @param length - The maximum length of the typed array. + */ + maxLength(length: number) { + return this.addValidator({ + message: (value, label) => `Expected ${label} to have a maximum length of \`${length}\`, got \`${value.length}\``, + validator: value => value.length <= length, + negatedMessage: (value, label) => `Expected ${label} to have a minimum length of \`${length + 1}\`, got \`${value.length}\`` + }); + } +} diff --git a/test/array-buffer.ts b/test/array-buffer.ts index 53375dd..f6df01d 100644 --- a/test/array-buffer.ts +++ b/test/array-buffer.ts @@ -22,3 +22,49 @@ test('arrayBuffer', t => { ow(12 as any, ow.arrayBuffer); }, 'Expected argument to be of type `ArrayBuffer` but received type `number`'); }); + +test('arrayBuffer.byteLength', t => { + t.notThrows(() => { + ow(new ArrayBuffer(1), ow.arrayBuffer.byteLength(1)); + }); + + t.notThrows(() => { + ow(new ArrayBuffer(2), ow.arrayBuffer.byteLength(2)); + }); + + t.throws(() => { + ow(new ArrayBuffer(1), ow.arrayBuffer.byteLength(2)); + }, 'Expected ArrayBuffer to have byte length of `2`, got `1`'); + + t.throws(() => { + ow(new ArrayBuffer(1), 'foo', ow.arrayBuffer.byteLength(2)); + }, 'Expected ArrayBuffer `foo` to have byte length of `2`, got `1`'); +}); + +test('arrayBuffer.minByteLength', t => { + t.notThrows(() => { + ow(new ArrayBuffer(1), ow.arrayBuffer.minByteLength(1)); + }); + + t.notThrows(() => { + ow(new ArrayBuffer(2), ow.arrayBuffer.minByteLength(1)); + }); + + t.throws(() => { + ow(new ArrayBuffer(1), ow.arrayBuffer.minByteLength(2)); + }, 'Expected ArrayBuffer to have a minimum byte length of `2`, got `1`'); +}); + +test('arrayBuffer.maxByteLength', t => { + t.notThrows(() => { + ow(new ArrayBuffer(1), ow.arrayBuffer.maxByteLength(1)); + }); + + t.notThrows(() => { + ow(new ArrayBuffer(2), ow.arrayBuffer.maxByteLength(4)); + }); + + t.throws(() => { + ow(new ArrayBuffer(2), ow.arrayBuffer.maxByteLength(1)); + }, 'Expected ArrayBuffer to have a maximum byte length of `1`, got `2`'); +}); diff --git a/test/data-view.ts b/test/data-view.ts index 9c215fd..da71cea 100644 --- a/test/data-view.ts +++ b/test/data-view.ts @@ -18,3 +18,49 @@ test('dataView', t => { ow(12 as any, ow.dataView); }, 'Expected argument to be of type `DataView` but received type `number`'); }); + +test('dataView.byteLength', t => { + t.notThrows(() => { + ow(new DataView(new ArrayBuffer(1)), ow.dataView.byteLength(1)); + }); + + t.notThrows(() => { + ow(new DataView(new ArrayBuffer(2)), ow.dataView.byteLength(2)); + }); + + t.throws(() => { + ow(new DataView(new ArrayBuffer(1)), ow.dataView.byteLength(2)); + }, 'Expected DataView to have byte length of `2`, got `1`'); + + t.throws(() => { + ow(new DataView(new ArrayBuffer(1)), 'foo', ow.dataView.byteLength(2)); + }, 'Expected DataView `foo` to have byte length of `2`, got `1`'); +}); + +test('dataView.minByteLength', t => { + t.notThrows(() => { + ow(new DataView(new ArrayBuffer(1)), ow.dataView.minByteLength(1)); + }); + + t.notThrows(() => { + ow(new DataView(new ArrayBuffer(2)), ow.dataView.minByteLength(1)); + }); + + t.throws(() => { + ow(new DataView(new ArrayBuffer(1)), ow.dataView.minByteLength(2)); + }, 'Expected DataView to have a minimum byte length of `2`, got `1`'); +}); + +test('dataView.maxByteLength', t => { + t.notThrows(() => { + ow(new DataView(new ArrayBuffer(1)), ow.dataView.maxByteLength(1)); + }); + + t.notThrows(() => { + ow(new DataView(new ArrayBuffer(2)), ow.dataView.maxByteLength(4)); + }); + + t.throws(() => { + ow(new DataView(new ArrayBuffer(2)), ow.dataView.maxByteLength(1)); + }, 'Expected DataView to have a maximum byte length of `1`, got `2`'); +}); diff --git a/test/test.ts b/test/test.ts index af09686..c39b2cb 100644 --- a/test/test.ts +++ b/test/test.ts @@ -160,6 +160,86 @@ test('not', t => { t.throws(() => { ow([1], ow.array.not.maxLength(3)); }, 'Expected array to have a minimum length of `4`, got `1`'); + + t.notThrows(() => { + ow(new Int8Array(1), ow.typedArray.not.minByteLength(3)); + }); + t.notThrows(() => { + ow(new Int8Array(2), ow.typedArray.not.minByteLength(3)); + }); + t.throws(() => { + ow(new Int8Array(3), ow.typedArray.not.minByteLength(3)); + }, 'Expected TypedArray to have a maximum byte length of `2`, got `3`'); + + t.notThrows(() => { + ow(new Uint8Array(4), ow.typedArray.not.maxByteLength(2)); + }); + t.notThrows(() => { + ow(new Uint8Array(3), ow.typedArray.not.maxByteLength(2)); + }); + t.throws(() => { + ow(new Uint8Array(2), ow.typedArray.not.maxByteLength(2)); + }, 'Expected TypedArray to have a minimum byte length of `3`, got `2`'); + + t.notThrows(() => { + ow(new Uint8ClampedArray(1), ow.typedArray.not.minLength(3)); + }); + t.notThrows(() => { + ow(new Int16Array(2), ow.typedArray.not.minLength(3)); + }); + t.throws(() => { + ow(new Float32Array(3), ow.typedArray.not.minLength(3)); + }, 'Expected TypedArray to have a maximum length of `2`, got `3`'); + + t.notThrows(() => { + ow(new Uint16Array(4), ow.typedArray.not.maxLength(2)); + }); + t.notThrows(() => { + ow(new Uint32Array(3), ow.typedArray.not.maxLength(2)); + }); + t.throws(() => { + ow(new Float64Array(2), ow.typedArray.not.maxLength(2)); + }, 'Expected TypedArray to have a minimum length of `3`, got `2`'); + + t.notThrows(() => { + ow(new ArrayBuffer(1), ow.arrayBuffer.not.minByteLength(3)); + }); + t.notThrows(() => { + ow(new ArrayBuffer(2), ow.arrayBuffer.not.minByteLength(3)); + }); + t.throws(() => { + ow(new ArrayBuffer(3), ow.arrayBuffer.not.minByteLength(3)); + }, 'Expected ArrayBuffer to have a maximum byte length of `2`, got `3`'); + + t.notThrows(() => { + ow(new ArrayBuffer(4), ow.arrayBuffer.not.maxByteLength(2)); + }); + t.notThrows(() => { + ow(new ArrayBuffer(3), ow.arrayBuffer.not.maxByteLength(2)); + }); + t.throws(() => { + ow(new ArrayBuffer(2), ow.arrayBuffer.not.maxByteLength(2)); + }, 'Expected ArrayBuffer to have a minimum byte length of `3`, got `2`'); + + t.notThrows(() => { + ow(new DataView(new ArrayBuffer(1)), ow.dataView.not.minByteLength(3)); + }); + t.notThrows(() => { + ow(new DataView(new ArrayBuffer(2)), ow.dataView.not.minByteLength(3)); + }); + t.throws(() => { + ow(new DataView(new ArrayBuffer(3)), ow.dataView.not.minByteLength(3)); + }, 'Expected DataView to have a maximum byte length of `2`, got `3`'); + + t.notThrows(() => { + ow(new DataView(new ArrayBuffer(4)), ow.dataView.not.maxByteLength(2)); + }); + t.notThrows(() => { + ow(new DataView(new ArrayBuffer(3)), ow.dataView.not.maxByteLength(2)); + }); + t.throws(() => { + ow(new DataView(new ArrayBuffer(2)), ow.dataView.not.maxByteLength(2)); + }, 'Expected DataView to have a minimum byte length of `3`, got `2`'); }); test('is', t => { @@ -225,6 +305,33 @@ test('reusable validator', t => { }, 'Expected argument to be of type `string` but received type `number`'); }); +test('reusable validator called with label', t => { + const checkUsername = ow.create(ow.string.minLength(3)); + + const value = 'x'; + const label = 'bar'; + + t.notThrows(() => { + checkUsername('foo', label); + }); + + t.notThrows(() => { + checkUsername('foobar', label); + }); + + t.throws(() => { + checkUsername('fo', label); + }, 'Expected string `bar` to have a minimum length of `3`, got `fo`'); + + t.throws(() => { + checkUsername(value, label); + }, 'Expected string `bar` to have a minimum length of `3`, got `x`'); + + t.throws(() => { + checkUsername(5 as any, label); + }, 'Expected `bar` to be of type `string` but received type `number`'); +}); + test('reusable validator with label', t => { const checkUsername = ow.create('foo', ow.string.minLength(3)); @@ -245,6 +352,28 @@ test('reusable validator with label', t => { }, 'Expected `foo` to be of type `string` but received type `number`'); }); +test('reusable validator with label called with label', t => { + const checkUsername = ow.create('foo', ow.string.minLength(3)); + + const label = 'bar'; + + t.notThrows(() => { + checkUsername('foo', label); + }); + + t.notThrows(() => { + checkUsername('foobar', label); + }); + + t.throws(() => { + checkUsername('fo', label); + }, 'Expected string `bar` to have a minimum length of `3`, got `fo`'); + + t.throws(() => { + checkUsername(5 as any, label); + }, 'Expected `bar` to be of type `string` but received type `number`'); +}); + test('any-reusable validator', t => { const checkUsername = ow.create(ow.any(ow.string.includes('.'), ow.string.minLength(3))); diff --git a/test/typed-array.ts b/test/typed-array.ts index 503f14b..11bf804 100644 --- a/test/typed-array.ts +++ b/test/typed-array.ts @@ -31,6 +31,128 @@ test('typedArray', t => { }, 'Expected argument to be of type `TypedArray` but received type `number`'); }); +test('typedArray.byteLength', t => { + t.notThrows(() => { + ow(new Int8Array(1), ow.typedArray.byteLength(1)); + }); + + t.notThrows(() => { + ow(new Uint8Array(1), ow.typedArray.byteLength(1)); + }); + + t.notThrows(() => { + ow(new Uint8ClampedArray(1), ow.typedArray.byteLength(1)); + }); + + t.notThrows(() => { + ow(new Int16Array(1), ow.typedArray.byteLength(2)); + }); + + t.notThrows(() => { + ow(new Uint16Array(1), ow.typedArray.byteLength(2)); + }); + + t.notThrows(() => { + ow(new Int32Array(1), ow.typedArray.byteLength(4)); + }); + + t.notThrows(() => { + ow(new Uint32Array(1), ow.typedArray.byteLength(4)); + }); + + t.notThrows(() => { + ow(new Float32Array(1), ow.typedArray.byteLength(4)); + }); + + t.notThrows(() => { + ow(new Float64Array(1), ow.typedArray.byteLength(8)); + }); + + t.throws(() => { + ow(new Int8Array(1), ow.typedArray.byteLength(2)); + }, 'Expected TypedArray to have byte length of `2`, got `1`'); + + t.throws(() => { + ow(new Int8Array(1), 'foo', ow.typedArray.byteLength(2)); + }, 'Expected TypedArray `foo` to have byte length of `2`, got `1`'); +}); + +test('typedArray.minByteLength', t => { + t.notThrows(() => { + ow(new Int8Array(1), ow.typedArray.minByteLength(1)); + }); + + t.notThrows(() => { + ow(new Float64Array(2), ow.typedArray.minByteLength(1)); + }); + + t.throws(() => { + ow(new Uint8Array(1), ow.typedArray.minByteLength(2)); + }, 'Expected TypedArray to have a minimum byte length of `2`, got `1`'); +}); + +test('typedArray.maxByteLength', t => { + t.notThrows(() => { + ow(new Uint8Array(1), ow.typedArray.maxByteLength(1)); + }); + + t.notThrows(() => { + ow(new Int16Array(1), ow.typedArray.maxByteLength(4)); + }); + + t.throws(() => { + ow(new Uint32Array(1), ow.typedArray.maxByteLength(1)); + }, 'Expected TypedArray to have a maximum byte length of `1`, got `4`'); +}); + +test('typedArray.length', t => { + t.notThrows(() => { + t.notThrows(() => { + ow(new Int8Array(1), ow.typedArray.length(1)); + }); + + t.notThrows(() => { + ow(new Uint16Array(2), ow.typedArray.length(2)); + }); + + t.throws(() => { + ow(new Float32Array(1), ow.typedArray.length(2)); + }, 'Expected TypedArray to have length `2`, got `1`'); + + t.throws(() => { + ow(new Float32Array(1), 'foo', ow.typedArray.length(2)); + }, 'Expected TypedArray `foo` to have length `2`, got `1`'); + }); +}); + +test('typedArray.minLength', t => { + t.notThrows(() => { + ow(new Uint8Array(1), ow.typedArray.minLength(1)); + }); + + t.notThrows(() => { + ow(new Int16Array(2), ow.typedArray.minLength(1)); + }); + + t.throws(() => { + ow(new Uint32Array(1), ow.typedArray.minLength(2)); + }, 'Expected TypedArray to have a minimum length of `2`, got `1`'); +}); + +test('typedArray.maxLength', t => { + t.notThrows(() => { + ow(new Uint8ClampedArray(1), ow.typedArray.maxLength(1)); + }); + + t.notThrows(() => { + ow(new Int32Array(2), ow.typedArray.maxLength(4)); + }); + + t.throws(() => { + ow(new Float64Array(2), ow.typedArray.maxLength(1)); + }, 'Expected TypedArray to have a maximum length of `1`, got `2`'); +}); + test('int8Array', t => { t.notThrows(() => { ow(new Int8Array(2), ow.int8Array);