Files
config/test/parsing.test.ts
2025-09-12 10:33:16 +02:00

185 lines
6.0 KiB
TypeScript

import {expect, test, describe, beforeEach} from 'bun:test'
import {yup} from '../src/index'
import * as parsing from '../src/parsing'
import {Ok} from '../src/helpers'
beforeEach(() => (process.env = {}))
describe('Object', () => {
test('basic', async () => {
const scheme = yup.object({})
const res = await parsing.object(scheme)
expect(res).toEqual({ok: true, data: {}})
})
describe('empty', () => {
test('Optional', async () => {
const res = await parsing.object(yup.object({thing: yup.number()}))
// @ts-expect-error empty is undefined, duh ??
expect(res).toEqual({ok: true, data: {}})
})
test('Required missing', async () => {
const res = await parsing.object(yup.object({thing: yup.number().required()}))
expect(res.ok).not.toBeTrue()
})
test('default', async () => {
const res = await parsing.object(yup.object({thing: yup.number().default(42)}))
expect(res).toEqual({ok: true, data: {thing: 42}})
})
})
describe('Nested objects', () => {
test('One level', async () => {
process.env = {
NAME: 'test',
PORT: '12',
TS: '2025-06-08 23:51:12'
}
const scheme = yup.object({name: yup.string(), port: yup.number(), ts: yup.date()})
const res = await parsing.object(scheme)
expect(res).toEqual({ok: true, data: {name: 'test', port: 12, ts: new Date('2025-06-08 23:51:12')}})
})
test('Two levels', async () => {
process.env = {
DB_PORT: '12',
DB_HOST: 'localhost',
THING_A: 'Hello!',
THING_B: '212',
NAME: 'Pascal',
AGE: '27'
}
const expected = {
name: 'Pascal',
age: 27,
db: {
port: 12,
host: 'localhost'
},
thing: {
a: 'Hello!',
b: 212
}
}
const scheme = yup.object({
name: yup.string().required(),
age: yup.number().required(),
db: yup
.object({
port: yup.number().required(),
host: yup.string().required()
})
.required(),
thing: yup
.object({
a: yup.string().required(),
b: yup.number().required()
})
.required()
})
const res = await parsing.object(scheme)
expect(res).toEqual({ok: true, data: expected})
})
test('Three levels', async () => {
process.env = {
DB_HOST: 'localhost',
THING_A: 'Hello!',
AGE: '27',
THING_THANG_A: '2025-06-06 23:56:12'
}
const expected = {
age: 27,
db: {
host: 'localhost'
},
thing: {
a: 'Hello!',
thang: {
a: new Date('2025-06-06 23:56:12')
}
}
}
const scheme = yup.object({
age: yup.number(),
db: yup.object({
host: yup.string()
}),
thing: yup.object({
a: yup.string(),
thang: yup.object({
a: yup.date()
})
})
})
const res = await parsing.object(scheme)
expect(res).toEqual({ok: true, data: expected})
})
})
describe('Specific parsing', () => {
async function testing<T>(env_value: string, scheme: yup.AnySchema, should_be_successful: boolean, thing?: T) {
process.env['THING'] = env_value
const my_scheme = yup.object({thing: scheme})
const res: Ok<{thing: T}> = await parsing.object(my_scheme)
// @ts-expect-error annoying typing issue, but it works, so, yk
if (should_be_successful) expect(res).toEqual({ok: true, data: {thing}})
else expect(res.ok).not.toBeTrue()
}
describe('array', () => {
test('basic', () => testing('1,2,3', yup.array(yup.number()), true, [1, 2, 3]))
test('basic with whitespaces', () => testing(' 1 , 2 , 3 ', yup.array(yup.number()), true, [1, 2, 3]))
test('Empty', () => testing('', yup.array(yup.number()), true, []))
test('Empty fails with minimum length', () => testing('', yup.array(yup.number()).min(3), false))
test('With minimum elements', () => testing('1,2,3', yup.array(yup.number()).min(3), true, [1, 2, 3]))
})
describe('tuple', () => {
test('basic', () => testing('1,2,3', yup.tuple([yup.number(), yup.number(), yup.number()]), true, [1, 2, 3]))
test('Missing value', () => testing('1,2', yup.tuple([yup.number(), yup.number(), yup.number()]), false))
test('Too much values', () => testing('1,2,3,4', yup.tuple([yup.number(), yup.number(), yup.number()]), false))
})
})
})
describe('generic', () => {
async function testing(
value: string | string[],
scheme: yup.AnySchema,
should_be_successful: boolean,
data?: unknown
) {
const res = await parsing.generic(value, scheme)
if (should_be_successful) expect(res).toEqual({ok: true, data})
else expect(res.ok).not.toBeTrue()
}
describe('Integer', () => {
test('basic', () => testing('12', yup.number(), true, 12))
test('string', () => testing('coucou', yup.number(), false))
test('min-max OK', () => testing('12', yup.number().min(11).max(13), true, 12))
test('min-max KO', () => testing('10', yup.number().min(11).max(13), false, 10))
test('min-max KO 2', () => testing('10', yup.number().min(11).max(13), false, 14))
})
describe('String', () => {
test('basic', () => testing('coucou', yup.string(), true, 'coucou'))
test('Length min-max', () => testing('coucou', yup.string().max(7), true, 'coucou'))
test('KO: Length min-max', () => testing('coucou', yup.string().max(5), false))
})
describe('boolean', () => {
test('basic true', () => testing('true', yup.boolean(), true, true))
test('basic false', () => testing('false', yup.boolean(), true, false))
test('basic 1', () => testing('1', yup.boolean(), true, true))
test('basic 0', () => testing('0', yup.boolean(), true, false))
test('junk', () => testing('yeet', yup.boolean(), false))
})
describe('Date', () => {
test('basic', () => testing('2025-06-08 22:40:17', yup.date(), true, new Date('2025-06-08 22:40:17')))
})
})