Skip to content

Commit

Permalink
Use vitest except where possible and organize tests
Browse files Browse the repository at this point in the history
  • Loading branch information
yeoffrey committed Jun 10, 2024
1 parent f24c3cd commit 578b42d
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 143 deletions.
2 changes: 1 addition & 1 deletion test/api/assert.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { throws, doesNotThrow } from 'assert'
import { doesNotThrow, throws } from 'assert'
import { describe, it } from 'vitest'
import { assert, string, StructError } from '../../src'

Expand Down
16 changes: 8 additions & 8 deletions test/api/create.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { strictEqual, deepEqual, deepStrictEqual, throws } from 'assert'
import { describe, it } from 'vitest'
import { describe, expect, it } from 'vitest'
import {
type,
optional,
Expand All @@ -9,26 +8,27 @@ import {
literal,
coerce,
} from '../../src'
import { throws } from 'assert'

describe('create', () => {
it('missing as helper', () => {
const S = defaulted(string(), 'default')
strictEqual(create(undefined, S), 'default')
expect(create(undefined, S)).toBe('default')
})

it('missing as method', () => {
const S = defaulted(string(), 'default')
strictEqual(S.create(undefined), 'default')
expect(S.create(undefined)).toBe('default')
})

it('not missing as helper', () => {
const S = defaulted(string(), 'default')
strictEqual(create('string', S), 'string')
expect(create('string', S)).toBe('string')
})

it('not missing as method', () => {
const S = defaulted(string(), 'default')
strictEqual(S.create('string'), 'string')
expect(S.create('string')).toBe('string')
})

it('missing optional fields remain missing', () => {
Expand All @@ -37,7 +37,7 @@ describe('create', () => {
b: optional(string()),
c: optional(type({ d: string() })),
})
deepEqual(S.create({ a: 'a' }), { a: 'a' })
expect(S.create({ a: 'a' })).toStrictEqual({ a: 'a' })
})

it('explicit undefined values are kept', () => {
Expand All @@ -46,7 +46,7 @@ describe('create', () => {
b: coerce(optional(string()), literal(null), () => undefined),
c: optional(type({ d: string() })),
})
deepStrictEqual(S.create({ a: 'a', b: null, c: undefined }), {
expect(S.create({ a: 'a', b: null, c: undefined })).toStrictEqual({
a: 'a',
b: undefined,
c: undefined,
Expand Down
11 changes: 5 additions & 6 deletions test/api/is.test.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
import { strictEqual } from 'assert'
import { describe, it } from 'vitest'
import { describe, expect, it } from 'vitest'
import { is, string } from '../../src'

describe('is', () => {
it('valid as helper', () => {
strictEqual(is('valid', string()), true)
expect(is('valid', string())).toBe(true)
})

it('valid as method', () => {
strictEqual(string().is('valid'), true)
expect(string().is('valid')).toBe(true)
})

it('invalid as helper', () => {
strictEqual(is(42, string()), false)
expect(is(42, string())).toBe(false)
})

it('invalid as method', () => {
strictEqual(string().is(42), false)
expect(string().is(42)).toBe(false)
})
})
18 changes: 9 additions & 9 deletions test/api/mask.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { deepStrictEqual, throws } from 'assert'
import { describe, it } from 'vitest'
import { throws } from 'assert'
import { describe, expect, it } from 'vitest'
import {
mask,
object,
Expand All @@ -14,7 +14,7 @@ describe('mask', () => {
it('object as helper', () => {
const S = object({ id: string() })
const value = { id: '1', unknown: true }
deepStrictEqual(mask(value, S), { id: '1' })
expect(mask(value, S)).toStrictEqual({ id: '1' })
})

it('non-object as helper', () => {
Expand All @@ -28,7 +28,7 @@ describe('mask', () => {
it('coercing', () => {
const S = defaulted(object({ id: string() }), { id: '0' })
const value = { unknown: true }
deepStrictEqual(mask(value, S), { id: '0' })
expect(mask(value, S)).toStrictEqual({ id: '0' })
})

it('deep masking of objects', () => {
Expand All @@ -41,7 +41,7 @@ describe('mask', () => {
unknown: true,
sub: [{ prop: '2', unknown: true }],
}
deepStrictEqual(mask(value, S), { id: '1', sub: [{ prop: '2' }] })
expect(mask(value, S)).toStrictEqual({ id: '1', sub: [{ prop: '2' }] })
})

it('masking of a nested type', () => {
Expand All @@ -54,7 +54,7 @@ describe('mask', () => {
unknown: true,
sub: [{ prop: '2', unknown: true }],
}
deepStrictEqual(mask(value, S), {
expect(mask(value, S)).toStrictEqual({
id: '1',
sub: [{ prop: '2', unknown: true }],
})
Expand All @@ -70,7 +70,7 @@ describe('mask', () => {
unknown: true,
sub: [{ prop: '2', unknown: true }],
}
deepStrictEqual(mask(value, S), {
expect(mask(value, S)).toStrictEqual({
id: '1',
unknown: true,
sub: [{ prop: '2' }],
Expand All @@ -80,8 +80,8 @@ describe('mask', () => {
it('masking does not change the original value', () => {
const S = object({ id: string() })
const value = { id: '1', unknown: true }
deepStrictEqual(mask(value, S), { id: '1' })
deepStrictEqual(value, { id: '1', unknown: true })
expect(mask(value, S)).toStrictEqual({ id: '1' })
expect(value).toStrictEqual({ id: '1', unknown: true })
})

it('custom error message', () => {
Expand Down
38 changes: 18 additions & 20 deletions test/api/validate.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { deepStrictEqual, strictEqual } from 'assert'
import { describe, it } from 'vitest'
import { describe, expect, it } from 'vitest'
import {
validate,
string,
Expand All @@ -13,20 +12,20 @@ import {
describe('validate', () => {
it('valid as helper', () => {
const S = string()
deepStrictEqual(validate('valid', S), [undefined, 'valid'])
expect(validate('valid', S)).toStrictEqual([undefined, 'valid'])
})

it('valid as method', () => {
const S = string()
deepStrictEqual(S.validate('valid'), [undefined, 'valid'])
expect(S.validate('valid')).toStrictEqual([undefined, 'valid'])
})

it('invalid as helper', () => {
const S = string()
const [err, value] = validate(42, S)
strictEqual(value, undefined)
strictEqual(err instanceof StructError, true)
deepStrictEqual(Array.from((err as StructError).failures()), [
expect(value).toStrictEqual(undefined)
expect(err).toBeInstanceOf(StructError)
expect(Array.from((err as StructError).failures())).toStrictEqual([
{
value: 42,
key: undefined,
Expand All @@ -43,9 +42,9 @@ describe('validate', () => {
it('invalid as method', () => {
const S = string()
const [err, value] = S.validate(42)
strictEqual(value, undefined)
strictEqual(err instanceof StructError, true)
deepStrictEqual(Array.from((err as StructError).failures()), [
expect(value).toStrictEqual(undefined)
expect(err).toBeInstanceOf(StructError)
expect(Array.from((err as StructError).failures())).toStrictEqual([
{
value: 42,
key: undefined,
Expand All @@ -62,22 +61,21 @@ describe('validate', () => {
it('error message path', () => {
const S = object({ author: object({ name: string() }) })
const [err] = S.validate({ author: { name: 42 } })
strictEqual(
(err as StructError).message,
expect(err?.message).toBe(
'At path: author.name -- Expected a string, but received: 42'
)
})

it('custom error message', () => {
const S = string()
const [err] = S.validate(42, { message: 'Validation failed!' })
strictEqual(err?.message, 'Validation failed!')
strictEqual(err?.cause, 'Expected a string, but received: 42')
expect(err?.message).toBe('Validation failed!')
expect(err?.cause).toBe('Expected a string, but received: 42')
})

it('early exit', () => {
let ranA = false
let ranB = false
const ranB = false

const A = define('A', (x) => {
ranA = true
Expand All @@ -91,8 +89,8 @@ describe('validate', () => {

const S = object({ a: A, b: B })
S.validate({ a: null, b: null })
strictEqual(ranA, true)
strictEqual(ranB, false)
expect(ranA).toBe(true)
expect(ranB).toBe(false)
})

it('refiners after children', () => {
Expand All @@ -109,7 +107,7 @@ describe('validate', () => {
})

B.validate({ a: null })
deepStrictEqual(order, ['validator', 'refiner'])
expect(order).toStrictEqual(['validator', 'refiner'])
})

it('refiners even if nested refiners fail', () => {
Expand All @@ -127,7 +125,7 @@ describe('validate', () => {
const [error] = B.validate({ a: null })
// Collect all failures. Ensures all validation runs.
error?.failures()
strictEqual(ranOuterRefiner, true)
expect(ranOuterRefiner).toBe(true)
})

it('skips refiners if validators return errors', () => {
Expand All @@ -145,6 +143,6 @@ describe('validate', () => {
const [error] = B.validate({ a: null })
// Collect all failures. Ensures all validation runs.
error?.failures()
strictEqual(ranRefiner, false)
expect(ranRefiner).toBe(false)
})
})
33 changes: 33 additions & 0 deletions test/deprecated.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { describe, it } from 'vitest'
import { CallTracker } from 'assert'
import { any, assert, Context, deprecated } from '../src'

describe('deprecated', () => {
it('does not log deprecated type if value is undefined', () => {
const tracker = new CallTracker()
const logSpy = buildSpyWithZeroCalls(tracker)
assert(undefined, deprecated(any(), logSpy))
tracker.verify()
})

it('logs deprecated type to passed function if value is present', () => {
const tracker = new CallTracker()
const fakeLog = (value: unknown, ctx: Context) => {}
const logSpy = tracker.calls(fakeLog, 1)
assert('present', deprecated(any(), logSpy))
tracker.verify()
})
})

/**
* This emulates `tracker.calls(0)`.
*
* `CallTracker.calls` doesn't support passing `0`, therefore we expect it
* to be called once which is our call in this test. This proves that
* the following action didn't call it.
*/
function buildSpyWithZeroCalls(tracker: CallTracker) {
const logSpy = tracker.calls(1)
logSpy()
return logSpy
}
Loading

0 comments on commit 578b42d

Please sign in to comment.