Skip to content

Commit

Permalink
Simplify tests for basic structs
Browse files Browse the repository at this point in the history
  • Loading branch information
yeoffrey committed Jul 30, 2024
1 parent 0fe23dd commit 93bf438
Show file tree
Hide file tree
Showing 29 changed files with 336 additions and 189 deletions.
25 changes: 25 additions & 0 deletions test/fixtures/fixtures.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { expect, test } from 'vitest'
import { data, fixtures } from './fixtures'

test('Test that picking fixtures works as expected', () => {
const expected = [...data.integers(), ...data.strings(), ...data.functions()]

const actual = fixtures.pick(['integers', 'strings', 'functions'])

expect(JSON.stringify(actual)).toStrictEqual(JSON.stringify(expected))
})

test('Test that omitting fixtures works as expected', () => {
const expected = [
...data.booleans(),
...data.functions(),
...data.nulls(),
...data.undefineds(),
...data.nan(),
...data.floats(),
]

const actual = fixtures.omit(['integers', 'strings'])

expect(JSON.stringify(actual)).toStrictEqual(JSON.stringify(expected))
})
40 changes: 40 additions & 0 deletions test/fixtures/fixtures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { flatMap, omit, pick, values } from 'lodash'

type AllFixtures = {
booleans: () => unknown[]
functions: () => unknown[]
nulls: () => unknown[]
strings: () => unknown[]
undefineds: () => unknown[]
nan: () => unknown[]
floats: () => unknown[]
integers: () => unknown[]
}

export const data: AllFixtures = {
booleans: () => [true, false],
functions: () => [
() => {},
(a: number, b: number) => a + b,
function namedFunction() {},
],
nulls: () => [null],
strings: () => ['Hello', '', '123', 'Special characters: !@#$%^&*()'],
undefineds: () => [undefined],
nan: () => [NaN],
floats: () => [3.14159],
integers: () => [3, -17, 0, Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER],
}

export const fixtures = {
all: (): unknown[] => flatMap(values(data), (value) => value()),

pick: (keys: (keyof AllFixtures)[]): unknown[] =>
flatMap(values(pick(data, keys)), (value) => value()),

omit: (keys: (keyof AllFixtures)[]): unknown[] => {
const arrays: (() => unknown[])[] = values(omit(data, keys))

return flatMap(arrays, (value) => value())
},
}
15 changes: 15 additions & 0 deletions test/structs/any.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { expect, test } from 'vitest'
import { fixtures } from '../fixtures/fixtures'
import { any } from '../../src'

test('Everything is considered valid and returned as anything', () => {
const cases = fixtures.all()

for (const c of cases) {
const [error, result] = any().validate(c)

expect(error).toBeUndefined()
expect(result).toBe(c)
expect(result).toBeTypeOf(typeof c)
}
})
41 changes: 41 additions & 0 deletions test/structs/boolean.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { expect, test } from 'vitest'
import { boolean, StructError } from '../../src'
import { print } from '../../src/utils'
import { fixtures } from '../fixtures/fixtures'

test('Booleans are considered valid and returned as a boolean', () => {
const cases = fixtures.pick(['booleans'])

for (const bool of cases) {
const [error, result] = boolean().validate(bool)

expect(error).toBeUndefined()
expect(result).toBe(bool)
expect(result).toBeTypeOf('boolean')
}
})

test('Non booleans are considered invalid and returned with Error', () => {
const cases = fixtures.omit(['booleans'])

for (const invalidBool of cases) {
const [error, result] = boolean().validate(invalidBool)

expect(result).toBeUndefined()

expect(error).not.toBeUndefined()
expect(error).toBeInstanceOf(StructError)
expect(error?.failures()).toStrictEqual([
{
branch: [invalidBool],
explanation: undefined,
key: undefined,
message: `Expected a value of type \`boolean\`, but received: \`${print(invalidBool)}\``,
path: [],
refinement: undefined,
type: 'boolean',
value: invalidBool,
},
])
}
})
41 changes: 41 additions & 0 deletions test/structs/function.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { expect, test } from 'vitest'
import { func, StructError } from '../../src'
import { print } from '../../src/utils'
import { fixtures } from '../fixtures/fixtures'

test('Functions are considered valid and returned as functions', () => {
const cases = fixtures.pick(['functions'])

for (const f of cases) {
const [error, result] = func().validate(f)

expect(error).toBeUndefined()
expect(result).toBe(f)
expect(f).toBeTypeOf('function')
}
})

test('Non functions are considered invalid and returned with Error', () => {
const cases = fixtures.omit(['functions'])

for (const invalidFunc of cases) {
const [error, result] = func().validate(invalidFunc)

expect(result).toBeUndefined()

expect(error).not.toBeUndefined()
expect(error).toBeInstanceOf(StructError)
expect(error?.failures()).toStrictEqual([
{
branch: [invalidFunc],
explanation: undefined,
key: undefined,
message: `Expected a function, but received: ${print(invalidFunc)}`,
path: [],
refinement: undefined,
type: 'func',
value: invalidFunc,
},
])
}
})
41 changes: 41 additions & 0 deletions test/structs/integer.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { expect, test } from 'vitest'
import { integer, StructError } from '../../src'
import { print } from '../../src/utils'
import { fixtures } from '../fixtures/fixtures'

