diff --git a/README.md b/README.md index 1adb5273..94d623f6 100644 --- a/README.md +++ b/README.md @@ -425,17 +425,17 @@ s.function([s.string, s.number], s.string); // (arg0: string, arg1: number) => s ```ts const typedArray = s.typedArray(); -const i8Array = s.i8Array; -const u8Array = s.u8Array; -const u8clampedArray = s.u8clampedArray; -const i16Array = s.i16Array; -const u16Array = s.u16Array; -const i32Array = s.i32Array; -const u32Array = s.u32Array; -const f32Array = s.f32Array; -const f64Array = s.f64Array; -const i64Array = s.i64Array; -const u64Array = s.u64Array; +const int16Array = s.int16Array; +const uint16Array = s.uint16Array; +const uint8ClampedArray = s.uint8ClampedArray; +const int16ArrayArray = s.int16ArrayArray; +const uint16ArrayArray = s.uint16ArrayArray; +const int32ArrayArray = s.int32ArrayArray; +const uint32ArrayArray = s.uint32ArrayArray; +const float32ArrayArray = s.float32ArrayArray; +const float64ArrayArray = s.float64ArrayArray; +const bigInt64ArrayArray = s.bigInt64ArrayArray; +const bigUint64ArrayArray = s.bigUint64ArrayArray; ``` ShapeShift includes a handful of validations specific to typed arrays. diff --git a/src/constraints/util/common/vowels.ts b/src/constraints/util/common/vowels.ts new file mode 100644 index 00000000..91717981 --- /dev/null +++ b/src/constraints/util/common/vowels.ts @@ -0,0 +1,5 @@ +const vowels = ['a', 'e', 'i', 'o', 'u']; + +export const aOrAn = (word: string) => { + return `${vowels.includes(word[0].toLowerCase()) ? 'an' : 'a'} ${word}`; +}; diff --git a/src/constraints/util/typedArray.ts b/src/constraints/util/typedArray.ts index b864735e..729d9509 100644 --- a/src/constraints/util/typedArray.ts +++ b/src/constraints/util/typedArray.ts @@ -12,17 +12,17 @@ export type TypedArray = | BigUint64Array; export const TypedArrays = { - i8Array: (x: unknown): x is Int8Array => x instanceof Int8Array, - u8Array: (x: unknown): x is Uint8Array => x instanceof Uint8Array, - u8clampedArray: (x: unknown): x is Uint8ClampedArray => x instanceof Uint8ClampedArray, - i16Array: (x: unknown): x is Int16Array => x instanceof Int16Array, - u16Array: (x: unknown): x is Uint16Array => x instanceof Uint16Array, - i32Array: (x: unknown): x is Int32Array => x instanceof Int32Array, - u32Array: (x: unknown): x is Uint32Array => x instanceof Uint32Array, - f32Array: (x: unknown): x is Float32Array => x instanceof Float32Array, - f64Array: (x: unknown): x is Float64Array => x instanceof Float64Array, - i64Array: (x: unknown): x is BigInt64Array => x instanceof BigInt64Array, - u64Array: (x: unknown): x is BigUint64Array => x instanceof BigUint64Array, + Int8Array: (x: unknown): x is Int8Array => x instanceof Int8Array, + Uint8Array: (x: unknown): x is Uint8Array => x instanceof Uint8Array, + Uint8ClampedArray: (x: unknown): x is Uint8ClampedArray => x instanceof Uint8ClampedArray, + Int16Array: (x: unknown): x is Int16Array => x instanceof Int16Array, + Uint16Array: (x: unknown): x is Uint16Array => x instanceof Uint16Array, + Int32Array: (x: unknown): x is Int32Array => x instanceof Int32Array, + Uint32Array: (x: unknown): x is Uint32Array => x instanceof Uint32Array, + Float32Array: (x: unknown): x is Float32Array => x instanceof Float32Array, + Float64Array: (x: unknown): x is Float64Array => x instanceof Float64Array, + BigInt64Array: (x: unknown): x is BigInt64Array => x instanceof BigInt64Array, + BigUint64Array: (x: unknown): x is BigUint64Array => x instanceof BigUint64Array, TypedArray: (x: unknown): x is TypedArray => ArrayBuffer.isView(x) && !(x instanceof DataView) } as const; diff --git a/src/lib/Shapes.ts b/src/lib/Shapes.ts index df7de486..ec8c03ff 100644 --- a/src/lib/Shapes.ts +++ b/src/lib/Shapes.ts @@ -101,48 +101,48 @@ export class Shapes { return new TypedArrayValidator(type); } - public get i8Array() { - return this.typedArray('i8Array'); + public get int8Array() { + return this.typedArray('Int8Array'); } - public get u8Array() { - return this.typedArray('u8Array'); + public get uint8Array() { + return this.typedArray('Uint8Array'); } - public get u8clampedArray() { - return this.typedArray('u8clampedArray'); + public get uint8ClampedArray() { + return this.typedArray('Uint8ClampedArray'); } - public get i16Array() { - return this.typedArray('i16Array'); + public get int16Array() { + return this.typedArray('Int16Array'); } - public get u16Array() { - return this.typedArray('u16Array'); + public get uint16Array() { + return this.typedArray('Uint16Array'); } - public get i32Array() { - return this.typedArray('i32Array'); + public get int32Array() { + return this.typedArray('Int32Array'); } - public get u32Array() { - return this.typedArray('u32Array'); + public get uint32Array() { + return this.typedArray('Uint32Array'); } - public get f32Array() { - return this.typedArray('f32Array'); + public get float32Array() { + return this.typedArray('Float32Array'); } - public get f64Array() { - return this.typedArray('f64Array'); + public get float64Array() { + return this.typedArray('Float64Array'); } - public get i64Array() { - return this.typedArray('i64Array'); + public get bigInt64Array() { + return this.typedArray('BigInt64Array'); } - public get u64Array() { - return this.typedArray('u64Array'); + public get bigUint64Array() { + return this.typedArray('BigUint64Array'); } public tuple[]]>(validators: [...T]): TupleValidator> { diff --git a/src/validators/TypedArrayValidator.ts b/src/validators/TypedArrayValidator.ts index 39b01163..08289758 100644 --- a/src/validators/TypedArrayValidator.ts +++ b/src/validators/TypedArrayValidator.ts @@ -23,6 +23,7 @@ import { ValidationError } from '../lib/errors/ValidationError'; import { Result } from '../lib/Result'; import { BaseValidator } from './imports'; import { TypedArray, TypedArrayName, TypedArrays } from '../constraints/util/typedArray'; +import { aOrAn } from '../constraints/util/common/vowels'; export class TypedArrayValidator extends BaseValidator { private readonly type: TypedArrayName; @@ -111,6 +112,6 @@ export class TypedArrayValidator extends BaseValidator protected handle(value: unknown): Result { return TypedArrays[this.type](value) ? Result.ok(value as T) - : Result.err(new ValidationError('s.typedArray', `Expected an ${this.type}`, value)); + : Result.err(new ValidationError('s.typedArray', `Expected ${aOrAn(this.type)}`, value)); } } diff --git a/tests/validators/typedArray.test.ts b/tests/validators/typedArray.test.ts index dd0a3e1d..271a355f 100644 --- a/tests/validators/typedArray.test.ts +++ b/tests/validators/typedArray.test.ts @@ -22,12 +22,12 @@ describe('TypedArray', () => { }); test.each([1, true, 'sapphire'])('GIVEN %p THEN throw', (input) => { - expect(() => predicate.parse(input)).toThrow(new ValidationError('s.typedArray', `Expected an TypedArray`, input)); + expect(() => predicate.parse(input)).toThrow(new ValidationError('s.typedArray', `Expected a TypedArray`, input)); }); }); - describe('i8', () => { - const predicate = s.i8Array; + describe('Int8Array', () => { + const predicate = s.int8Array; test('GIVEN typed array THEN return the input', () => { const typedArray = new Int8Array(); @@ -35,12 +35,12 @@ describe('TypedArray', () => { }); test.each([1, true, 'sapphire', new Int16Array()])('GIVEN %p THEN throw', (input) => { - expect(() => predicate.parse(input)).toThrow(new ValidationError('s.typedArray', `Expected an i8Array`, input)); + expect(() => predicate.parse(input)).toThrow(new ValidationError('s.typedArray', `Expected an Int8Array`, input)); }); }); - describe('u8', () => { - const predicate = s.u8Array; + describe('Uint8Array', () => { + const predicate = s.uint8Array; test('GIVEN typed array THEN return the input', () => { const typedArray = new Uint8Array(); @@ -48,12 +48,12 @@ describe('TypedArray', () => { }); test.each([1, true, 'sapphire', new Uint16Array()])('GIVEN %p THEN throw', (input) => { - expect(() => predicate.parse(input)).toThrow(new ValidationError('s.typedArray', `Expected an u8Array`, input)); + expect(() => predicate.parse(input)).toThrow(new ValidationError('s.typedArray', `Expected an Uint8Array`, input)); }); }); - describe('u8clamped', () => { - const predicate = s.u8clampedArray; + describe('Uint8ClampedArray', () => { + const predicate = s.uint8ClampedArray; test('GIVEN typed array THEN return the input', () => { const typedArray = new Uint8ClampedArray(); @@ -61,12 +61,12 @@ describe('TypedArray', () => { }); test.each([1, true, 'sapphire', new Uint16Array()])('GIVEN %p THEN throw', (input) => { - expect(() => predicate.parse(input)).toThrow(new ValidationError('s.typedArray', `Expected an u8clampedArray`, input)); + expect(() => predicate.parse(input)).toThrow(new ValidationError('s.typedArray', `Expected an Uint8ClampedArray`, input)); }); }); - describe('i16', () => { - const predicate = s.i16Array; + describe('Int16Array', () => { + const predicate = s.int16Array; test('GIVEN typed array THEN return the input', () => { const typedArray = new Int16Array(); @@ -74,12 +74,12 @@ describe('TypedArray', () => { }); test.each([1, true, 'sapphire', new Int32Array()])('GIVEN %p THEN throw', (input) => { - expect(() => predicate.parse(input)).toThrow(new ValidationError('s.typedArray', `Expected an i16Array`, input)); + expect(() => predicate.parse(input)).toThrow(new ValidationError('s.typedArray', `Expected an Int16Array`, input)); }); }); - describe('u16', () => { - const predicate = s.u16Array; + describe('Uint16Array', () => { + const predicate = s.uint16Array; test('GIVEN typed array THEN return the input', () => { const typedArray = new Uint16Array(); @@ -87,12 +87,12 @@ describe('TypedArray', () => { }); test.each([1, true, 'sapphire', new Uint32Array()])('GIVEN %p THEN throw', (input) => { - expect(() => predicate.parse(input)).toThrow(new ValidationError('s.typedArray', `Expected an u16Array`, input)); + expect(() => predicate.parse(input)).toThrow(new ValidationError('s.typedArray', `Expected an Uint16Array`, input)); }); }); - describe('i32', () => { - const predicate = s.i32Array; + describe('Int32Array', () => { + const predicate = s.int32Array; test('GIVEN typed array THEN return the input', () => { const typedArray = new Int32Array(); @@ -100,12 +100,12 @@ describe('TypedArray', () => { }); test.each([1, true, 'sapphire', new Int16Array()])('GIVEN %p THEN throw', (input) => { - expect(() => predicate.parse(input)).toThrow(new ValidationError('s.typedArray', `Expected an i32Array`, input)); + expect(() => predicate.parse(input)).toThrow(new ValidationError('s.typedArray', `Expected an Int32Array`, input)); }); }); - describe('u32', () => { - const predicate = s.u32Array; + describe('Uint32Array', () => { + const predicate = s.uint32Array; test('GIVEN typed array THEN return the input', () => { const typedArray = new Uint32Array(); @@ -113,12 +113,12 @@ describe('TypedArray', () => { }); test.each([1, true, 'sapphire', new Uint16Array()])('GIVEN %p THEN throw', (input) => { - expect(() => predicate.parse(input)).toThrow(new ValidationError('s.typedArray', `Expected an u32Array`, input)); + expect(() => predicate.parse(input)).toThrow(new ValidationError('s.typedArray', `Expected an Uint32Array`, input)); }); }); - describe('f32', () => { - const predicate = s.f32Array; + describe('Float32Array', () => { + const predicate = s.float32Array; test('GIVEN typed array THEN return the input', () => { const typedArray = new Float32Array(); @@ -126,12 +126,12 @@ describe('TypedArray', () => { }); test.each([1, true, 'sapphire', new Float64Array()])('GIVEN %p THEN throw', (input) => { - expect(() => predicate.parse(input)).toThrow(new ValidationError('s.typedArray', `Expected an f32Array`, input)); + expect(() => predicate.parse(input)).toThrow(new ValidationError('s.typedArray', `Expected a Float32Array`, input)); }); }); - describe('f64', () => { - const predicate = s.f64Array; + describe('Float64Array', () => { + const predicate = s.float64Array; test('GIVEN typed array THEN return the input', () => { const typedArray = new Float64Array(); @@ -139,12 +139,12 @@ describe('TypedArray', () => { }); test.each([1, true, 'sapphire'])('GIVEN %p THEN throw', (input) => { - expect(() => predicate.parse(input)).toThrow(new ValidationError('s.typedArray', `Expected an f64Array`, input)); + expect(() => predicate.parse(input)).toThrow(new ValidationError('s.typedArray', `Expected a Float64Array`, input)); }); }); - describe('bi64', () => { - const predicate = s.i64Array; + describe('BigInt64Array', () => { + const predicate = s.bigInt64Array; test('GIVEN typed array THEN return the input', () => { const typedArray = new BigInt64Array(); @@ -152,12 +152,12 @@ describe('TypedArray', () => { }); test.each([1, true, 'sapphire', new BigUint64Array()])('GIVEN %p THEN throw', (input) => { - expect(() => predicate.parse(input)).toThrow(new ValidationError('s.typedArray', `Expected an i64Array`, input)); + expect(() => predicate.parse(input)).toThrow(new ValidationError('s.typedArray', `Expected a BigInt64Array`, input)); }); }); - describe('bu64', () => { - const predicate = s.u64Array; + describe('BigUint64Array', () => { + const predicate = s.bigUint64Array; test('GIVEN typed array THEN return the input', () => { const typedArray = new BigUint64Array(); @@ -165,7 +165,7 @@ describe('TypedArray', () => { }); test.each([1, true, 'sapphire'])('GIVEN %p THEN throw', (input) => { - expect(() => predicate.parse(input)).toThrow(new ValidationError('s.typedArray', `Expected an u64Array`, input)); + expect(() => predicate.parse(input)).toThrow(new ValidationError('s.typedArray', `Expected a BigUint64Array`, input)); }); });