test('Integers are considered valid and returned as a number', () => {
const cases = fixtures.pick(['integers'])

for (const num of cases) {
const [error, result] = integer().validate(num)

expect(error).toBeUndefined()
expect(result).toBe(num)
expect(result).toBeTypeOf('number')
}
})

test('Non integers are considered invalid and returned with Error', () => {
const cases = fixtures.omit(['integers'])

for (const invalidNum of cases) {
const [error, result] = integer().validate(invalidNum)

expect(result).toBeUndefined()

expect(error).not.toBeUndefined()
expect(error).toBeInstanceOf(StructError)
expect(error?.failures()).toStrictEqual([
{
branch: [invalidNum],
explanation: undefined,
key: undefined,
message: `Expected an integer, but received: ${print(invalidNum)}`,
path: [],
refinement: undefined,
type: 'integer',
value: invalidNum,
},
])
}
})
37 changes: 37 additions & 0 deletions test/structs/literal.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { expect, test } from 'vitest'
import { literal, StructError } from '../../src'
import { print } from '../../src/utils'
import { fixtures } from '../fixtures/fixtures'

test('Literal is only considered valid and returned', () => {
const [error, result] = literal(42).validate(42)

expect(error).toBeUndefined()
expect(result).toBe(42)
expect(result).toBeTypeOf('number')
})

test('Non integers are considered invalid and returned with Error', () => {
const cases = fixtures.all()

for (const invalidLiteral of cases) {
const [error, result] = literal(42).validate(invalidLiteral)

expect(result).toBeUndefined()

expect(error).not.toBeUndefined()
expect(error).toBeInstanceOf(StructError)
expect(error?.failures()).toStrictEqual([
{
branch: [invalidLiteral],
explanation: undefined,
key: undefined,
message: `Expected the literal \`42\`, but received: ${print(invalidLiteral)}`,
path: [],
refinement: undefined,
type: 'literal',
value: invalidLiteral,
},
])
}
})
41 changes: 41 additions & 0 deletions test/structs/number.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { expect, test } from 'vitest'
import { number, StructError } from '../../src'
import { print } from '../../src/utils'
import { fixtures } from '../fixtures/fixtures'

test('Numbers are considered valid and returned as a number', () => {
const cases = fixtures.pick(['floats', 'integers'])

for (const num of cases) {
const [error, result] = number().validate(num)

expect(error).toBeUndefined()
expect(result).toBe(num)
expect(result).toBeTypeOf('number')
}
})

test('Non numbers are considered invalid and returned with Error', () => {
const cases = fixtures.omit(['floats', 'integers'])

for (const invalidNum of cases) {
const [error, result] = number().validate(invalidNum)

expect(result).toBeUndefined()

expect(error).not.toBeUndefined()
expect(error).toBeInstanceOf(StructError)
expect(error?.failures()).toStrictEqual([
{
branch: [invalidNum],
explanation: undefined,
key: undefined,
message: `Expected a number, but received: ${print(invalidNum)}`,
path: [],
refinement: undefined,
type: 'number',
value: invalidNum,
},
])
}
})
41 changes: 41 additions & 0 deletions test/structs/string.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { expect, test } from 'vitest'
import { string, StructError } from '../../src'
import { print } from '../../src/utils'
import { fixtures } from '../fixtures/fixtures'

test('Strings are considered valid and returned as a string', () => {
const cases = fixtures.pick(['strings'])

for (const strings of cases) {
const [error, result] = string().validate(strings)

expect(error).toBeUndefined()
expect(result).toBe(strings)
expect(result).toBeTypeOf('string')
}
})

test('Non strings are considered invalid and returned with Error', () => {
const cases = fixtures.omit(['strings'])

for (const invalidStrings of cases) {
const [error, result] = string().validate(invalidStrings)

expect(result).toBeUndefined()

expect(error).not.toBeUndefined()
expect(error).toBeInstanceOf(StructError)
expect(error?.failures()).toStrictEqual([
{
branch: [invalidStrings],
explanation: undefined,
key: undefined,
message: `Expected a string, but received: ${print(invalidStrings)}`,
path: [],
refinement: undefined,
type: 'string',
value: invalidStrings,
},
])
}
})
14 changes: 14 additions & 0 deletions test/structs/unknown.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { expect, test } from 'vitest'
import { fixtures } from '../fixtures/fixtures'
import { unknown } from '../../src'

test('Everything is considered valid and returned as unknown', () => {
const cases = fixtures.all()

for (const c of cases) {
const [error, result] = unknown().validate(c)

expect(error).toBeUndefined()
expect(result).toBe(c)
}
})
7 changes: 0 additions & 7 deletions test/validation/any/valid-number.ts

This file was deleted.

7 changes: 0 additions & 7 deletions test/validation/any/valid-string.ts

This file was deleted.

7 changes: 0 additions & 7 deletions test/validation/any/valid-undefined.ts

This file was deleted.

15 changes: 0 additions & 15 deletions test/validation/boolean/invalid.ts

This file was deleted.

7 changes: 0 additions & 7 deletions test/validation/boolean/valid.ts

This file was deleted.

Loading

0 comments on commit 93bf438

Please sign in to comment.