Publish
This commit is contained in:
35
test/runtime/value/assert/assert.ts
Normal file
35
test/runtime/value/assert/assert.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { Value, AssertError } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/Assert', () => {
|
||||
it('Should Assert', () => {
|
||||
Assert.Throws(() => Value.Assert(Type.String(), 1))
|
||||
})
|
||||
it('Should throw AssertError', () => {
|
||||
try {
|
||||
Value.Assert(Type.String(), 1)
|
||||
} catch (error) {
|
||||
if (error instanceof AssertError) {
|
||||
return
|
||||
}
|
||||
throw error
|
||||
}
|
||||
})
|
||||
it('Should throw AssertError and produce Iterator', () => {
|
||||
try {
|
||||
Value.Assert(Type.String(), 1)
|
||||
} catch (error) {
|
||||
if (error instanceof AssertError) {
|
||||
const first = error.Errors().First()
|
||||
Assert.HasProperty(first, 'type')
|
||||
Assert.HasProperty(first, 'schema')
|
||||
Assert.HasProperty(first, 'path')
|
||||
Assert.HasProperty(first, 'value')
|
||||
Assert.HasProperty(first, 'message')
|
||||
return
|
||||
}
|
||||
throw error
|
||||
}
|
||||
})
|
||||
})
|
||||
1
test/runtime/value/assert/index.ts
Normal file
1
test/runtime/value/assert/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
import './assert'
|
||||
52
test/runtime/value/cast/any.ts
Normal file
52
test/runtime/value/cast/any.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/Any', () => {
|
||||
const T = Type.Any()
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
it('Should upcast from number', () => {
|
||||
const value = 1
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
it('Should upcast from boolean', () => {
|
||||
const value = false
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
it('Should upcast from date', () => {
|
||||
const value = new Date(100)
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result.getTime(100), 100)
|
||||
})
|
||||
it('Should preserve', () => {
|
||||
const value = { a: 1, b: 2 }
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, { a: 1, b: 2 })
|
||||
})
|
||||
})
|
||||
118
test/runtime/value/cast/array.ts
Normal file
118
test/runtime/value/cast/array.ts
Normal file
@@ -0,0 +1,118 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/Array', () => {
|
||||
const T = Type.Array(Type.Number(), { default: [1, 2, 3] })
|
||||
const E = [1, 2, 3]
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from number', () => {
|
||||
const value = 1
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, [1])
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from date', () => {
|
||||
const value = new Date(100)
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should preserve', () => {
|
||||
const value = [6, 7, 8]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, [6, 7, 8])
|
||||
})
|
||||
it('Should preserve with invalid element set to default', () => {
|
||||
const value = [6, 7, 8, 'hello', 9]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, [6, 7, 8, 0, 9])
|
||||
})
|
||||
// -----------------------------------------------------------------
|
||||
// Constraints: Ranges
|
||||
// -----------------------------------------------------------------
|
||||
it('Should cast array and truncate to maxItems from value', () => {
|
||||
const result = Value.Cast(Type.Array(Type.Number(), { maxItems: 3 }), [0, 1, 2, 4, 5, 6])
|
||||
Assert.IsEqual(result, [0, 1, 2])
|
||||
})
|
||||
it('Should cast arrays and append array to minItems from value', () => {
|
||||
const result = Value.Cast(Type.Array(Type.Number(), { minItems: 6 }), [0, 1, 2])
|
||||
Assert.IsEqual(result, [0, 1, 2, 0, 0, 0])
|
||||
})
|
||||
it('Should cast array and truncate to maxItems from default value', () => {
|
||||
const result = Value.Cast(Type.Array(Type.Number(), { maxItems: 3, default: [0, 1, 2, 4, 5, 6] }), null)
|
||||
Assert.IsEqual(result, [0, 1, 2])
|
||||
})
|
||||
it('Should cast arrays and append array to minItems from default value', () => {
|
||||
const result = Value.Cast(Type.Array(Type.Number({ default: 1 }), { minItems: 6, default: [0, 1, 2] }), null)
|
||||
Assert.IsEqual(result, [0, 1, 2, 1, 1, 1])
|
||||
})
|
||||
// -----------------------------------------------------------------
|
||||
// Constraints: Unique
|
||||
// -----------------------------------------------------------------
|
||||
it('Should cast arrays with uniqueItems with unique default value', () => {
|
||||
const result = Value.Cast(Type.Array(Type.Number(), { uniqueItems: true, default: [0, 1, 2] }), null)
|
||||
Assert.IsEqual(result, [0, 1, 2])
|
||||
})
|
||||
it('Should cast arrays with uniqueItems with unique value', () => {
|
||||
const result = Value.Cast(Type.Array(Type.Number(), { uniqueItems: true }), [0, 1, 2])
|
||||
Assert.IsEqual(result, [0, 1, 2])
|
||||
})
|
||||
it('Should throw when casting arrays with uniqueItems and no value or default value', () => {
|
||||
Assert.Throws(() => Value.Cast(Type.Array(Type.Number(), { uniqueItems: true }), null))
|
||||
})
|
||||
it('Should throw when casting arrays with uniqueItems and not enough values to populate set', () => {
|
||||
Assert.Throws(() => Value.Cast(Type.Array(Type.Number(), { minItems: 3, uniqueItems: true }), [0, 1]))
|
||||
})
|
||||
it('Should throw when casting arrays with uniqueItems and not enough default values to populate set', () => {
|
||||
Assert.Throws(() => Value.Cast(Type.Array(Type.Number(), { minItems: 3, uniqueItems: true, default: [0, 1] }), null))
|
||||
})
|
||||
// -----------------------------------------------------------------
|
||||
// Suggestion: https://github.com/sinclairzx81/typebox/issues/239
|
||||
// -----------------------------------------------------------------
|
||||
it('Should remove duplicates if uniqueItems is true', () => {
|
||||
const T = Type.Array(Type.Number(), { uniqueItems: true })
|
||||
const value = [1, 1, 2, 2]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, [1, 2])
|
||||
})
|
||||
it('Should should fill up with defaults to minItems', () => {
|
||||
const T = Type.Array(Type.Number(), { minItems: 3 })
|
||||
const value = [1, 2]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, [1, 2, 0])
|
||||
})
|
||||
it('Should should truncate to maxItems', () => {
|
||||
const T = Type.Array(Type.Number(), { maxItems: 3 })
|
||||
const value = [1, 2, 3, 4]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, [1, 2, 3])
|
||||
})
|
||||
})
|
||||
37
test/runtime/value/cast/async-iterator.ts
Normal file
37
test/runtime/value/cast/async-iterator.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/AsyncIterator', () => {
|
||||
const T = Type.AsyncIterator(Type.Any())
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'world'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsTrue(Symbol.asyncIterator in result)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsTrue(Symbol.asyncIterator in result)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsTrue(Symbol.asyncIterator in result)
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsTrue(Symbol.asyncIterator in result)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsTrue(Symbol.asyncIterator in result)
|
||||
})
|
||||
it('Should preseve', () => {
|
||||
const value = (async function* () {})()
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsTrue(value === result)
|
||||
})
|
||||
})
|
||||
53
test/runtime/value/cast/bigint.ts
Normal file
53
test/runtime/value/cast/bigint.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/BigInt', () => {
|
||||
const T = Type.BigInt()
|
||||
const E = BigInt(0)
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from number', () => {
|
||||
const value = 0
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from date', () => {
|
||||
const value = new Date(100)
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should preserve', () => {
|
||||
const value = BigInt(100)
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, BigInt(100))
|
||||
})
|
||||
})
|
||||
53
test/runtime/value/cast/boolean.ts
Normal file
53
test/runtime/value/cast/boolean.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/Boolean', () => {
|
||||
const T = Type.Boolean()
|
||||
const E = false
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from number', () => {
|
||||
const value = 0
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from date', () => {
|
||||
const value = new Date(100)
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should preserve', () => {
|
||||
const value = true
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
})
|
||||
89
test/runtime/value/cast/composite.ts
Normal file
89
test/runtime/value/cast/composite.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/Composite', () => {
|
||||
const A = Type.Object({
|
||||
x: Type.Number({ default: 0 }),
|
||||
y: Type.Number({ default: 1 }),
|
||||
z: Type.Number({ default: 2 }),
|
||||
})
|
||||
const B = Type.Object({
|
||||
a: Type.Number({ default: 'a' }),
|
||||
b: Type.Number({ default: 'b' }),
|
||||
c: Type.Number({ default: 'c' }),
|
||||
})
|
||||
const T = Type.Composite([A, B])
|
||||
const E = {
|
||||
x: 0,
|
||||
y: 1,
|
||||
z: 2,
|
||||
a: 'a',
|
||||
b: 'b',
|
||||
c: 'c',
|
||||
}
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from number', () => {
|
||||
const value = E
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from date', () => {
|
||||
const value = new Date(100)
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast and preserve object', () => {
|
||||
const value = { x: 7, y: 8, z: 9 }
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, {
|
||||
x: 7,
|
||||
y: 8,
|
||||
z: 9,
|
||||
a: 'a',
|
||||
b: 'b',
|
||||
c: 'c',
|
||||
})
|
||||
})
|
||||
it('Should upcast and preserve from incorrect properties', () => {
|
||||
const value = { x: {}, y: 8, z: 9 }
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, {
|
||||
x: 0,
|
||||
y: 8,
|
||||
z: 9,
|
||||
a: 'a',
|
||||
b: 'b',
|
||||
c: 'c',
|
||||
})
|
||||
})
|
||||
})
|
||||
38
test/runtime/value/cast/date.ts
Normal file
38
test/runtime/value/cast/date.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/Date', () => {
|
||||
const T = Type.Date()
|
||||
const E = new Date(0)
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'world'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.InRange(result.getTime(), new Date().getTime(), 1000)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.InRange(result.getTime(), new Date().getTime(), 1000)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.InRange(result.getTime(), new Date().getTime(), 1000)
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.InRange(result.getTime(), new Date().getTime(), 1000)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.InRange(result.getTime(), new Date().getTime(), 1000)
|
||||
})
|
||||
it('Should preseve', () => {
|
||||
const value = new Date(100)
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result.getTime(), 100)
|
||||
})
|
||||
})
|
||||
62
test/runtime/value/cast/enum.ts
Normal file
62
test/runtime/value/cast/enum.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/Boolean', () => {
|
||||
enum Foo {
|
||||
A,
|
||||
B,
|
||||
}
|
||||
const T = Type.Enum(Foo)
|
||||
const E = Foo.A
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from number', () => {
|
||||
const value = 123
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from date', () => {
|
||||
const value = new Date(100)
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from enum A', () => {
|
||||
const value = Foo.A
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, Foo.A)
|
||||
})
|
||||
it('Should upcast from enum B', () => {
|
||||
const value = Foo.B
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, Foo.B)
|
||||
})
|
||||
})
|
||||
51
test/runtime/value/cast/import.ts
Normal file
51
test/runtime/value/cast/import.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/Import', () => {
|
||||
const T = Type.Module({
|
||||
A: Type.Number(),
|
||||
}).Import('A')
|
||||
|
||||
const E = 0
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'world'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from number', () => {
|
||||
const value = 1
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, 1)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from date', () => {
|
||||
const value = new Date(100)
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should preseve', () => {
|
||||
const value = 123
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, 123)
|
||||
})
|
||||
})
|
||||
32
test/runtime/value/cast/index.ts
Normal file
32
test/runtime/value/cast/index.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import './any'
|
||||
import './array'
|
||||
import './async-iterator'
|
||||
import './bigint'
|
||||
import './boolean'
|
||||
import './composite'
|
||||
import './date'
|
||||
import './enum'
|
||||
import './import'
|
||||
import './integer'
|
||||
import './intersect'
|
||||
import './iterator'
|
||||
import './keyof'
|
||||
import './kind'
|
||||
import './literal'
|
||||
import './never'
|
||||
import './not'
|
||||
import './null'
|
||||
import './number'
|
||||
import './object'
|
||||
import './recursive'
|
||||
import './record'
|
||||
import './regexp'
|
||||
import './string'
|
||||
import './symbol'
|
||||
import './template-literal'
|
||||
import './tuple'
|
||||
import './uint8array'
|
||||
import './undefined'
|
||||
import './union'
|
||||
import './unknown'
|
||||
import './void'
|
||||
43
test/runtime/value/cast/integer.ts
Normal file
43
test/runtime/value/cast/integer.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/Integer', () => {
|
||||
const T = Type.Integer()
|
||||
const E = 0
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from number', () => {
|
||||
const value = 1
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, 1)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from date', () => {
|
||||
const value = new Date(100)
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
})
|
||||
112
test/runtime/value/cast/intersect.ts
Normal file
112
test/runtime/value/cast/intersect.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/Intersect', () => {
|
||||
it('Should cast from an invalid object', () => {
|
||||
// prettier-ignore
|
||||
const T = Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() })
|
||||
])
|
||||
const V = Value.Cast(T, 1)
|
||||
Assert.IsEqual(V, { x: 0, y: 0 })
|
||||
})
|
||||
it('Should cast from an partial object and preserve', () => {
|
||||
// prettier-ignore
|
||||
const T = Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() })
|
||||
])
|
||||
const V = Value.Cast(T, { x: 1 })
|
||||
Assert.IsEqual(V, { x: 1, y: 0 })
|
||||
})
|
||||
it('Should cast and use default values', () => {
|
||||
// prettier-ignore
|
||||
const T = Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number({ default: 42 }) })
|
||||
])
|
||||
const V = Value.Cast(T, { x: 1 })
|
||||
Assert.IsEqual(V, { x: 1, y: 42 })
|
||||
})
|
||||
it('Should throw with an illogical intersect', () => {
|
||||
// prettier-ignore
|
||||
const T = Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ x: Type.String() })
|
||||
])
|
||||
Assert.Throws(() => Value.Cast(T, { x: 1 }))
|
||||
})
|
||||
it('Should throw with an illogical intersect (primative)', () => {
|
||||
// prettier-ignore
|
||||
const T = Type.Intersect([
|
||||
Type.Number(),
|
||||
Type.String()
|
||||
])
|
||||
Assert.Throws(() => Value.Cast(T, { x: 1 }))
|
||||
})
|
||||
it('Should use last intersected default for equivalent sub schemas', () => {
|
||||
// prettier-ignore
|
||||
const T = Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ x: Type.Number({ default: 1000 }) })
|
||||
])
|
||||
const V = Value.Cast(T, null)
|
||||
Assert.IsEqual(V, { x: 1000 })
|
||||
})
|
||||
it('Should use last intersected default for equivalent sub schemas (primitives)', () => {
|
||||
// prettier-ignore
|
||||
const T = Type.Intersect([
|
||||
Type.Number(),
|
||||
Type.Number({ default: 1000 })
|
||||
])
|
||||
const V = Value.Cast(T, null)
|
||||
Assert.IsEqual(V, 1000)
|
||||
})
|
||||
it('Should preserve if default is specified', () => {
|
||||
// prettier-ignore
|
||||
const T = Type.Intersect([
|
||||
Type.Number(),
|
||||
Type.Number({ default: 1000 })
|
||||
])
|
||||
const V = Value.Cast(T, 2000)
|
||||
Assert.IsEqual(V, 2000)
|
||||
})
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// https://github.com/sinclairzx81/typebox/issues/1264
|
||||
// ----------------------------------------------------------------
|
||||
it('Should preserve intersected properties', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Object({}),
|
||||
Type.Object({
|
||||
name: Type.String(),
|
||||
age: Type.Optional(Type.Number()),
|
||||
location: Type.Object({
|
||||
lat: Type.Number(),
|
||||
long: Type.Number(),
|
||||
}),
|
||||
greeting: Type.String(),
|
||||
}),
|
||||
])
|
||||
const V0 = Value.Cast(T, { greeting: 'Hello' })
|
||||
const V1 = Value.Cast(T, { location: null, greeting: 'Hello' })
|
||||
const V2 = Value.Cast(T, { location: { lat: 1 }, greeting: 'Hello' })
|
||||
const V3 = Value.Cast(T, { location: { lat: 1, long: 1 }, greeting: 'Hello' })
|
||||
|
||||
Assert.IsEqual(V0, { name: '', location: { lat: 0, long: 0 }, greeting: 'Hello' })
|
||||
Assert.IsEqual(V1, { name: '', location: { lat: 0, long: 0 }, greeting: 'Hello' })
|
||||
Assert.IsEqual(V2, { name: '', location: { lat: 1, long: 0 }, greeting: 'Hello' })
|
||||
Assert.IsEqual(V3, { name: '', location: { lat: 1, long: 1 }, greeting: 'Hello' })
|
||||
})
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// https://github.com/sinclairzx81/typebox/issues/1269#issuecomment-2993924180
|
||||
// --------------------------------------------------------------------------
|
||||
it('Should Cast with intersected Record', () => {
|
||||
const T = Type.Intersect([Type.Record(Type.TemplateLiteral('x-${string}'), Type.Unknown()), Type.Object({ name: Type.String() })])
|
||||
const R = Value.Cast(T, {})
|
||||
Assert.IsEqual(R, { name: '' })
|
||||
})
|
||||
})
|
||||
37
test/runtime/value/cast/iterator.ts
Normal file
37
test/runtime/value/cast/iterator.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/Iterator', () => {
|
||||
const T = Type.Iterator(Type.Any())
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'world'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsTrue(Symbol.iterator in result)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsTrue(Symbol.iterator in result)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsTrue(Symbol.iterator in result)
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsTrue(Symbol.iterator in result)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsTrue(Symbol.iterator in result)
|
||||
})
|
||||
it('Should preseve', () => {
|
||||
const value = (function* () {})()
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsTrue(value === result)
|
||||
})
|
||||
})
|
||||
59
test/runtime/value/cast/keyof.ts
Normal file
59
test/runtime/value/cast/keyof.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/KeyOf', () => {
|
||||
const T = Type.KeyOf(
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
z: Type.Number(),
|
||||
}),
|
||||
)
|
||||
const E = 'x'
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from number', () => {
|
||||
const value = 1
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from date', () => {
|
||||
const value = new Date(100)
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should preserve', () => {
|
||||
const value = 'y'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, 'y')
|
||||
})
|
||||
})
|
||||
62
test/runtime/value/cast/kind.ts
Normal file
62
test/runtime/value/cast/kind.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type, Kind, TypeRegistry } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/Kind', () => {
|
||||
// ---------------------------------------------------------
|
||||
// Fixtures
|
||||
// ---------------------------------------------------------
|
||||
before(() => TypeRegistry.Set('Kind', (schema, value) => value === 'hello' || value === 'world'))
|
||||
after(() => TypeRegistry.Clear())
|
||||
// ---------------------------------------------------------
|
||||
// Tests
|
||||
// ---------------------------------------------------------
|
||||
const T = Type.Unsafe({ [Kind]: 'Kind', default: 'hello' })
|
||||
const E = 'hello'
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from number', () => {
|
||||
const value = 1
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from boolean', () => {
|
||||
const value = false
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should preserve', () => {
|
||||
const value = { a: 'hello', b: 'world' }
|
||||
const result = Value.Cast(
|
||||
Type.Object({
|
||||
a: T,
|
||||
b: T,
|
||||
}),
|
||||
value,
|
||||
)
|
||||
Assert.IsEqual(result, { a: 'hello', b: 'world' })
|
||||
})
|
||||
})
|
||||
53
test/runtime/value/cast/literal.ts
Normal file
53
test/runtime/value/cast/literal.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/Literal', () => {
|
||||
const T = Type.Literal('hello')
|
||||
const E = 'hello'
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'world'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from number', () => {
|
||||
const value = 1
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from date', () => {
|
||||
const value = new Date(100)
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should preseve', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, 'hello')
|
||||
})
|
||||
})
|
||||
39
test/runtime/value/cast/never.ts
Normal file
39
test/runtime/value/cast/never.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/Never', () => {
|
||||
const T = Type.Never()
|
||||
it('Should throw from string', () => {
|
||||
const value = 'hello'
|
||||
Assert.Throws(() => Value.Cast(T, value))
|
||||
})
|
||||
it('Should throw from number', () => {
|
||||
const value = 1
|
||||
Assert.Throws(() => Value.Cast(T, value))
|
||||
})
|
||||
it('Should throw from boolean', () => {
|
||||
const value = false
|
||||
Assert.Throws(() => Value.Cast(T, value))
|
||||
})
|
||||
it('Should throw from object', () => {
|
||||
const value = {}
|
||||
Assert.Throws(() => Value.Cast(T, value))
|
||||
})
|
||||
it('Should throw from array', () => {
|
||||
const value = [1]
|
||||
Assert.Throws(() => Value.Cast(T, value))
|
||||
})
|
||||
it('Should throw from undefined', () => {
|
||||
const value = undefined
|
||||
Assert.Throws(() => Value.Cast(T, value))
|
||||
})
|
||||
it('Should throw from null', () => {
|
||||
const value = null
|
||||
Assert.Throws(() => Value.Cast(T, value))
|
||||
})
|
||||
it('Should upcast from date', () => {
|
||||
const value = null
|
||||
Assert.Throws(() => Value.Cast(T, value))
|
||||
})
|
||||
})
|
||||
52
test/runtime/value/cast/not.ts
Normal file
52
test/runtime/value/cast/not.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/Not', () => {
|
||||
const T = Type.Not(Type.String(), { default: 0 })
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, 0) // default
|
||||
})
|
||||
it('Should upcast from number', () => {
|
||||
const value = 0
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
it('Should upcast from boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
it('Should upcast from date', () => {
|
||||
const value = new Date(100)
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
it('Should preserve', () => {
|
||||
const value = 100
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, 100)
|
||||
})
|
||||
})
|
||||
53
test/runtime/value/cast/null.ts
Normal file
53
test/runtime/value/cast/null.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/Null', () => {
|
||||
const T = Type.Null()
|
||||
const E = null
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'world'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from number', () => {
|
||||
const value = 1
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from date', () => {
|
||||
const value = new Date(100)
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should preseve', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, null)
|
||||
})
|
||||
})
|
||||
48
test/runtime/value/cast/number.ts
Normal file
48
test/runtime/value/cast/number.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/Number', () => {
|
||||
const T = Type.Number()
|
||||
const E = 0
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'world'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from number', () => {
|
||||
const value = 1
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, 1)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from date', () => {
|
||||
const value = new Date(100)
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should preseve', () => {
|
||||
const value = 123
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, 123)
|
||||
})
|
||||
})
|
||||
162
test/runtime/value/cast/object.ts
Normal file
162
test/runtime/value/cast/object.ts
Normal file
@@ -0,0 +1,162 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/Object', () => {
|
||||
const T = Type.Object({
|
||||
a: Type.Number({ default: 'a' }),
|
||||
b: Type.Number({ default: 'b' }),
|
||||
c: Type.Number({ default: 'c' }),
|
||||
x: Type.Number({ default: 0 }),
|
||||
y: Type.Number({ default: 1 }),
|
||||
z: Type.Number({ default: 2 }),
|
||||
})
|
||||
const E = {
|
||||
x: 0,
|
||||
y: 1,
|
||||
z: 2,
|
||||
a: 'a',
|
||||
b: 'b',
|
||||
c: 'c',
|
||||
}
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from number', () => {
|
||||
const value = E
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from date', () => {
|
||||
const value = new Date(100)
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should preserve', () => {
|
||||
const value = { x: 7, y: 8, z: 9, a: 10, b: 11, c: 12 }
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, {
|
||||
x: 7,
|
||||
y: 8,
|
||||
z: 9,
|
||||
a: 10,
|
||||
b: 11,
|
||||
c: 12,
|
||||
})
|
||||
})
|
||||
it('Should upcast and preserve partial object', () => {
|
||||
const value = { x: 7, y: 8, z: 9 }
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, {
|
||||
x: 7,
|
||||
y: 8,
|
||||
z: 9,
|
||||
a: 'a',
|
||||
b: 'b',
|
||||
c: 'c',
|
||||
})
|
||||
})
|
||||
it('Should upcast and preserve partial object with incorrect properties', () => {
|
||||
const value = { x: {}, y: 8, z: 9 }
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, {
|
||||
x: 0,
|
||||
y: 8,
|
||||
z: 9,
|
||||
a: 'a',
|
||||
b: 'b',
|
||||
c: 'c',
|
||||
})
|
||||
})
|
||||
it('Should upcast and preserve partial object and omit unknown properties', () => {
|
||||
const value = { x: 7, y: 8, z: 9, unknown: 'foo' }
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, {
|
||||
x: 7,
|
||||
y: 8,
|
||||
z: 9,
|
||||
a: 'a',
|
||||
b: 'b',
|
||||
c: 'c',
|
||||
})
|
||||
})
|
||||
it('Should upcast and create invalid additional properties', () => {
|
||||
const result = Value.Cast(
|
||||
Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
},
|
||||
{
|
||||
additionalProperties: Type.Object({
|
||||
a: Type.Number(),
|
||||
b: Type.Number(),
|
||||
}),
|
||||
},
|
||||
),
|
||||
{
|
||||
x: 1,
|
||||
y: 2,
|
||||
z: true,
|
||||
},
|
||||
)
|
||||
Assert.IsEqual(result, {
|
||||
x: 1,
|
||||
y: 2,
|
||||
z: { a: 0, b: 0 },
|
||||
})
|
||||
})
|
||||
it('Should upcast and preserve additional properties', () => {
|
||||
const result = Value.Cast(
|
||||
Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
},
|
||||
{
|
||||
additionalProperties: Type.Object({
|
||||
a: Type.Number(),
|
||||
b: Type.Number(),
|
||||
}),
|
||||
},
|
||||
),
|
||||
{
|
||||
x: 1,
|
||||
y: 2,
|
||||
z: { b: 1 },
|
||||
},
|
||||
)
|
||||
Assert.IsEqual(result, {
|
||||
x: 1,
|
||||
y: 2,
|
||||
z: { a: 0, b: 1 },
|
||||
})
|
||||
})
|
||||
})
|
||||
80
test/runtime/value/cast/record.ts
Normal file
80
test/runtime/value/cast/record.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/Record', () => {
|
||||
const T = Type.Record(
|
||||
Type.String(),
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
z: Type.Number(),
|
||||
}),
|
||||
)
|
||||
const E = {}
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from number', () => {
|
||||
const value = E
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from date', () => {
|
||||
const value = new Date(100)
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should preserve', () => {
|
||||
const value = {
|
||||
a: { x: 1, y: 2, z: 3 },
|
||||
b: { x: 4, y: 5, z: 6 },
|
||||
}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
it('Should preserve and patch invalid records', () => {
|
||||
const value = {
|
||||
a: { x: 1, y: 2, z: 3 },
|
||||
b: { x: 4, y: 5, z: {} },
|
||||
c: [1, 2, 3],
|
||||
d: 1,
|
||||
e: { x: 1, y: 2, w: 9000 },
|
||||
}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, {
|
||||
a: { x: 1, y: 2, z: 3 },
|
||||
b: { x: 4, y: 5, z: 0 },
|
||||
c: { x: 0, y: 0, z: 0 },
|
||||
d: { x: 0, y: 0, z: 0 },
|
||||
e: { x: 1, y: 2, z: 0 },
|
||||
})
|
||||
})
|
||||
})
|
||||
98
test/runtime/value/cast/recursive.ts
Normal file
98
test/runtime/value/cast/recursive.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/Recursive', () => {
|
||||
const T = Type.Recursive((This) =>
|
||||
Type.Object({
|
||||
id: Type.String(),
|
||||
nodes: Type.Array(This),
|
||||
}),
|
||||
)
|
||||
const E = { id: '', nodes: [] }
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from number', () => {
|
||||
const value = E
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from date', () => {
|
||||
const value = new Date(100)
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should preserve', () => {
|
||||
const value = {
|
||||
id: 'A',
|
||||
nodes: [
|
||||
{ id: 'B', nodes: [] },
|
||||
{ id: 'C', nodes: [] },
|
||||
{ id: 'D', nodes: [] },
|
||||
],
|
||||
}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
it('Should upcast from varying types', () => {
|
||||
const TypeA = Type.Recursive((This) =>
|
||||
Type.Object({
|
||||
id: Type.String(),
|
||||
nodes: Type.Array(This),
|
||||
}),
|
||||
)
|
||||
const TypeB = Type.Recursive((This) =>
|
||||
Type.Object({
|
||||
id: Type.String(),
|
||||
name: Type.String({ default: 'test' }),
|
||||
nodes: Type.Array(This),
|
||||
}),
|
||||
)
|
||||
const ValueA = {
|
||||
id: 'A',
|
||||
nodes: [
|
||||
{ id: 'B', nodes: [] },
|
||||
{ id: 'C', nodes: [] },
|
||||
{ id: 'D', nodes: [] },
|
||||
],
|
||||
}
|
||||
const ValueB = Value.Cast(TypeB, ValueA)
|
||||
// Assert.isEqual(ValueB, {
|
||||
// id: 'A',
|
||||
// name: 'test',
|
||||
// nodes: [
|
||||
// { id: 'B', name: 'test', nodes: [] },
|
||||
// { id: 'C', name: 'test', nodes: [] },
|
||||
// { id: 'D', name: 'test', nodes: [] },
|
||||
// ],
|
||||
// })
|
||||
})
|
||||
})
|
||||
60
test/runtime/value/cast/regexp.ts
Normal file
60
test/runtime/value/cast/regexp.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/RegExp', () => {
|
||||
const T = Type.RegExp(/foo/, { default: 'foo' })
|
||||
const E = 'foo'
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, 'foo')
|
||||
})
|
||||
it('Should upcast from number', () => {
|
||||
const value = 1
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from date', () => {
|
||||
const value = new Date(100)
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should preserve', () => {
|
||||
const value = 'foo'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Throw
|
||||
// ----------------------------------------------------------------
|
||||
it('Should throw with no default', () => {
|
||||
const T = Type.RegExp(/foo/)
|
||||
Assert.Throws(() => Value.Cast(T, null))
|
||||
})
|
||||
})
|
||||
43
test/runtime/value/cast/string.ts
Normal file
43
test/runtime/value/cast/string.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/String', () => {
|
||||
const T = Type.String()
|
||||
const E = ''
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, 'hello')
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from date', () => {
|
||||
const value = new Date(100)
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should preserve', () => {
|
||||
const value = 'foo'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
})
|
||||
52
test/runtime/value/cast/symbol.ts
Normal file
52
test/runtime/value/cast/symbol.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/Symbol', () => {
|
||||
const T = Type.Symbol()
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsTypeOf(result, 'symbol')
|
||||
})
|
||||
it('Should upcast from number', () => {
|
||||
const value = 0
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsTypeOf(result, 'symbol')
|
||||
})
|
||||
it('Should upcast from boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsTypeOf(result, 'symbol')
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsTypeOf(result, 'symbol')
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsTypeOf(result, 'symbol')
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsTypeOf(result, 'symbol')
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsTypeOf(result, 'symbol')
|
||||
})
|
||||
it('Should upcast from date', () => {
|
||||
const value = new Date(100)
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsTypeOf(result, 'symbol')
|
||||
})
|
||||
it('Should preserve', () => {
|
||||
const value = Symbol('hello')
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result.description, value.description)
|
||||
})
|
||||
})
|
||||
53
test/runtime/value/cast/template-literal.ts
Normal file
53
test/runtime/value/cast/template-literal.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/TemplateLiteral', () => {
|
||||
const T = Type.TemplateLiteral([Type.Literal('hello'), Type.Literal('world')])
|
||||
const E = 'helloworld'
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'world'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from number', () => {
|
||||
const value = 1
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from date', () => {
|
||||
const value = new Date(100)
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should preseve', () => {
|
||||
const value = 'helloworld'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, 'helloworld')
|
||||
})
|
||||
})
|
||||
73
test/runtime/value/cast/tuple.ts
Normal file
73
test/runtime/value/cast/tuple.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/Tuple', () => {
|
||||
const T = Type.Tuple([Type.Number(), Type.String()])
|
||||
const E = [0, '']
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from number', () => {
|
||||
const value = 1
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, [1, ''])
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from date', () => {
|
||||
const value = new Date(100)
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should preserve', () => {
|
||||
const value = [42, 'world']
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
it('Should upcast with empty', () => {
|
||||
const value = [] as any[]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should append with less than tuple length', () => {
|
||||
const value = [42]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, [42, ''])
|
||||
})
|
||||
it('Should truncate with greater than tuple length', () => {
|
||||
const value = [42, '', true]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, [42, ''])
|
||||
})
|
||||
it('Should preserve and patch invalid element', () => {
|
||||
const value = [{}, 'hello']
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, [0, 'hello'])
|
||||
})
|
||||
})
|
||||
53
test/runtime/value/cast/uint8array.ts
Normal file
53
test/runtime/value/cast/uint8array.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/Uint8Array', () => {
|
||||
const T = Type.Uint8Array({ default: new Uint8Array([0, 1, 2, 3]) })
|
||||
const E = new Uint8Array([0, 1, 2, 3])
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from number', () => {
|
||||
const value = 1
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from date', () => {
|
||||
const value = new Date(100)
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should preserve', () => {
|
||||
const value = new Uint8Array([6, 7, 8, 9, 10])
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
})
|
||||
53
test/runtime/value/cast/undefined.ts
Normal file
53
test/runtime/value/cast/undefined.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/Undefined', () => {
|
||||
const T = Type.Undefined()
|
||||
const E = undefined
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'world'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from number', () => {
|
||||
const value = 1
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from date', () => {
|
||||
const value = new Date(100)
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should preseve', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, undefined)
|
||||
})
|
||||
})
|
||||
435
test/runtime/value/cast/union.ts
Normal file
435
test/runtime/value/cast/union.ts
Normal file
@@ -0,0 +1,435 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/Union', () => {
|
||||
const A = Type.Object(
|
||||
{
|
||||
type: Type.Literal('A'),
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
z: Type.Number(),
|
||||
},
|
||||
{ additionalProperties: false },
|
||||
)
|
||||
const B = Type.Object(
|
||||
{
|
||||
type: Type.Literal('B'),
|
||||
a: Type.String(),
|
||||
b: Type.String(),
|
||||
c: Type.String(),
|
||||
},
|
||||
{ additionalProperties: false },
|
||||
)
|
||||
const T = Type.Union([A, B])
|
||||
const E = {
|
||||
type: 'A',
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0,
|
||||
}
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from number', () => {
|
||||
const value = 1
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from date', () => {
|
||||
const value = new Date(100)
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should preserve A', () => {
|
||||
const value = { type: 'A', x: 1, y: 2, z: 3 }
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
it('Should preserve B', () => {
|
||||
const value = { type: 'B', a: 'a', b: 'b', c: 'c' }
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
it('Should infer through heuristics #1', () => {
|
||||
const value = { type: 'A', a: 'a', b: 'b', c: 'c' }
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, { type: 'A', x: 0, y: 0, z: 0 })
|
||||
})
|
||||
it('Should infer through heuristics #2', () => {
|
||||
const value = { type: 'B', x: 1, y: 2, z: 3 }
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, { type: 'B', a: '', b: '', c: '' })
|
||||
})
|
||||
it('Should infer through heuristics #3', () => {
|
||||
const value = { type: 'A', a: 'a', b: 'b', c: null }
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, { type: 'A', x: 0, y: 0, z: 0 })
|
||||
})
|
||||
it('Should infer through heuristics #4', () => {
|
||||
const value = { type: 'B', x: 1, y: 2, z: {} }
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, { type: 'B', a: '', b: '', c: '' })
|
||||
})
|
||||
it('Should infer through heuristics #5', () => {
|
||||
const value = { type: 'B', x: 1, y: 2, z: null }
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, { type: 'B', a: '', b: '', c: '' })
|
||||
})
|
||||
it('Should infer through heuristics #6', () => {
|
||||
const value = { x: 1 }
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, { type: 'A', x: 1, y: 0, z: 0 })
|
||||
})
|
||||
it('Should infer through heuristics #7', () => {
|
||||
const value = { a: null } // property existing should contribute
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, { type: 'B', a: '', b: '', c: '' })
|
||||
})
|
||||
it('Should cast with default value (create)', () => {
|
||||
const result = Value.Cast(
|
||||
Type.Object({
|
||||
id: Type.Number(),
|
||||
value: Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')], { default: 'C' }),
|
||||
}),
|
||||
{
|
||||
id: 42,
|
||||
value: 'D',
|
||||
},
|
||||
)
|
||||
Assert.IsEqual(result, {
|
||||
id: 42,
|
||||
value: 'C',
|
||||
})
|
||||
})
|
||||
it('Should cast with default value (preserve)', () => {
|
||||
const result = Value.Cast(
|
||||
Type.Object({
|
||||
id: Type.Number(),
|
||||
value: Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')], { default: 'C' }),
|
||||
}),
|
||||
{
|
||||
id: 42,
|
||||
value: 'B',
|
||||
},
|
||||
)
|
||||
Assert.IsEqual(result, {
|
||||
id: 42,
|
||||
value: 'B',
|
||||
})
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// https://github.com/sinclairzx81/typebox/issues/880
|
||||
// ----------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
it('Should dereference union variants', () => {
|
||||
const A = Type.Object({ type: Type.Literal('A') }, { $id: 'A' })
|
||||
const B = Type.Object({ type: Type.Literal('B'), value: Type.Number() }, { $id: 'B' })
|
||||
const RA = Type.Union([A, B])
|
||||
const RB = Type.Union([Type.Ref('A'), Type.Ref('B')])
|
||||
// variant 0
|
||||
Assert.IsEqual(Value.Cast(RA, [A, B], { type: 'B' }), { type: 'B', value: 0 })
|
||||
Assert.IsEqual(Value.Cast(RB, [A, B], { type: 'B' }), { type: 'B', value: 0 })
|
||||
// variant 1
|
||||
Assert.IsEqual(Value.Cast(RA, [A, B], { type: 'A' }), { type: 'A' })
|
||||
Assert.IsEqual(Value.Cast(RB, [A, B], { type: 'A' }), { type: 'A' })
|
||||
})
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// ref: https://github.com/sinclairzx81/typebox/issues/1268
|
||||
// ------------------------------------------------------------------------
|
||||
it('should correctly score nested union types #1', () => {
|
||||
const A = Type.Union([
|
||||
Type.Union([
|
||||
Type.Object({
|
||||
type: Type.Literal('a'),
|
||||
name: Type.String(),
|
||||
in: Type.String(),
|
||||
}),
|
||||
Type.Object({
|
||||
type: Type.Literal('b'),
|
||||
description: Type.Optional(Type.String()),
|
||||
nested: Type.Object({
|
||||
a: Type.String(),
|
||||
b: Type.Optional(Type.String()),
|
||||
}),
|
||||
}),
|
||||
]),
|
||||
Type.Object({
|
||||
$ref: Type.String(),
|
||||
description: Type.Optional(Type.String()),
|
||||
}),
|
||||
])
|
||||
|
||||
Assert.IsEqual(
|
||||
Value.Cast(A, {
|
||||
type: 'b',
|
||||
description: 'Hello World',
|
||||
nested: {
|
||||
b: 'hello',
|
||||
},
|
||||
}),
|
||||
{
|
||||
type: 'b',
|
||||
description: 'Hello World',
|
||||
nested: { a: '', b: 'hello' },
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
it('should correctly score nested union types #2', () => {
|
||||
const A = Type.Union([
|
||||
Type.Union([
|
||||
Type.Object({
|
||||
prop1: Type.String(),
|
||||
prop2: Type.String(),
|
||||
prop3: Type.String(),
|
||||
}),
|
||||
Type.Object({
|
||||
prop1: Type.String(),
|
||||
prop4: Type.String(),
|
||||
prop5: Type.String(),
|
||||
}),
|
||||
]),
|
||||
Type.Union([
|
||||
Type.Object({
|
||||
prop6: Type.String(),
|
||||
prop7: Type.String(),
|
||||
prop8: Type.String(),
|
||||
}),
|
||||
Type.Object({
|
||||
prop1: Type.String(),
|
||||
prop9: Type.String(),
|
||||
prop10: Type.String(),
|
||||
}),
|
||||
]),
|
||||
])
|
||||
|
||||
// Picks the first union variant when the score is equal
|
||||
Assert.IsEqual(
|
||||
Value.Cast(A, {
|
||||
prop1: '',
|
||||
}),
|
||||
{
|
||||
prop1: '',
|
||||
prop2: '',
|
||||
prop3: '',
|
||||
},
|
||||
)
|
||||
|
||||
Assert.IsEqual(
|
||||
Value.Cast(A, {
|
||||
prop1: '',
|
||||
prop4: '',
|
||||
}),
|
||||
{
|
||||
prop1: '',
|
||||
prop4: '',
|
||||
prop5: '',
|
||||
},
|
||||
)
|
||||
|
||||
Assert.IsEqual(
|
||||
Value.Cast(A, {
|
||||
prop6: '',
|
||||
}),
|
||||
{
|
||||
prop6: '',
|
||||
prop7: '',
|
||||
prop8: '',
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
it('should correctly score nested union types #3', () => {
|
||||
const A = Type.Union([
|
||||
Type.Object({
|
||||
prop1: Type.String(),
|
||||
prop2: Type.String(),
|
||||
prop3: Type.String(),
|
||||
}),
|
||||
Type.Object({
|
||||
prop4: Type.String(),
|
||||
prop5: Type.String(),
|
||||
prop6: Type.String(),
|
||||
}),
|
||||
Type.Union([
|
||||
Type.Object({
|
||||
prop4: Type.String(),
|
||||
prop5: Type.String(),
|
||||
prop6: Type.String(),
|
||||
}),
|
||||
Type.Object({
|
||||
prop1: Type.String(),
|
||||
prop2: Type.String(),
|
||||
prop7: Type.String(),
|
||||
prop8: Type.String(),
|
||||
}),
|
||||
]),
|
||||
])
|
||||
|
||||
Assert.IsEqual(
|
||||
Value.Cast(A, {
|
||||
prop1: '',
|
||||
prop2: '',
|
||||
prop7: '',
|
||||
}),
|
||||
{
|
||||
prop1: '',
|
||||
prop2: '',
|
||||
prop7: '',
|
||||
prop8: '',
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
it('should correctly score nested union types #4', () => {
|
||||
const A = Type.Union([
|
||||
Type.Object({
|
||||
prop1: Type.String(),
|
||||
prop2: Type.String(),
|
||||
prop3: Type.String(),
|
||||
}),
|
||||
Type.Union([
|
||||
Type.Object({
|
||||
prop4: Type.String(),
|
||||
prop5: Type.String(),
|
||||
prop6: Type.String(),
|
||||
}),
|
||||
Type.Union([
|
||||
Type.Object({
|
||||
prop1: Type.String(),
|
||||
prop2: Type.String(),
|
||||
prop7: Type.String(),
|
||||
prop8: Type.String(),
|
||||
}),
|
||||
Type.Union([
|
||||
Type.Object({
|
||||
prop1: Type.String(),
|
||||
prop2: Type.String(),
|
||||
prop9: Type.String(),
|
||||
prop10: Type.String(),
|
||||
}),
|
||||
Type.Object({
|
||||
prop1: Type.String(),
|
||||
prop2: Type.String(),
|
||||
prop11: Type.String(),
|
||||
prop12: Type.String(),
|
||||
}),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
])
|
||||
|
||||
Assert.IsEqual(
|
||||
Value.Cast(A, {
|
||||
prop1: '',
|
||||
prop2: '',
|
||||
prop9: '',
|
||||
}),
|
||||
{
|
||||
prop1: '',
|
||||
prop2: '',
|
||||
prop9: '',
|
||||
prop10: '',
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// ref: https://github.com/sinclairzx81/typebox/issues/1292
|
||||
// ------------------------------------------------------------------------
|
||||
it('should correctly score object unions with shared properties #1', () => {
|
||||
const schema = Type.Union([
|
||||
Type.Object({
|
||||
summary: Type.Optional(Type.String()),
|
||||
description: Type.Optional(Type.String()),
|
||||
parameters: Type.Optional(Type.Array(Type.Any())),
|
||||
responses: Type.Optional(Type.Record(Type.String(), Type.Any())),
|
||||
requestBody: Type.Optional(Type.Any()),
|
||||
}),
|
||||
Type.Object({
|
||||
$ref: Type.String(),
|
||||
summary: Type.Optional(Type.String()),
|
||||
}),
|
||||
])
|
||||
|
||||
Assert.IsEqual(
|
||||
Value.Cast(schema, {
|
||||
summary: 'Test Summary',
|
||||
parameters: {},
|
||||
}),
|
||||
{
|
||||
summary: 'Test Summary',
|
||||
parameters: [],
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
it('should correctly score object unions with shared properties #2', () => {
|
||||
const A = Type.Union([
|
||||
Type.Object({
|
||||
prop1: Type.String(),
|
||||
prop2: Type.String(),
|
||||
prop3: Type.String(),
|
||||
}),
|
||||
Type.Object({
|
||||
prop1: Type.String(),
|
||||
prop2: Type.String(),
|
||||
prop4: Type.String(),
|
||||
prop5: Type.String(),
|
||||
prop6: Type.String(),
|
||||
prop7: Type.String(),
|
||||
prop8: Type.String(),
|
||||
prop9: Type.String(),
|
||||
prop10: Type.String(),
|
||||
}),
|
||||
])
|
||||
|
||||
Assert.IsEqual(
|
||||
Value.Cast(A, {
|
||||
prop1: '',
|
||||
prop2: '',
|
||||
prop7: '',
|
||||
}),
|
||||
{
|
||||
prop1: '',
|
||||
prop2: '',
|
||||
prop4: '',
|
||||
prop5: '',
|
||||
prop6: '',
|
||||
prop7: '',
|
||||
prop8: '',
|
||||
prop9: '',
|
||||
prop10: '',
|
||||
},
|
||||
)
|
||||
})
|
||||
})
|
||||
52
test/runtime/value/cast/unknown.ts
Normal file
52
test/runtime/value/cast/unknown.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/Unknown', () => {
|
||||
const T = Type.Unknown()
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
it('Should upcast from number', () => {
|
||||
const value = 1
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
it('Should upcast from boolean', () => {
|
||||
const value = false
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, value)
|
||||
})
|
||||
it('Should upcast from date', () => {
|
||||
const value = new Date(100)
|
||||
const result: any = Value.Cast(T, value)
|
||||
Assert.IsEqual(result.getTime(), 100)
|
||||
})
|
||||
it('Should preserve', () => {
|
||||
const value = { a: 1, b: 2 }
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, { a: 1, b: 2 })
|
||||
})
|
||||
})
|
||||
53
test/runtime/value/cast/void.ts
Normal file
53
test/runtime/value/cast/void.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/cast/Void', () => {
|
||||
const T = Type.Void()
|
||||
const E = undefined
|
||||
it('Should upcast from string', () => {
|
||||
const value = 'world'
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from number', () => {
|
||||
const value = 1
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from object', () => {
|
||||
const value = {}
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from array', () => {
|
||||
const value = [1]
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from null', () => {
|
||||
const value = null
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should upcast from date', () => {
|
||||
const value = new Date(100)
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, E)
|
||||
})
|
||||
it('Should preserve', () => {
|
||||
const value = undefined
|
||||
const result = Value.Cast(T, value)
|
||||
Assert.IsEqual(result, undefined)
|
||||
})
|
||||
})
|
||||
47
test/runtime/value/check/any.ts
Normal file
47
test/runtime/value/check/any.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Any', () => {
|
||||
const T = Type.Any()
|
||||
it('Should pass string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass number', () => {
|
||||
const value = 1
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass null', () => {
|
||||
const value = null
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass object', () => {
|
||||
const value = { a: 1 }
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass array', () => {
|
||||
const value = [1, 2]
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass Date', () => {
|
||||
const value = new Date()
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
})
|
||||
47
test/runtime/value/check/argument.ts
Normal file
47
test/runtime/value/check/argument.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Argument', () => {
|
||||
const T = Type.Argument(0)
|
||||
it('Should pass string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass number', () => {
|
||||
const value = 1
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass null', () => {
|
||||
const value = null
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass object', () => {
|
||||
const value = { a: 1 }
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass array', () => {
|
||||
const value = [1, 2]
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass Date', () => {
|
||||
const value = new Date()
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
})
|
||||
155
test/runtime/value/check/array.ts
Normal file
155
test/runtime/value/check/array.ts
Normal file
@@ -0,0 +1,155 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Array', () => {
|
||||
it('Should pass number array', () => {
|
||||
const T = Type.Array(Type.Number())
|
||||
const value = [1, 2, 3]
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should fail number array', () => {
|
||||
const T = Type.Array(Type.Number())
|
||||
const value = ['a', 'b', 'c']
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should pass object array', () => {
|
||||
const T = Type.Array(Type.Object({ x: Type.Number() }))
|
||||
const value = [{ x: 1 }, { x: 1 }, { x: 1 }]
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should fail object array', () => {
|
||||
const T = Type.Array(Type.Object({ x: Type.Number() }))
|
||||
const value = [{ x: 1 }, { x: 1 }, 1]
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail Date', () => {
|
||||
const value = new Date()
|
||||
const result = Value.Check(Type.Array(Type.Any()), value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should validate array with unique primitive items', () => {
|
||||
const T = Type.Array(Type.Number(), { uniqueItems: true })
|
||||
const result = Value.Check(T, [0, 1, 2])
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should not validate array with non-unique primitive items', () => {
|
||||
const T = Type.Array(Type.Number(), { uniqueItems: true })
|
||||
const result = Value.Check(T, [0, 0, 2])
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should validate array with unique object items', () => {
|
||||
const T = Type.Array(Type.Object({ x: Type.Number(), y: Type.Number() }), { uniqueItems: true })
|
||||
const result = Value.Check(T, [
|
||||
{ x: 1, y: 1 },
|
||||
{ x: 2, y: 2 },
|
||||
{ x: 3, y: 3 },
|
||||
])
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should not validate array with non-unique object items', () => {
|
||||
const T = Type.Array(Type.Object({ x: Type.Number(), y: Type.Number() }), { uniqueItems: true })
|
||||
const result = Value.Check(T, [
|
||||
{ x: 1, y: 1 },
|
||||
{ x: 1, y: 1 },
|
||||
{ x: 3, y: 3 },
|
||||
])
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
// ---------------------------------------------------------
|
||||
// Contains
|
||||
// ---------------------------------------------------------
|
||||
it('Should validate for contains', () => {
|
||||
const T = Type.Array(Type.Number(), { contains: Type.Literal(1) })
|
||||
Assert.IsTrue(Value.Check(T, [1]))
|
||||
Assert.IsTrue(Value.Check(T, [1, 2]))
|
||||
Assert.IsFalse(Value.Check(T, []))
|
||||
Assert.IsFalse(Value.Check(T, [2]))
|
||||
})
|
||||
it('Should validate for minContains', () => {
|
||||
const T = Type.Array(Type.Number(), { contains: Type.Literal(1), minContains: 3 })
|
||||
Assert.IsTrue(Value.Check(T, [1, 1, 1, 2]))
|
||||
Assert.IsTrue(Value.Check(T, [2, 1, 1, 1, 2]))
|
||||
Assert.IsTrue(Value.Check(T, [1, 1, 1]))
|
||||
Assert.IsFalse(Value.Check(T, []))
|
||||
Assert.IsFalse(Value.Check(T, [1, 1]))
|
||||
Assert.IsFalse(Value.Check(T, [2]))
|
||||
})
|
||||
it('Should validate for maxContains', () => {
|
||||
const T = Type.Array(Type.Number(), { contains: Type.Literal(1), maxContains: 3 })
|
||||
Assert.IsTrue(Value.Check(T, [1, 1, 1]))
|
||||
Assert.IsTrue(Value.Check(T, [1, 1]))
|
||||
Assert.IsTrue(Value.Check(T, [2, 2, 2, 2, 1, 1, 1]))
|
||||
Assert.IsFalse(Value.Check(T, [1, 1, 1, 1]))
|
||||
})
|
||||
it('Should validate for minContains and maxContains', () => {
|
||||
const T = Type.Array(Type.Number(), { contains: Type.Literal(1), minContains: 3, maxContains: 5 })
|
||||
Assert.IsFalse(Value.Check(T, [1, 1]))
|
||||
Assert.IsTrue(Value.Check(T, [1, 1, 1]))
|
||||
Assert.IsTrue(Value.Check(T, [1, 1, 1, 1]))
|
||||
Assert.IsTrue(Value.Check(T, [1, 1, 1, 1, 1]))
|
||||
Assert.IsFalse(Value.Check(T, [1, 1, 1, 1, 1, 1]))
|
||||
})
|
||||
it('Should not validate minContains and maxContains when contains is unspecified', () => {
|
||||
const T = Type.Array(Type.Number(), { minContains: 3, maxContains: 5 })
|
||||
Assert.IsFalse(Value.Check(T, [1, 1]))
|
||||
Assert.IsFalse(Value.Check(T, [1, 1, 1]))
|
||||
Assert.IsFalse(Value.Check(T, [1, 1, 1, 1]))
|
||||
Assert.IsFalse(Value.Check(T, [1, 1, 1, 1, 1]))
|
||||
Assert.IsFalse(Value.Check(T, [1, 1, 1, 1, 1, 1]))
|
||||
})
|
||||
it('Should produce illogical schema when contains is not sub type of items', () => {
|
||||
const T = Type.Array(Type.Number(), { contains: Type.String(), minContains: 3, maxContains: 5 })
|
||||
Assert.IsFalse(Value.Check(T, [1, 1]))
|
||||
Assert.IsFalse(Value.Check(T, [1, 1, 1]))
|
||||
Assert.IsFalse(Value.Check(T, [1, 1, 1, 1]))
|
||||
Assert.IsFalse(Value.Check(T, [1, 1, 1, 1, 1]))
|
||||
Assert.IsFalse(Value.Check(T, [1, 1, 1, 1, 1, 1]))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Issue: https://github.com/sinclairzx81/typebox/discussions/607
|
||||
// ----------------------------------------------------------------
|
||||
it('Should correctly handle undefined array properties', () => {
|
||||
const Answer = Type.Object({
|
||||
text: Type.String(),
|
||||
isCorrect: Type.Boolean(),
|
||||
})
|
||||
const Question = Type.Object({
|
||||
text: Type.String(),
|
||||
options: Type.Array(Answer, {
|
||||
minContains: 1,
|
||||
maxContains: 1,
|
||||
contains: Type.Object({
|
||||
text: Type.String(),
|
||||
isCorrect: Type.Literal(true),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
Assert.IsFalse(Value.Check(Question, { text: 'A' }))
|
||||
Assert.IsFalse(Value.Check(Question, { text: 'A', options: [] }))
|
||||
Assert.IsTrue(Value.Check(Question, { text: 'A', options: [{ text: 'A', isCorrect: true }] }))
|
||||
Assert.IsTrue(
|
||||
Value.Check(Question, {
|
||||
text: 'A',
|
||||
options: [
|
||||
{ text: 'A', isCorrect: true },
|
||||
{ text: 'B', isCorrect: false },
|
||||
],
|
||||
}),
|
||||
)
|
||||
Assert.IsFalse(Value.Check(Question, { text: 'A', options: [{ text: 'A', isCorrect: false }] }))
|
||||
Assert.IsFalse(
|
||||
Value.Check(Question, {
|
||||
text: 'A',
|
||||
options: [
|
||||
{ text: 'A', isCorrect: true },
|
||||
{ text: 'B', isCorrect: true },
|
||||
],
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
24
test/runtime/value/check/async-iterator.ts
Normal file
24
test/runtime/value/check/async-iterator.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/AsyncIterator', () => {
|
||||
it('Should pass async iterator 1', () => {
|
||||
async function* f() {}
|
||||
const T = Type.AsyncIterator(Type.Any())
|
||||
const result = Value.Check(T, f())
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass async iterator 2', () => {
|
||||
const T = Type.AsyncIterator(Type.Any())
|
||||
const result = Value.Check(T, {
|
||||
[Symbol.asyncIterator]: () => {},
|
||||
})
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass async iterator', () => {
|
||||
const T = Type.AsyncIterator(Type.Any())
|
||||
const result = Value.Check(T, {})
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
})
|
||||
41
test/runtime/value/check/bigint.ts
Normal file
41
test/runtime/value/check/bigint.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/BigInt', () => {
|
||||
const T = Type.BigInt()
|
||||
it('Should not validate NaN', () => {
|
||||
const T = Type.BigInt()
|
||||
const result = Value.Check(T, NaN)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should not validate +Infinity', () => {
|
||||
const T = Type.BigInt()
|
||||
const result = Value.Check(T, Infinity)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should not validate -Infinity', () => {
|
||||
const T = Type.BigInt()
|
||||
const result = Value.Check(T, -Infinity)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail integer', () => {
|
||||
const value = 1
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail integer', () => {
|
||||
const value = 3.14
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail Date', () => {
|
||||
const value = new Date()
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should pass bigint', () => {
|
||||
const result = Value.Check(T, BigInt(0))
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
})
|
||||
47
test/runtime/value/check/boolean.ts
Normal file
47
test/runtime/value/check/boolean.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Boolean', () => {
|
||||
const T = Type.Boolean()
|
||||
it('Should fail string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail number', () => {
|
||||
const value = 1
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should pass boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should fail null', () => {
|
||||
const value = null
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail object', () => {
|
||||
const value = { a: 1 }
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail array', () => {
|
||||
const value = [1, 2]
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail Date', () => {
|
||||
const value = new Date()
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
})
|
||||
77
test/runtime/value/check/composite.ts
Normal file
77
test/runtime/value/check/composite.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Composite', () => {
|
||||
const A = Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
z: Type.Number(),
|
||||
})
|
||||
const B = Type.Object({
|
||||
a: Type.String(),
|
||||
b: Type.String(),
|
||||
c: Type.String(),
|
||||
})
|
||||
const T = Type.Composite([A, B])
|
||||
it('Should pass composite', () => {
|
||||
const value = {
|
||||
x: 1,
|
||||
y: 1,
|
||||
z: 1,
|
||||
a: '1',
|
||||
b: '1',
|
||||
c: '1',
|
||||
}
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should fail intersect with invalid property', () => {
|
||||
const value = {
|
||||
x: true,
|
||||
y: 1,
|
||||
z: 1,
|
||||
a: '1',
|
||||
b: '1',
|
||||
c: '1',
|
||||
}
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail intersect with missing property', () => {
|
||||
const value = {
|
||||
y: 1,
|
||||
z: 1,
|
||||
a: '1',
|
||||
b: '1',
|
||||
c: '1',
|
||||
}
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail intersect with primitive value', () => {
|
||||
const value = 1
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should pass intersect with optional properties', () => {
|
||||
const A = Type.Object({
|
||||
x: Type.Optional(Type.Number()),
|
||||
y: Type.Optional(Type.Number()),
|
||||
z: Type.Optional(Type.Number()),
|
||||
})
|
||||
const B = Type.Object({
|
||||
a: Type.String(),
|
||||
b: Type.String(),
|
||||
c: Type.String(),
|
||||
})
|
||||
const T = Type.Composite([A, B])
|
||||
const value = {
|
||||
a: '1',
|
||||
b: '1',
|
||||
c: '1',
|
||||
}
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
})
|
||||
42
test/runtime/value/check/const.ts
Normal file
42
test/runtime/value/check/const.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Const', () => {
|
||||
it('Should validate 1', () => {
|
||||
const T = Type.Const(1)
|
||||
Assert.IsTrue(Value.Check(T, 1))
|
||||
})
|
||||
it('Should validate 2', () => {
|
||||
const T = Type.Const('hello')
|
||||
Assert.IsTrue(Value.Check(T, 'hello'))
|
||||
})
|
||||
it('Should validate 3', () => {
|
||||
const T = Type.Const(true)
|
||||
Assert.IsTrue(Value.Check(T, true))
|
||||
})
|
||||
it('Should validate 4', () => {
|
||||
const T = Type.Const({ x: 1, y: 2 })
|
||||
Assert.IsTrue(Value.Check(T, { x: 1, y: 2 }))
|
||||
})
|
||||
it('Should validate 5', () => {
|
||||
const T = Type.Const([1, 2, 3])
|
||||
Assert.IsTrue(Value.Check(T, [1, 2, 3]))
|
||||
})
|
||||
it('Should validate 6', () => {
|
||||
const T = Type.Const([1, true, 'hello'])
|
||||
Assert.IsTrue(Value.Check(T, [1, true, 'hello']))
|
||||
})
|
||||
it('Should validate 7', () => {
|
||||
const T = Type.Const({
|
||||
x: [1, 2, 3, 4],
|
||||
y: { x: 1, y: 2, z: 3 },
|
||||
})
|
||||
Assert.IsTrue(
|
||||
Value.Check(T, {
|
||||
x: [1, 2, 3, 4],
|
||||
y: { x: 1, y: 2, z: 3 },
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
87
test/runtime/value/check/constructor.ts
Normal file
87
test/runtime/value/check/constructor.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Constructor', () => {
|
||||
it('Should validate constructor 1', () => {
|
||||
const T = Type.Constructor([], Type.Object({}))
|
||||
Assert.IsTrue(Value.Check(T, class {}))
|
||||
})
|
||||
it('Should validate constructor 2', () => {
|
||||
const T = Type.Constructor([Type.Number()], Type.Object({}))
|
||||
// note: constructor arguments are non-checkable
|
||||
Assert.IsTrue(Value.Check(T, class {}))
|
||||
})
|
||||
it('Should validate constructor 3', () => {
|
||||
const T = Type.Constructor(
|
||||
[Type.Number()],
|
||||
Type.Object({
|
||||
method: Type.Function([], Type.Void()),
|
||||
}),
|
||||
)
|
||||
Assert.IsTrue(
|
||||
Value.Check(
|
||||
T,
|
||||
class {
|
||||
method() {}
|
||||
},
|
||||
),
|
||||
)
|
||||
})
|
||||
it('Should validate constructor 4', () => {
|
||||
const T = Type.Constructor(
|
||||
[Type.Number()],
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
z: Type.Number(),
|
||||
}),
|
||||
)
|
||||
Assert.IsTrue(
|
||||
Value.Check(
|
||||
T,
|
||||
class {
|
||||
get x() {
|
||||
return 1
|
||||
}
|
||||
get y() {
|
||||
return 1
|
||||
}
|
||||
get z() {
|
||||
return 1
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
})
|
||||
it('Should not validate constructor 1', () => {
|
||||
const T = Type.Constructor([Type.Number()], Type.Object({}))
|
||||
Assert.IsFalse(Value.Check(T, 1))
|
||||
})
|
||||
it('Should not validate constructor 2', () => {
|
||||
const T = Type.Constructor(
|
||||
[Type.Number()],
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
z: Type.Number(),
|
||||
}),
|
||||
)
|
||||
Assert.IsFalse(
|
||||
Value.Check(
|
||||
T,
|
||||
class {
|
||||
get x() {
|
||||
return null
|
||||
}
|
||||
get y() {
|
||||
return null
|
||||
}
|
||||
get z() {
|
||||
return null
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
})
|
||||
})
|
||||
87
test/runtime/value/check/date.ts
Normal file
87
test/runtime/value/check/date.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Date', () => {
|
||||
const T = Type.Date()
|
||||
it('Should fail string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsFalse(result)
|
||||
})
|
||||
it('Should fail number', () => {
|
||||
const value = 1
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsFalse(result)
|
||||
})
|
||||
it('Should fail boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsFalse(result)
|
||||
})
|
||||
it('Should fail null', () => {
|
||||
const value = null
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsFalse(result)
|
||||
})
|
||||
it('Should fail undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsFalse(result)
|
||||
})
|
||||
it('Should fail object', () => {
|
||||
const value = { a: 1 }
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsFalse(result)
|
||||
})
|
||||
it('Should fail array', () => {
|
||||
const value = [1, 2]
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsFalse(result)
|
||||
})
|
||||
it('Should pass Date', () => {
|
||||
const value = new Date()
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsTrue(result)
|
||||
})
|
||||
it('Should not validate Date if is invalid', () => {
|
||||
const value = new Date('not-a-valid-date')
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsFalse(result)
|
||||
})
|
||||
it('Should validate Date minimumTimestamp', () => {
|
||||
const T = Type.Date({ minimumTimestamp: 10 })
|
||||
const R1 = Value.Check(T, new Date(9))
|
||||
const R2 = Value.Check(T, new Date(10))
|
||||
Assert.IsFalse(R1)
|
||||
Assert.IsTrue(R2)
|
||||
})
|
||||
it('Should validate Date maximumTimestamp', () => {
|
||||
const T = Type.Date({ maximumTimestamp: 10 })
|
||||
const R1 = Value.Check(T, new Date(11))
|
||||
const R2 = Value.Check(T, new Date(10))
|
||||
Assert.IsFalse(R1)
|
||||
Assert.IsTrue(R2)
|
||||
})
|
||||
it('Should validate Date exclusiveMinimumTimestamp', () => {
|
||||
const T = Type.Date({ exclusiveMinimumTimestamp: 10 })
|
||||
const R1 = Value.Check(T, new Date(10))
|
||||
const R2 = Value.Check(T, new Date(11))
|
||||
Assert.IsFalse(R1)
|
||||
Assert.IsTrue(R2)
|
||||
})
|
||||
it('Should validate Date exclusiveMaximumTimestamp', () => {
|
||||
const T = Type.Date({ exclusiveMaximumTimestamp: 10 })
|
||||
const R1 = Value.Check(T, new Date(10))
|
||||
const R2 = Value.Check(T, new Date(9))
|
||||
Assert.IsFalse(R1)
|
||||
Assert.IsTrue(R2)
|
||||
})
|
||||
it('Should validate Date multipleOfTimestamp', () => {
|
||||
const T = Type.Date({ multipleOfTimestamp: 2 })
|
||||
const R1 = Value.Check(T, new Date(1))
|
||||
const R2 = Value.Check(T, new Date(2))
|
||||
Assert.IsFalse(R1)
|
||||
Assert.IsTrue(R2)
|
||||
})
|
||||
})
|
||||
31
test/runtime/value/check/enum.ts
Normal file
31
test/runtime/value/check/enum.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Enum', () => {
|
||||
enum Foo {
|
||||
A = 1,
|
||||
B = 2,
|
||||
}
|
||||
const T = Type.Enum(Foo)
|
||||
it('Should pass enum option A', () => {
|
||||
const value = Foo.A
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass enum option B', () => {
|
||||
const value = Foo.A
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should fail unknown value', () => {
|
||||
const value = 'unknown'
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail Date', () => {
|
||||
const value = new Date()
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
})
|
||||
28
test/runtime/value/check/function.ts
Normal file
28
test/runtime/value/check/function.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Function', () => {
|
||||
it('Should validate function 1', () => {
|
||||
const T = Type.Function([Type.Number()], Type.Number())
|
||||
Assert.IsTrue(Value.Check(T, function () {}))
|
||||
})
|
||||
it('Should validate function 2', () => {
|
||||
const T = Type.Function([Type.Number()], Type.Number())
|
||||
// note: validation only checks typeof 'function'
|
||||
Assert.IsTrue(Value.Check(T, function (a: string, b: string, c: string, d: string) {}))
|
||||
})
|
||||
it('Should validate function 3', () => {
|
||||
const T = Type.Function([Type.Number()], Type.Number())
|
||||
// note: validation only checks typeof 'function'
|
||||
Assert.IsTrue(
|
||||
Value.Check(T, function () {
|
||||
return 'not-a-number'
|
||||
}),
|
||||
)
|
||||
})
|
||||
it('Should not validate function', () => {
|
||||
const T = Type.Function([Type.Number()], Type.Number())
|
||||
Assert.IsFalse(Value.Check(T, 1))
|
||||
})
|
||||
})
|
||||
37
test/runtime/value/check/index.ts
Normal file
37
test/runtime/value/check/index.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import './any'
|
||||
import './argument'
|
||||
import './array'
|
||||
import './async-iterator'
|
||||
import './bigint'
|
||||
import './boolean'
|
||||
import './composite'
|
||||
import './const'
|
||||
import './constructor'
|
||||
import './date'
|
||||
import './enum'
|
||||
import './function'
|
||||
import './integer'
|
||||
import './intersect'
|
||||
import './iterator'
|
||||
import './keyof'
|
||||
import './kind'
|
||||
import './literal'
|
||||
import './module'
|
||||
import './never'
|
||||
import './not'
|
||||
import './null'
|
||||
import './number'
|
||||
import './object'
|
||||
import './recursive'
|
||||
import './ref'
|
||||
import './record'
|
||||
import './regexp'
|
||||
import './string'
|
||||
import './symbol'
|
||||
import './template-literal'
|
||||
import './tuple'
|
||||
import './uint8array'
|
||||
import './undefined'
|
||||
import './union'
|
||||
import './unknown'
|
||||
import './void'
|
||||
37
test/runtime/value/check/integer.ts
Normal file
37
test/runtime/value/check/integer.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Integer', () => {
|
||||
const T = Type.Integer()
|
||||
it('Should not validate NaN', () => {
|
||||
const T = Type.Integer()
|
||||
const result = Value.Check(T, NaN)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should not validate +Infinity', () => {
|
||||
const T = Type.Integer()
|
||||
const result = Value.Check(T, Infinity)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should not validate -Infinity', () => {
|
||||
const T = Type.Integer()
|
||||
const result = Value.Check(T, -Infinity)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should pass integer', () => {
|
||||
const value = 1
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should fail integer', () => {
|
||||
const value = 3.14
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail Date', () => {
|
||||
const value = new Date()
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
})
|
||||
219
test/runtime/value/check/intersect.ts
Normal file
219
test/runtime/value/check/intersect.ts
Normal file
@@ -0,0 +1,219 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Intersect', () => {
|
||||
it('Should intersect number and number', () => {
|
||||
const A = Type.Number()
|
||||
const B = Type.Number()
|
||||
const T = Type.Intersect([A, B], {})
|
||||
Assert.IsEqual(Value.Check(T, 1), true)
|
||||
})
|
||||
it('Should not intersect string and number', () => {
|
||||
const A = Type.String()
|
||||
const B = Type.Number()
|
||||
const T = Type.Intersect([A, B], {})
|
||||
Assert.IsEqual(Value.Check(T, 1), false)
|
||||
Assert.IsEqual(Value.Check(T, '1'), false)
|
||||
})
|
||||
it('Should intersect two objects', () => {
|
||||
const A = Type.Object({ x: Type.Number() })
|
||||
const B = Type.Object({ y: Type.Number() })
|
||||
const T = Type.Intersect([A, B], {})
|
||||
Assert.IsEqual(Value.Check(T, { x: 1, y: 1 }), true)
|
||||
})
|
||||
it('Should not intersect two objects with internal additionalProperties false', () => {
|
||||
const A = Type.Object({ x: Type.Number() }, { additionalProperties: false })
|
||||
const B = Type.Object({ y: Type.Number() }, { additionalProperties: false })
|
||||
const T = Type.Intersect([A, B], {})
|
||||
Assert.IsEqual(Value.Check(T, { x: 1, y: 1 }), false)
|
||||
})
|
||||
it('Should intersect two objects and mandate required properties', () => {
|
||||
const A = Type.Object({ x: Type.Number() })
|
||||
const B = Type.Object({ y: Type.Number() })
|
||||
const T = Type.Intersect([A, B], {})
|
||||
Assert.IsEqual(Value.Check(T, { x: 1, y: 1 }), true)
|
||||
Assert.IsEqual(Value.Check(T, { x: 1 }), false)
|
||||
Assert.IsEqual(Value.Check(T, { x: 1 }), false)
|
||||
})
|
||||
it('Should intersect two objects with unevaluated properties', () => {
|
||||
const A = Type.Object({ x: Type.Number() })
|
||||
const B = Type.Object({ y: Type.Number() })
|
||||
const T = Type.Intersect([A, B], {})
|
||||
Assert.IsEqual(Value.Check(T, { x: 1, y: 1, z: 1 }), true)
|
||||
})
|
||||
it('Should intersect two objects and restrict unevaluated properties', () => {
|
||||
const A = Type.Object({ x: Type.Number() })
|
||||
const B = Type.Object({ y: Type.Number() })
|
||||
const T = Type.Intersect([A, B], { unevaluatedProperties: false })
|
||||
Assert.IsEqual(Value.Check(T, { x: 1, y: 1, z: 1 }), false)
|
||||
})
|
||||
it('Should intersect two objects and allow unevaluated properties of number', () => {
|
||||
const A = Type.Object({ x: Type.Number() })
|
||||
const B = Type.Object({ y: Type.Number() })
|
||||
const T = Type.Intersect([A, B], { unevaluatedProperties: Type.Number() })
|
||||
Assert.IsEqual(Value.Check(T, { x: 1, y: 2, z: 3 }), true)
|
||||
Assert.IsEqual(Value.Check(T, { x: 1, y: 2, z: '1' }), false)
|
||||
})
|
||||
it('Should intersect two union objects with overlapping properties of the same type', () => {
|
||||
const A = Type.Union([Type.Object({ x: Type.Number() })])
|
||||
const B = Type.Union([Type.Object({ x: Type.Number() })])
|
||||
const T = Type.Intersect([A, B])
|
||||
Assert.IsEqual(Value.Check(T, { x: 1 }), true)
|
||||
Assert.IsEqual(Value.Check(T, { x: '1' }), false)
|
||||
})
|
||||
it('Should not intersect two union objects with overlapping properties of varying types', () => {
|
||||
const A = Type.Union([Type.Object({ x: Type.Number() })])
|
||||
const B = Type.Union([Type.Object({ x: Type.String() })])
|
||||
const T = Type.Intersect([A, B])
|
||||
Assert.IsEqual(Value.Check(T, { x: 1 }), false)
|
||||
Assert.IsEqual(Value.Check(T, { x: '1' }), false)
|
||||
})
|
||||
it('Should intersect two union objects with non-overlapping properties', () => {
|
||||
const A = Type.Union([Type.Object({ x: Type.Number() })])
|
||||
const B = Type.Union([Type.Object({ y: Type.Number() })])
|
||||
const T = Type.Intersect([A, B])
|
||||
Assert.IsEqual(Value.Check(T, { x: 1, y: 1 }), true)
|
||||
})
|
||||
it('Should not intersect two union objects with non-overlapping properties for additionalProperties false', () => {
|
||||
const A = Type.Union([Type.Object({ x: Type.Number() }, { additionalProperties: false })])
|
||||
const B = Type.Union([Type.Object({ y: Type.Number() }, { additionalProperties: false })])
|
||||
const T = Type.Intersect([A, B])
|
||||
Assert.IsEqual(Value.Check(T, { x: 1, y: 1 }), false)
|
||||
})
|
||||
it('unevaluatedProperties with Record 1', () => {
|
||||
const T = Type.Intersect(
|
||||
[
|
||||
Type.Record(Type.Number(), Type.String()),
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
],
|
||||
{
|
||||
unevaluatedProperties: false,
|
||||
},
|
||||
)
|
||||
Assert.IsEqual(Value.Check(T, { x: 1, y: 2 }), true)
|
||||
})
|
||||
it('unevaluatedProperties with Record 2', () => {
|
||||
const T = Type.Intersect(
|
||||
[
|
||||
Type.Record(Type.Number(), Type.String()),
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
],
|
||||
{
|
||||
unevaluatedProperties: false,
|
||||
},
|
||||
)
|
||||
Assert.IsEqual(Value.Check(T, { x: 1, y: 2, 0: 'hello' }), true)
|
||||
})
|
||||
it('unevaluatedProperties with Record 3', () => {
|
||||
const T = Type.Intersect(
|
||||
[
|
||||
Type.Record(Type.Number(), Type.String()),
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
],
|
||||
{
|
||||
unevaluatedProperties: false,
|
||||
},
|
||||
)
|
||||
Assert.IsEqual(Value.Check(T, { x: 1, y: 2, 0: 1 }), false)
|
||||
})
|
||||
it('unevaluatedProperties with Record 4', () => {
|
||||
const T = Type.Intersect(
|
||||
[
|
||||
Type.Record(Type.Number(), Type.String()),
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
],
|
||||
{
|
||||
unevaluatedProperties: Type.Boolean(),
|
||||
},
|
||||
)
|
||||
Assert.IsEqual(Value.Check(T, { x: 1, y: 2 }), true)
|
||||
})
|
||||
it('unevaluatedProperties with Record 5', () => {
|
||||
const T = Type.Intersect(
|
||||
[
|
||||
Type.Record(Type.Number(), Type.String()),
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
],
|
||||
{
|
||||
unevaluatedProperties: Type.Boolean(),
|
||||
},
|
||||
)
|
||||
Assert.IsEqual(Value.Check(T, { x: 1, y: 2, z: true }), true)
|
||||
})
|
||||
it('unevaluatedProperties with Record 6', () => {
|
||||
const T = Type.Intersect(
|
||||
[
|
||||
Type.Record(Type.Number(), Type.String()),
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
],
|
||||
{
|
||||
unevaluatedProperties: Type.Boolean(),
|
||||
},
|
||||
)
|
||||
Assert.IsEqual(Value.Check(T, { x: 1, y: 2, z: 1 }), false)
|
||||
})
|
||||
it('unevaluatedProperties with Record 7', () => {
|
||||
const T = Type.Intersect(
|
||||
[
|
||||
Type.Record(Type.Number(), Type.String()),
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
],
|
||||
{
|
||||
unevaluatedProperties: Type.Boolean(),
|
||||
},
|
||||
)
|
||||
Assert.IsEqual(Value.Check(T, { x: 1, y: 2, 0: '' }), true)
|
||||
})
|
||||
it('unevaluatedProperties with Record 8', () => {
|
||||
const T = Type.Intersect(
|
||||
[
|
||||
Type.Record(Type.Number(), Type.String()),
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
],
|
||||
{
|
||||
unevaluatedProperties: Type.Boolean(),
|
||||
},
|
||||
)
|
||||
Assert.IsEqual(Value.Check(T, { x: 1, y: 2, 0: '', z: true }), true)
|
||||
})
|
||||
it('unevaluatedProperties with Record 9', () => {
|
||||
const T = Type.Intersect(
|
||||
[
|
||||
Type.Record(Type.Number(), Type.String()),
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
],
|
||||
{
|
||||
unevaluatedProperties: Type.Boolean(),
|
||||
},
|
||||
)
|
||||
Assert.IsEqual(Value.Check(T, { x: 1, y: 2, 0: '', z: 1 }), false)
|
||||
})
|
||||
})
|
||||
24
test/runtime/value/check/iterator.ts
Normal file
24
test/runtime/value/check/iterator.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Iterator', () => {
|
||||
it('Should pass iterator 1', () => {
|
||||
function* f() {}
|
||||
const T = Type.Iterator(Type.Any())
|
||||
const result = Value.Check(T, f())
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass iterator 2', () => {
|
||||
const T = Type.Iterator(Type.Any())
|
||||
const result = Value.Check(T, {
|
||||
[Symbol.iterator]: () => {},
|
||||
})
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass iterator', () => {
|
||||
const T = Type.Iterator(Type.Any())
|
||||
const result = Value.Check(T, {})
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
})
|
||||
33
test/runtime/value/check/keyof.ts
Normal file
33
test/runtime/value/check/keyof.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/KeyOf', () => {
|
||||
const T = Type.KeyOf(
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
z: Type.Number(),
|
||||
}),
|
||||
)
|
||||
it('Should pass keyof', () => {
|
||||
const value = 'x'
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should fail keyof', () => {
|
||||
const value = 'w'
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail keyof with undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail keyof with null', () => {
|
||||
const value = null
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
})
|
||||
107
test/runtime/value/check/kind.ts
Normal file
107
test/runtime/value/check/kind.ts
Normal file
@@ -0,0 +1,107 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { TypeRegistry, Type, Kind, TSchema } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert'
|
||||
|
||||
describe('value/check/Kind', () => {
|
||||
// ------------------------------------------------------------
|
||||
// Fixtures
|
||||
// ------------------------------------------------------------
|
||||
beforeEach(() => TypeRegistry.Set('PI', (_, value) => value === Math.PI))
|
||||
afterEach(() => TypeRegistry.Delete('PI'))
|
||||
// ------------------------------------------------------------
|
||||
// Tests
|
||||
// ------------------------------------------------------------
|
||||
it('Should validate', () => {
|
||||
const T = Type.Unsafe({ [Kind]: 'PI' })
|
||||
Assert.IsTrue(Value.Check(T, Math.PI))
|
||||
})
|
||||
it('Should not validate', () => {
|
||||
const T = Type.Unsafe({ [Kind]: 'PI' })
|
||||
Assert.IsFalse(Value.Check(T, Math.PI * 2))
|
||||
})
|
||||
it('Should validate in object', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Unsafe({ [Kind]: 'PI' }),
|
||||
})
|
||||
Assert.IsTrue(Value.Check(T, { x: Math.PI }))
|
||||
})
|
||||
it('Should not validate in object', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Unsafe({ [Kind]: 'PI' }),
|
||||
})
|
||||
Assert.IsFalse(Value.Check(T, { x: Math.PI * 2 }))
|
||||
})
|
||||
it('Should validate in array', () => {
|
||||
const T = Type.Array(Type.Unsafe({ [Kind]: 'PI' }))
|
||||
Assert.IsTrue(Value.Check(T, [Math.PI]))
|
||||
})
|
||||
it('Should not validate in array', () => {
|
||||
const T = Type.Array(Type.Unsafe({ [Kind]: 'PI' }))
|
||||
Assert.IsFalse(Value.Check(T, [Math.PI * 2]))
|
||||
})
|
||||
it('Should validate in tuple', () => {
|
||||
const T = Type.Tuple([Type.Unsafe({ [Kind]: 'PI' })])
|
||||
Assert.IsTrue(Value.Check(T, [Math.PI]))
|
||||
})
|
||||
it('Should not validate in tuple', () => {
|
||||
const T = Type.Tuple([Type.Unsafe({ [Kind]: 'PI' })])
|
||||
Assert.IsFalse(Value.Check(T, [Math.PI * 2]))
|
||||
})
|
||||
// ------------------------------------------------------------
|
||||
// Instances
|
||||
// ------------------------------------------------------------
|
||||
it('Should receive kind instance on registry callback', () => {
|
||||
const stack: string[] = []
|
||||
TypeRegistry.Set('Kind', (schema: unknown) => {
|
||||
// prettier-ignore
|
||||
return (typeof schema === 'object' && schema !== null && Kind in schema && schema[Kind] === 'Kind' && '$id' in schema && typeof schema.$id === 'string')
|
||||
? (() => { stack.push(schema.$id); return true })()
|
||||
: false
|
||||
})
|
||||
const A = { [Kind]: 'Kind', $id: 'A' } as TSchema
|
||||
const B = { [Kind]: 'Kind', $id: 'B' } as TSchema
|
||||
const T = Type.Object({ a: A, b: B })
|
||||
const R = Value.Check(T, { a: null, b: null })
|
||||
Assert.IsTrue(R)
|
||||
Assert.IsEqual(stack[0], 'A')
|
||||
Assert.IsEqual(stack[1], 'B')
|
||||
TypeRegistry.Delete('Kind')
|
||||
})
|
||||
it('Should retain kind instances on subsequent check', () => {
|
||||
let stack: string[] = []
|
||||
TypeRegistry.Set('Kind', (schema: unknown) => {
|
||||
// prettier-ignore
|
||||
return (typeof schema === 'object' && schema !== null && Kind in schema && schema[Kind] === 'Kind' && '$id' in schema && typeof schema.$id === 'string')
|
||||
? (() => { stack.push(schema.$id); return true })()
|
||||
: false
|
||||
})
|
||||
const A = { [Kind]: 'Kind', $id: 'A' } as TSchema
|
||||
const B = { [Kind]: 'Kind', $id: 'B' } as TSchema
|
||||
const C = { [Kind]: 'Kind', $id: 'C' } as TSchema
|
||||
const D = { [Kind]: 'Kind', $id: 'D' } as TSchema
|
||||
const T1 = Type.Object({ a: A, b: B })
|
||||
const T2 = Type.Object({ a: C, b: D })
|
||||
// run T1 check
|
||||
const R2 = Value.Check(T1, { a: null, b: null })
|
||||
Assert.IsTrue(R2)
|
||||
Assert.IsEqual(stack.length, 2)
|
||||
Assert.IsEqual(stack[0], 'A')
|
||||
Assert.IsEqual(stack[1], 'B')
|
||||
stack = []
|
||||
// run T2 check
|
||||
const R3 = Value.Check(T2, { a: null, b: null })
|
||||
Assert.IsTrue(R3)
|
||||
Assert.IsEqual(stack.length, 2)
|
||||
Assert.IsEqual(stack[0], 'C')
|
||||
Assert.IsEqual(stack[1], 'D')
|
||||
stack = []
|
||||
// run T1 check
|
||||
const R4 = Value.Check(T1, { a: null, b: null })
|
||||
Assert.IsTrue(R4)
|
||||
Assert.IsEqual(stack.length, 2)
|
||||
Assert.IsEqual(stack[0], 'A')
|
||||
Assert.IsEqual(stack[1], 'B')
|
||||
stack = []
|
||||
TypeRegistry.Delete('Kind')
|
||||
})
|
||||
})
|
||||
27
test/runtime/value/check/literal.ts
Normal file
27
test/runtime/value/check/literal.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Literal', () => {
|
||||
const T = Type.Literal('hello')
|
||||
it('Should pass literal', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should fail literal', () => {
|
||||
const value = 1
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail literal with undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail literal with null', () => {
|
||||
const value = null
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
})
|
||||
146
test/runtime/value/check/module.ts
Normal file
146
test/runtime/value/check/module.ts
Normal file
@@ -0,0 +1,146 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert'
|
||||
|
||||
describe('value/check/Module', () => {
|
||||
it('Should validate string', () => {
|
||||
const Module = Type.Module({
|
||||
A: Type.String(),
|
||||
})
|
||||
const T = Module.Import('A')
|
||||
Assert.IsTrue(Value.Check(T, 'hello'))
|
||||
Assert.IsFalse(Value.Check(T, true))
|
||||
})
|
||||
it('Should validate referenced string', () => {
|
||||
const Module = Type.Module({
|
||||
A: Type.String(),
|
||||
B: Type.Ref('A'),
|
||||
})
|
||||
const T = Module.Import('B')
|
||||
Assert.IsTrue(Value.Check(T, 'hello'))
|
||||
Assert.IsFalse(Value.Check(T, true))
|
||||
})
|
||||
it('Should validate self referential', () => {
|
||||
const Module = Type.Module({
|
||||
A: Type.Object({
|
||||
nodes: Type.Array(Type.Ref('A')),
|
||||
}),
|
||||
})
|
||||
const T = Module.Import('A')
|
||||
Assert.IsTrue(Value.Check(T, { nodes: [{ nodes: [{ nodes: [] }, { nodes: [] }] }] }))
|
||||
Assert.IsFalse(Value.Check(T, { nodes: [{ nodes: [{ nodes: [] }, { nodes: false }] }] }))
|
||||
Assert.IsFalse(Value.Check(T, true))
|
||||
})
|
||||
it('Should validate mutual recursive', () => {
|
||||
const Module = Type.Module({
|
||||
A: Type.Object({
|
||||
b: Type.Ref('B'),
|
||||
}),
|
||||
B: Type.Object({
|
||||
a: Type.Union([Type.Ref('A'), Type.Null()]),
|
||||
}),
|
||||
})
|
||||
const T = Module.Import('A')
|
||||
Assert.IsTrue(Value.Check(T, { b: { a: null } }))
|
||||
Assert.IsTrue(Value.Check(T, { b: { a: { b: { a: null } } } }))
|
||||
|
||||
Assert.IsFalse(Value.Check(T, { b: { a: 1 } }))
|
||||
Assert.IsFalse(Value.Check(T, { b: { a: { b: { a: 1 } } } }))
|
||||
Assert.IsFalse(Value.Check(T, true))
|
||||
})
|
||||
it('Should validate mutual recursive (Array)', () => {
|
||||
const Module = Type.Module({
|
||||
A: Type.Object({
|
||||
b: Type.Ref('B'),
|
||||
}),
|
||||
B: Type.Object({
|
||||
a: Type.Array(Type.Ref('A')),
|
||||
}),
|
||||
})
|
||||
const T = Module.Import('A')
|
||||
Assert.IsTrue(Value.Check(T, { b: { a: [{ b: { a: [] } }] } }))
|
||||
Assert.IsFalse(Value.Check(T, { b: { a: [{ b: { a: [null] } }] } }))
|
||||
Assert.IsFalse(Value.Check(T, true))
|
||||
})
|
||||
it('Should validate deep referential', () => {
|
||||
const Module = Type.Module({
|
||||
A: Type.Ref('B'),
|
||||
B: Type.Ref('C'),
|
||||
C: Type.Ref('D'),
|
||||
D: Type.Ref('E'),
|
||||
E: Type.Ref('F'),
|
||||
F: Type.Ref('G'),
|
||||
G: Type.Ref('H'),
|
||||
H: Type.Literal('hello'),
|
||||
})
|
||||
const T = Module.Import('A')
|
||||
Assert.IsTrue(Value.Check(T, 'hello'))
|
||||
Assert.IsFalse(Value.Check(T, 'world'))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Modifiers
|
||||
// ----------------------------------------------------------------
|
||||
it('Should validate objects with property modifiers 1', () => {
|
||||
const Module = Type.Module({
|
||||
T: Type.Object({
|
||||
x: Type.ReadonlyOptional(Type.Null()),
|
||||
y: Type.Readonly(Type.Null()),
|
||||
z: Type.Optional(Type.Null()),
|
||||
w: Type.Null(),
|
||||
}),
|
||||
})
|
||||
const T = Module.Import('T')
|
||||
Assert.IsTrue(Value.Check(T, { x: null, y: null, w: null }))
|
||||
Assert.IsTrue(Value.Check(T, { y: null, w: null }))
|
||||
Assert.IsFalse(Value.Check(T, { x: 1, y: null, w: null }))
|
||||
})
|
||||
it('Should validate objects with property modifiers 2', () => {
|
||||
const Module = Type.Module({
|
||||
T: Type.Object({
|
||||
x: Type.ReadonlyOptional(Type.Array(Type.Null())),
|
||||
y: Type.Readonly(Type.Array(Type.Null())),
|
||||
z: Type.Optional(Type.Array(Type.Null())),
|
||||
w: Type.Array(Type.Null()),
|
||||
}),
|
||||
})
|
||||
const T = Module.Import('T')
|
||||
Assert.IsTrue(Value.Check(T, { x: [null], y: [null], w: [null] }))
|
||||
Assert.IsTrue(Value.Check(T, { y: [null], w: [null] }))
|
||||
Assert.IsFalse(Value.Check(T, { x: [1], y: [null], w: [null] }))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// https://github.com/sinclairzx81/typebox/issues/1109
|
||||
// ----------------------------------------------------------------
|
||||
it('Should validate deep referential 1', () => {
|
||||
const Module = Type.Module({
|
||||
A: Type.Union([Type.Literal('Foo'), Type.Literal('Bar')]),
|
||||
B: Type.Ref('A'),
|
||||
C: Type.Object({ ref: Type.Ref('B') }),
|
||||
D: Type.Union([Type.Ref('B'), Type.Ref('C')]),
|
||||
})
|
||||
Assert.IsTrue(Value.Check(Module.Import('A') as never, 'Foo'))
|
||||
Assert.IsTrue(Value.Check(Module.Import('A') as never, 'Bar'))
|
||||
Assert.IsTrue(Value.Check(Module.Import('B') as never, 'Foo'))
|
||||
Assert.IsTrue(Value.Check(Module.Import('B') as never, 'Bar'))
|
||||
Assert.IsTrue(Value.Check(Module.Import('C') as never, { ref: 'Foo' }))
|
||||
Assert.IsTrue(Value.Check(Module.Import('C') as never, { ref: 'Bar' }))
|
||||
Assert.IsTrue(Value.Check(Module.Import('D') as never, 'Foo'))
|
||||
Assert.IsTrue(Value.Check(Module.Import('D') as never, 'Bar'))
|
||||
Assert.IsTrue(Value.Check(Module.Import('D') as never, { ref: 'Foo' }))
|
||||
Assert.IsTrue(Value.Check(Module.Import('D') as never, { ref: 'Bar' }))
|
||||
})
|
||||
it('Should validate deep referential 2', () => {
|
||||
const Module = Type.Module({
|
||||
A: Type.Literal('Foo'),
|
||||
B: Type.Ref('A'),
|
||||
C: Type.Ref('B'),
|
||||
D: Type.Ref('C'),
|
||||
E: Type.Ref('D'),
|
||||
})
|
||||
Assert.IsTrue(Value.Check(Module.Import('A'), 'Foo'))
|
||||
Assert.IsTrue(Value.Check(Module.Import('B'), 'Foo'))
|
||||
Assert.IsTrue(Value.Check(Module.Import('C'), 'Foo'))
|
||||
Assert.IsTrue(Value.Check(Module.Import('D'), 'Foo'))
|
||||
Assert.IsTrue(Value.Check(Module.Import('E'), 'Foo'))
|
||||
})
|
||||
})
|
||||
42
test/runtime/value/check/never.ts
Normal file
42
test/runtime/value/check/never.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Never', () => {
|
||||
const T = Type.Never()
|
||||
it('Should fail string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail number', () => {
|
||||
const value = 1
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail null', () => {
|
||||
const value = null
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail object', () => {
|
||||
const value = { a: 1 }
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail array', () => {
|
||||
const value = [1, 2]
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
})
|
||||
30
test/runtime/value/check/not.ts
Normal file
30
test/runtime/value/check/not.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Not', () => {
|
||||
it('Should validate with not number', () => {
|
||||
const T = Type.Not(Type.Number())
|
||||
Assert.IsEqual(Value.Check(T, 1), false)
|
||||
Assert.IsEqual(Value.Check(T, 'A'), true)
|
||||
})
|
||||
it('Should validate with union left', () => {
|
||||
// prettier-ignore
|
||||
const T = Type.Not(Type.Union([
|
||||
Type.Literal('A'),
|
||||
Type.Literal('B'),
|
||||
Type.Literal('C')
|
||||
]))
|
||||
Assert.IsEqual(Value.Check(T, 'A'), false)
|
||||
Assert.IsEqual(Value.Check(T, 'B'), false)
|
||||
Assert.IsEqual(Value.Check(T, 'C'), false)
|
||||
Assert.IsEqual(Value.Check(T, 'D'), true)
|
||||
})
|
||||
it('Should validate with union right', () => {
|
||||
// prettier-ignore
|
||||
const T = Type.Not(Type.Number())
|
||||
Assert.IsEqual(Value.Check(T, 1), false)
|
||||
Assert.IsEqual(Value.Check(T, 'A'), true)
|
||||
Assert.IsEqual(Value.Check(T, true), true)
|
||||
})
|
||||
})
|
||||
47
test/runtime/value/check/null.ts
Normal file
47
test/runtime/value/check/null.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Null', () => {
|
||||
const T = Type.Null()
|
||||
it('Should fail string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail number', () => {
|
||||
const value = 1
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should pass null', () => {
|
||||
const value = null
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should fail undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail object', () => {
|
||||
const value = { a: 1 }
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail array', () => {
|
||||
const value = [1, 2]
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail Date', () => {
|
||||
const value = new Date()
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
})
|
||||
67
test/runtime/value/check/number.ts
Normal file
67
test/runtime/value/check/number.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Number', () => {
|
||||
const T = Type.Number()
|
||||
it('Should not validate NaN', () => {
|
||||
const T = Type.Number()
|
||||
const result = Value.Check(T, NaN)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should not validate +Infinity', () => {
|
||||
const T = Type.Number()
|
||||
const result = Value.Check(T, Infinity)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should not validate -Infinity', () => {
|
||||
const T = Type.Number()
|
||||
const result = Value.Check(T, -Infinity)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should pass number', () => {
|
||||
const value = 1
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should fail boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail null', () => {
|
||||
const value = null
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail object', () => {
|
||||
const value = { a: 1 }
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail array', () => {
|
||||
const value = [1, 2]
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail Date', () => {
|
||||
const value = new Date()
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
|
||||
it('Should fail NaN', () => {
|
||||
const result = Value.Check(Type.Number(), NaN)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
})
|
||||
212
test/runtime/value/check/object.ts
Normal file
212
test/runtime/value/check/object.ts
Normal file
@@ -0,0 +1,212 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Object', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
z: Type.Number(),
|
||||
a: Type.String(),
|
||||
b: Type.String(),
|
||||
c: Type.String(),
|
||||
})
|
||||
it('Should pass object', () => {
|
||||
const value = {
|
||||
x: 1,
|
||||
y: 1,
|
||||
z: 1,
|
||||
a: '1',
|
||||
b: '1',
|
||||
c: '1',
|
||||
}
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should fail object with additional properties', () => {
|
||||
const T = Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
z: Type.Number(),
|
||||
},
|
||||
{ additionalProperties: false },
|
||||
)
|
||||
const value = {
|
||||
x: 1,
|
||||
y: 1,
|
||||
z: 1,
|
||||
a: 1,
|
||||
}
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail object with invalid property', () => {
|
||||
const value = {
|
||||
x: true,
|
||||
y: 1,
|
||||
z: 1,
|
||||
a: '1',
|
||||
b: '1',
|
||||
c: '1',
|
||||
}
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail object with missing property', () => {
|
||||
const value = {
|
||||
y: 1,
|
||||
z: 1,
|
||||
a: '1',
|
||||
b: '1',
|
||||
c: '1',
|
||||
}
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should pass object with optional properties', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Optional(Type.Number()),
|
||||
y: Type.Optional(Type.Number()),
|
||||
z: Type.Optional(Type.Number()),
|
||||
a: Type.String(),
|
||||
b: Type.String(),
|
||||
c: Type.String(),
|
||||
})
|
||||
const value = {
|
||||
a: '1',
|
||||
b: '1',
|
||||
c: '1',
|
||||
}
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should fail object with null', () => {
|
||||
const value = null
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail object with undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should validate schema additional properties of string', () => {
|
||||
const T = Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
},
|
||||
{
|
||||
additionalProperties: Type.String(),
|
||||
},
|
||||
)
|
||||
Assert.IsEqual(
|
||||
Value.Check(T, {
|
||||
x: 1,
|
||||
y: 2,
|
||||
z: 'hello',
|
||||
}),
|
||||
true,
|
||||
)
|
||||
|
||||
Assert.IsEqual(
|
||||
Value.Check(T, {
|
||||
x: 1,
|
||||
y: 2,
|
||||
z: 3,
|
||||
}),
|
||||
false,
|
||||
)
|
||||
})
|
||||
it('Should validate schema additional properties of array', () => {
|
||||
const T = Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
},
|
||||
{
|
||||
additionalProperties: Type.Array(Type.Number()),
|
||||
},
|
||||
)
|
||||
Assert.IsEqual(
|
||||
Value.Check(T, {
|
||||
x: 1,
|
||||
y: 2,
|
||||
z: [0, 1, 2],
|
||||
}),
|
||||
true,
|
||||
)
|
||||
Assert.IsEqual(
|
||||
Value.Check(T, {
|
||||
x: 1,
|
||||
y: 2,
|
||||
z: 3,
|
||||
}),
|
||||
false,
|
||||
)
|
||||
})
|
||||
it('Should validate schema additional properties of object', () => {
|
||||
const T = Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
},
|
||||
{
|
||||
additionalProperties: Type.Object({
|
||||
z: Type.Number(),
|
||||
}),
|
||||
},
|
||||
)
|
||||
Assert.IsEqual(
|
||||
Value.Check(T, {
|
||||
x: 1,
|
||||
y: 2,
|
||||
z: { z: 1 },
|
||||
}),
|
||||
true,
|
||||
)
|
||||
Assert.IsEqual(
|
||||
Value.Check(T, {
|
||||
x: 1,
|
||||
y: 2,
|
||||
z: 3,
|
||||
}),
|
||||
false,
|
||||
)
|
||||
})
|
||||
it('Should check for property key if property type is undefined', () => {
|
||||
const T = Type.Object({ x: Type.Undefined() })
|
||||
Assert.IsEqual(Value.Check(T, { x: undefined }), true)
|
||||
Assert.IsEqual(Value.Check(T, {}), false)
|
||||
})
|
||||
it('Should check for property key if property type extends undefined', () => {
|
||||
const T = Type.Object({ x: Type.Union([Type.Number(), Type.Undefined()]) })
|
||||
Assert.IsEqual(Value.Check(T, { x: 1 }), true)
|
||||
Assert.IsEqual(Value.Check(T, { x: undefined }), true)
|
||||
Assert.IsEqual(Value.Check(T, {}), false)
|
||||
})
|
||||
it('Should not check for property key if property type is undefined and optional', () => {
|
||||
const T = Type.Object({ x: Type.Optional(Type.Undefined()) })
|
||||
Assert.IsEqual(Value.Check(T, { x: undefined }), true)
|
||||
Assert.IsEqual(Value.Check(T, {}), true)
|
||||
})
|
||||
it('Should not check for property key if property type extends undefined and optional', () => {
|
||||
const T = Type.Object({ x: Type.Optional(Type.Union([Type.Number(), Type.Undefined()])) })
|
||||
Assert.IsEqual(Value.Check(T, { x: 1 }), true)
|
||||
Assert.IsEqual(Value.Check(T, { x: undefined }), true)
|
||||
Assert.IsEqual(Value.Check(T, {}), true)
|
||||
})
|
||||
it('Should check undefined for optional property of number', () => {
|
||||
const T = Type.Object({ x: Type.Optional(Type.Number()) })
|
||||
Assert.IsEqual(Value.Check(T, { x: 1 }), true)
|
||||
Assert.IsEqual(Value.Check(T, { x: undefined }), true) // allowed by default
|
||||
Assert.IsEqual(Value.Check(T, {}), true)
|
||||
})
|
||||
it('Should check undefined for optional property of undefined', () => {
|
||||
const T = Type.Object({ x: Type.Optional(Type.Undefined()) })
|
||||
Assert.IsEqual(Value.Check(T, { x: 1 }), false)
|
||||
Assert.IsEqual(Value.Check(T, {}), true)
|
||||
Assert.IsEqual(Value.Check(T, { x: undefined }), true)
|
||||
})
|
||||
})
|
||||
297
test/runtime/value/check/record.ts
Normal file
297
test/runtime/value/check/record.ts
Normal file
@@ -0,0 +1,297 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Record', () => {
|
||||
it('Should pass record', () => {
|
||||
const T = Type.Record(
|
||||
Type.String(),
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
z: Type.Number(),
|
||||
}),
|
||||
)
|
||||
const value = {
|
||||
position: {
|
||||
x: 1,
|
||||
y: 2,
|
||||
z: 3,
|
||||
},
|
||||
}
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should fail when below minProperties', () => {
|
||||
const T = Type.Record(Type.String(), Type.Number(), { minProperties: 4 })
|
||||
Assert.IsEqual(Value.Check(T, { a: 1, b: 2, c: 3, d: 4 }), true)
|
||||
Assert.IsEqual(Value.Check(T, { a: 1, b: 2, c: 3 }), false)
|
||||
})
|
||||
it('Should fail when above maxProperties', () => {
|
||||
const T = Type.Record(Type.String(), Type.Number(), { maxProperties: 4 })
|
||||
Assert.IsEqual(Value.Check(T, { a: 1, b: 2, c: 3, d: 4 }), true)
|
||||
Assert.IsEqual(Value.Check(T, { a: 1, b: 2, c: 3, d: 4, e: 5 }), false)
|
||||
})
|
||||
it('Should fail with illogical minProperties | maxProperties', () => {
|
||||
const T = Type.Record(Type.String(), Type.Number(), { minProperties: 5, maxProperties: 4 })
|
||||
Assert.IsEqual(Value.Check(T, { a: 1, b: 2, c: 3 }), false)
|
||||
Assert.IsEqual(Value.Check(T, { a: 1, b: 2, c: 3, d: 4 }), false)
|
||||
Assert.IsEqual(Value.Check(T, { a: 1, b: 2, c: 3, d: 4, e: 5 }), false)
|
||||
})
|
||||
it('Should fail record with Date', () => {
|
||||
const T = Type.Record(Type.String(), Type.String())
|
||||
const result = Value.Check(T, new Date())
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail record with Uint8Array', () => {
|
||||
const T = Type.Record(Type.String(), Type.String())
|
||||
const result = Value.Check(T, new Uint8Array())
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail record with missing property', () => {
|
||||
const T = Type.Record(
|
||||
Type.String(),
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
z: Type.Number(),
|
||||
}),
|
||||
)
|
||||
const value = {
|
||||
position: {
|
||||
x: 1,
|
||||
y: 2,
|
||||
},
|
||||
}
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail record with invalid property', () => {
|
||||
const T = Type.Record(
|
||||
Type.String(),
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
z: Type.Number(),
|
||||
}),
|
||||
)
|
||||
const value = {
|
||||
position: {
|
||||
x: 1,
|
||||
y: 2,
|
||||
z: '3',
|
||||
},
|
||||
}
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should pass record with optional property', () => {
|
||||
const T = Type.Record(
|
||||
Type.String(),
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
z: Type.Optional(Type.Number()),
|
||||
}),
|
||||
)
|
||||
const value = {
|
||||
position: {
|
||||
x: 1,
|
||||
y: 2,
|
||||
},
|
||||
}
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass record with optional property', () => {
|
||||
const T = Type.Record(
|
||||
Type.String(),
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
z: Type.Optional(Type.Number()),
|
||||
}),
|
||||
)
|
||||
const value = {
|
||||
position: {
|
||||
x: 1,
|
||||
y: 2,
|
||||
},
|
||||
}
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should validate when specifying regular expressions', () => {
|
||||
const K = Type.RegExp(/^op_.*$/)
|
||||
const T = Type.Record(K, Type.Number())
|
||||
const R = Value.Check(T, {
|
||||
op_a: 1,
|
||||
op_b: 2,
|
||||
op_c: 3,
|
||||
})
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should not validate when specifying regular expressions and passing invalid property', () => {
|
||||
const K = Type.RegExp(/^op_.*$/)
|
||||
const T = Type.Record(K, Type.Number(), { additionalProperties: false })
|
||||
const R = Value.Check(T, {
|
||||
op_a: 1,
|
||||
op_b: 2,
|
||||
aop_c: 3,
|
||||
})
|
||||
Assert.IsFalse(R)
|
||||
})
|
||||
it('Should validate with quoted string pattern', () => {
|
||||
const K = Type.String({ pattern: "'(a|b|c)" })
|
||||
const T = Type.Record(K, Type.Number())
|
||||
const R = Value.Check(T, {
|
||||
"'a": 1,
|
||||
"'b": 2,
|
||||
"'c": 3,
|
||||
})
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
it('Should validate with forward-slash pattern', () => {
|
||||
const K = Type.String({ pattern: '/(a|b|c)' })
|
||||
const T = Type.Record(K, Type.Number())
|
||||
const R = Value.Check(T, {
|
||||
'/a': 1,
|
||||
'/b': 2,
|
||||
'/c': 3,
|
||||
})
|
||||
Assert.IsTrue(R)
|
||||
})
|
||||
// -------------------------------------------------
|
||||
// Number Key
|
||||
// -------------------------------------------------
|
||||
it('Should pass record with number key', () => {
|
||||
const T = Type.Record(Type.Number(), Type.String())
|
||||
const value = {
|
||||
0: 'a',
|
||||
1: 'a',
|
||||
2: 'a',
|
||||
}
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
|
||||
it('Should not pass record with invalid number key', () => {
|
||||
const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: false })
|
||||
const value = {
|
||||
a: 'a',
|
||||
1: 'a',
|
||||
2: 'a',
|
||||
}
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
// -------------------------------------------------
|
||||
// Integer Key
|
||||
// -------------------------------------------------
|
||||
it('Should pass record with integer key', () => {
|
||||
const T = Type.Record(Type.Integer(), Type.String())
|
||||
const value = {
|
||||
0: 'a',
|
||||
1: 'a',
|
||||
2: 'a',
|
||||
}
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should not pass record with invalid integer key', () => {
|
||||
const T = Type.Record(Type.Integer(), Type.String(), { additionalProperties: false })
|
||||
const value = {
|
||||
a: 'a',
|
||||
1: 'a',
|
||||
2: 'a',
|
||||
}
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
// ------------------------------------------------------------
|
||||
// AdditionalProperties
|
||||
// ------------------------------------------------------------
|
||||
it('AdditionalProperties 1', () => {
|
||||
const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: true })
|
||||
const R = Value.Check(T, { 1: '', 2: '', x: 1, y: 2, z: 3 })
|
||||
Assert.IsEqual(R, true)
|
||||
})
|
||||
it('AdditionalProperties 2', () => {
|
||||
const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: false })
|
||||
const R = Value.Check(T, { 1: '', 2: '', 3: '' })
|
||||
Assert.IsEqual(R, true)
|
||||
})
|
||||
it('AdditionalProperties 3', () => {
|
||||
const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: false })
|
||||
const R = Value.Check(T, { 1: '', 2: '', x: '' })
|
||||
Assert.IsEqual(R, false)
|
||||
})
|
||||
it('AdditionalProperties 4', () => {
|
||||
const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: Type.Boolean() })
|
||||
const R = Value.Check(T, { 1: '', 2: '', x: '' })
|
||||
Assert.IsEqual(R, false)
|
||||
})
|
||||
it('AdditionalProperties 5', () => {
|
||||
const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: Type.Boolean() })
|
||||
const R = Value.Check(T, { 1: '', 2: '', x: true })
|
||||
Assert.IsEqual(R, true)
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// https://github.com/sinclairzx81/typebox/issues/916
|
||||
// ----------------------------------------------------------------
|
||||
it('Should validate for string keys', () => {
|
||||
const T = Type.Record(Type.String(), Type.Null(), {
|
||||
additionalProperties: false,
|
||||
})
|
||||
const R = Value.Check(T, {
|
||||
a: null,
|
||||
b: null,
|
||||
0: null,
|
||||
1: null,
|
||||
})
|
||||
Assert.IsEqual(R, true)
|
||||
})
|
||||
it('Should validate for number keys', () => {
|
||||
const T = Type.Record(Type.Number(), Type.Null(), {
|
||||
additionalProperties: false,
|
||||
})
|
||||
const R1 = Value.Check(T, {
|
||||
a: null,
|
||||
b: null,
|
||||
0: null,
|
||||
1: null,
|
||||
})
|
||||
const R2 = Value.Check(T, {
|
||||
0: null,
|
||||
1: null,
|
||||
})
|
||||
Assert.IsEqual(R1, false)
|
||||
Assert.IsEqual(R2, true)
|
||||
})
|
||||
it('Should validate for any keys', () => {
|
||||
const T = Type.Record(Type.Any(), Type.Null(), {
|
||||
additionalProperties: false,
|
||||
})
|
||||
const R = Value.Check(T, {
|
||||
a: null,
|
||||
b: null,
|
||||
0: null,
|
||||
1: null,
|
||||
})
|
||||
Assert.IsEqual(R, true)
|
||||
})
|
||||
it('Should validate for never keys', () => {
|
||||
const T = Type.Record(Type.Never(), Type.Null(), {
|
||||
additionalProperties: false,
|
||||
})
|
||||
const R1 = Value.Check(T, {})
|
||||
const R2 = Value.Check(T, {
|
||||
a: null,
|
||||
b: null,
|
||||
0: null,
|
||||
1: null,
|
||||
})
|
||||
Assert.IsEqual(R1, true)
|
||||
Assert.IsEqual(R2, false)
|
||||
})
|
||||
})
|
||||
69
test/runtime/value/check/recursive.ts
Normal file
69
test/runtime/value/check/recursive.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Recursive', () => {
|
||||
const T = Type.Recursive((This) =>
|
||||
Type.Object({
|
||||
id: Type.String(),
|
||||
nodes: Type.Array(This),
|
||||
}),
|
||||
)
|
||||
|
||||
it('Should pass recursive', () => {
|
||||
const value = {
|
||||
id: 'A',
|
||||
nodes: [
|
||||
{ id: 'B', nodes: [] },
|
||||
{ id: 'C', nodes: [] },
|
||||
{ id: 'D', nodes: [] },
|
||||
],
|
||||
}
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
|
||||
it('Should fail recursive with invalid id', () => {
|
||||
const value = {
|
||||
id: 'A',
|
||||
nodes: [
|
||||
{ id: 1, nodes: [] },
|
||||
{ id: 'C', nodes: [] },
|
||||
{ id: 'D', nodes: [] },
|
||||
],
|
||||
}
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
|
||||
it('Should fail rec with invalid nodes', () => {
|
||||
const value = {
|
||||
id: 'A',
|
||||
nodes: [
|
||||
{ id: 'B', nodes: 1 },
|
||||
{ id: 'C', nodes: [] },
|
||||
{ id: 'D', nodes: [] },
|
||||
],
|
||||
}
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
|
||||
it('Should fail recursive with missing id', () => {
|
||||
const value = {
|
||||
id: 'A',
|
||||
nodes: [{ nodes: [] }, { id: 'C', nodes: [] }, { id: 'D', nodes: [] }],
|
||||
}
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
|
||||
it('Should fail rec with missing nodes', () => {
|
||||
const value = {
|
||||
id: 'A',
|
||||
nodes: [{ id: 'B' }, { id: 'C', nodes: [] }, { id: 'D', nodes: [] }],
|
||||
}
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
})
|
||||
95
test/runtime/value/check/ref.ts
Normal file
95
test/runtime/value/check/ref.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Ref', () => {
|
||||
// ----------------------------------------------------------------
|
||||
// Deprecated
|
||||
// ----------------------------------------------------------------
|
||||
it('Should validate for Ref(Schema)', () => {
|
||||
const T = Type.Number({ $id: 'T' })
|
||||
const R = Type.Ref(T)
|
||||
Assert.IsTrue(Value.Check(T, [T], 1234))
|
||||
Assert.IsFalse(Value.Check(T, [T], 'hello'))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Standard
|
||||
// ----------------------------------------------------------------
|
||||
it('Should should validate when referencing a type', () => {
|
||||
const T = Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
z: Type.Number(),
|
||||
},
|
||||
{ $id: Assert.NextId() },
|
||||
)
|
||||
const R = Type.Ref(T.$id!)
|
||||
Assert.IsEqual(
|
||||
Value.Check(R, [T], {
|
||||
x: 1,
|
||||
y: 2,
|
||||
z: 3,
|
||||
}),
|
||||
true,
|
||||
)
|
||||
})
|
||||
|
||||
it('Should not validate when passing invalid data', () => {
|
||||
const T = Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
z: Type.Number(),
|
||||
},
|
||||
{ $id: Assert.NextId() },
|
||||
)
|
||||
const R = Type.Ref(T.$id!)
|
||||
Assert.IsEqual(
|
||||
Value.Check(R, [T], {
|
||||
x: 1,
|
||||
y: 2,
|
||||
}),
|
||||
false,
|
||||
)
|
||||
})
|
||||
|
||||
it('Should de-reference object property schema', () => {
|
||||
const T = Type.Object(
|
||||
{
|
||||
name: Type.String(),
|
||||
},
|
||||
{ $id: 'R' },
|
||||
)
|
||||
|
||||
const R = Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
z: Type.Number(),
|
||||
r: Type.Optional(Type.Ref(T.$id!)),
|
||||
},
|
||||
{ $id: 'T' },
|
||||
)
|
||||
Assert.IsEqual(Value.Check(R, [T], { x: 1, y: 2, z: 3 }), true)
|
||||
Assert.IsEqual(Value.Check(R, [T], { x: 1, y: 2, z: 3, r: { name: 'hello' } }), true)
|
||||
Assert.IsEqual(Value.Check(R, [T], { x: 1, y: 2, z: 3, r: { name: 1 } }), false)
|
||||
Assert.IsEqual(Value.Check(R, [T], { x: 1, y: 2, z: 3, r: {} }), false)
|
||||
// Ok(R, { x: 1, y: 2, z: 3 }, [T])
|
||||
// Ok(R, , [T])
|
||||
// Fail(R, , [T])
|
||||
// Fail(R, , [T])
|
||||
})
|
||||
|
||||
it('Should reference recursive schema', () => {
|
||||
const T = Type.Recursive((Node) =>
|
||||
Type.Object({
|
||||
id: Type.String(),
|
||||
nodes: Type.Array(Node),
|
||||
}),
|
||||
)
|
||||
const R = Type.Ref(T.$id!)
|
||||
Assert.IsEqual(Value.Check(R, [T], { id: '', nodes: [{ id: '', nodes: [] }] }), true)
|
||||
Assert.IsEqual(Value.Check(R, [T], { id: '', nodes: [{ id: 1, nodes: [] }] }), false)
|
||||
})
|
||||
})
|
||||
50
test/runtime/value/check/regexp.ts
Normal file
50
test/runtime/value/check/regexp.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/RegExp', () => {
|
||||
// -------------------------------------------------
|
||||
// Regular Expression
|
||||
// -------------------------------------------------
|
||||
it('Should pass regular expression 1', () => {
|
||||
const T = Type.RegExp(/foo/)
|
||||
const value = 'foo'
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass regular expression 2', () => {
|
||||
const T = Type.RegExp(/foo/)
|
||||
const value = 'bar'
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
// -------------------------------------------------
|
||||
// Pattern
|
||||
// -------------------------------------------------
|
||||
it('Should pass pattern 1', () => {
|
||||
const T = Type.RegExp('foo')
|
||||
const value = 'foo'
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass pattern 2', () => {
|
||||
const T = Type.RegExp('foo')
|
||||
const value = 'bar'
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should validate with minLength constraint', () => {
|
||||
const T = Type.RegExp(/(.*)/, {
|
||||
minLength: 3,
|
||||
})
|
||||
Assert.IsTrue(Value.Check(T, 'xxx'))
|
||||
Assert.IsFalse(Value.Check(T, 'xx'))
|
||||
})
|
||||
it('Should validate with maxLength constraint', () => {
|
||||
const T = Type.RegExp(/(.*)/, {
|
||||
maxLength: 3,
|
||||
})
|
||||
Assert.IsTrue(Value.Check(T, 'xxx'))
|
||||
Assert.IsFalse(Value.Check(T, 'xxxx'))
|
||||
})
|
||||
})
|
||||
47
test/runtime/value/check/string.ts
Normal file
47
test/runtime/value/check/string.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/String', () => {
|
||||
const T = Type.String()
|
||||
it('Should pass string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should fail number', () => {
|
||||
const value = 1
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail null', () => {
|
||||
const value = null
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail object', () => {
|
||||
const value = { a: 1 }
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail array', () => {
|
||||
const value = [1, 2]
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail Date', () => {
|
||||
const value = new Date()
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
})
|
||||
52
test/runtime/value/check/symbol.ts
Normal file
52
test/runtime/value/check/symbol.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Symbol', () => {
|
||||
const T = Type.Symbol()
|
||||
it('Should fail string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail number', () => {
|
||||
const value = 1
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail null', () => {
|
||||
const value = null
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail object', () => {
|
||||
const value = { a: 1 }
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail array', () => {
|
||||
const value = [1, 2]
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail Date', () => {
|
||||
const value = new Date()
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should pass symbol', () => {
|
||||
const value = Symbol(1)
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
})
|
||||
187
test/runtime/value/check/template-literal.ts
Normal file
187
test/runtime/value/check/template-literal.ts
Normal file
@@ -0,0 +1,187 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/TemplateLiteral', () => {
|
||||
// --------------------------------------------------------
|
||||
// Finite
|
||||
// --------------------------------------------------------
|
||||
it('Should validate finite pattern 1', () => {
|
||||
// prettier-ignore
|
||||
const T = Type.TemplateLiteral([])
|
||||
Assert.IsEqual(Value.Check(T, ''), true)
|
||||
Assert.IsEqual(Value.Check(T, 'X'), false)
|
||||
})
|
||||
it('Should validate finite pattern 1', () => {
|
||||
// prettier-ignore
|
||||
const T = Type.TemplateLiteral([Type.Boolean()])
|
||||
Assert.IsEqual(Value.Check(T, 'true'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'false'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'X'), false)
|
||||
})
|
||||
it('Should validate finite pattern 2', () => {
|
||||
// prettier-ignore
|
||||
const T = Type.TemplateLiteral([
|
||||
Type.Literal('A')
|
||||
])
|
||||
Assert.IsEqual(Value.Check(T, 'A'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'X'), false)
|
||||
})
|
||||
it('Should validate finite pattern 3', () => {
|
||||
// prettier-ignore
|
||||
const T = Type.TemplateLiteral([
|
||||
Type.Literal('A'),
|
||||
Type.Literal('B')
|
||||
])
|
||||
Assert.IsEqual(Value.Check(T, 'AB'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'X'), false)
|
||||
})
|
||||
it('Should validate finite pattern 4', () => {
|
||||
// prettier-ignore
|
||||
const T = Type.TemplateLiteral([
|
||||
Type.Literal('A'),
|
||||
Type.Union([
|
||||
Type.Literal('B'),
|
||||
Type.Literal('C')
|
||||
]),
|
||||
])
|
||||
Assert.IsEqual(Value.Check(T, 'AB'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'AC'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'X'), false)
|
||||
})
|
||||
it('Should validate finite pattern 5', () => {
|
||||
// prettier-ignore
|
||||
const T = Type.TemplateLiteral([
|
||||
Type.Literal('A'),
|
||||
Type.Union([
|
||||
Type.Literal('B'),
|
||||
Type.Literal('C')
|
||||
]),
|
||||
Type.Literal('D'),
|
||||
])
|
||||
Assert.IsEqual(Value.Check(T, 'ABD'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'ACD'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'X'), false)
|
||||
})
|
||||
it('Should validate finite pattern 6', () => {
|
||||
// prettier-ignore
|
||||
const T = Type.TemplateLiteral([
|
||||
Type.Union([
|
||||
Type.Literal('0'),
|
||||
Type.Literal('1')
|
||||
]),
|
||||
Type.Union([
|
||||
Type.Literal('0'),
|
||||
Type.Literal('1')
|
||||
]),
|
||||
])
|
||||
Assert.IsEqual(Value.Check(T, '00'), true)
|
||||
Assert.IsEqual(Value.Check(T, '01'), true)
|
||||
Assert.IsEqual(Value.Check(T, '10'), true)
|
||||
Assert.IsEqual(Value.Check(T, '11'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'X'), false)
|
||||
})
|
||||
// --------------------------------------------------------
|
||||
// Infinite
|
||||
// --------------------------------------------------------
|
||||
it('Should validate infinite pattern 1', () => {
|
||||
// prettier-ignore
|
||||
const T = Type.TemplateLiteral([
|
||||
Type.Number()
|
||||
])
|
||||
Assert.IsEqual(Value.Check(T, '1'), true)
|
||||
Assert.IsEqual(Value.Check(T, '22'), true)
|
||||
Assert.IsEqual(Value.Check(T, '333'), true)
|
||||
Assert.IsEqual(Value.Check(T, '4444'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'X'), false)
|
||||
})
|
||||
it('Should validate infinite pattern 2', () => {
|
||||
// prettier-ignore
|
||||
const T = Type.TemplateLiteral([
|
||||
Type.Integer()
|
||||
])
|
||||
Assert.IsEqual(Value.Check(T, '1'), true)
|
||||
Assert.IsEqual(Value.Check(T, '22'), true)
|
||||
Assert.IsEqual(Value.Check(T, '333'), true)
|
||||
Assert.IsEqual(Value.Check(T, '4444'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'X'), false)
|
||||
})
|
||||
it('Should validate infinite pattern 3', () => {
|
||||
// prettier-ignore
|
||||
const T = Type.TemplateLiteral([
|
||||
Type.BigInt()
|
||||
])
|
||||
Assert.IsEqual(Value.Check(T, '1'), true)
|
||||
Assert.IsEqual(Value.Check(T, '22'), true)
|
||||
Assert.IsEqual(Value.Check(T, '333'), true)
|
||||
Assert.IsEqual(Value.Check(T, '4444'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'X'), false)
|
||||
})
|
||||
it('Should validate infinite pattern 4', () => {
|
||||
// prettier-ignore
|
||||
const T = Type.TemplateLiteral([
|
||||
Type.String()
|
||||
])
|
||||
Assert.IsEqual(Value.Check(T, '1'), true)
|
||||
Assert.IsEqual(Value.Check(T, '22'), true)
|
||||
Assert.IsEqual(Value.Check(T, '333'), true)
|
||||
Assert.IsEqual(Value.Check(T, '4444'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'a'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'bb'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'ccc'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'dddd'), true)
|
||||
})
|
||||
|
||||
it('Should validate infinite pattern 5', () => {
|
||||
// prettier-ignore
|
||||
const T = Type.TemplateLiteral([
|
||||
Type.Literal('A'),
|
||||
Type.Number()
|
||||
])
|
||||
Assert.IsEqual(Value.Check(T, 'A1'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'A22'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'A333'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'A4444'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'X'), false)
|
||||
})
|
||||
it('Should validate infinite pattern 6', () => {
|
||||
// prettier-ignore
|
||||
const T = Type.TemplateLiteral([
|
||||
Type.Literal('A'),
|
||||
Type.Integer()
|
||||
])
|
||||
Assert.IsEqual(Value.Check(T, 'A1'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'A22'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'A333'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'A4444'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'X'), false)
|
||||
})
|
||||
it('Should validate infinite pattern 7', () => {
|
||||
// prettier-ignore
|
||||
const T = Type.TemplateLiteral([
|
||||
Type.Literal('A'),
|
||||
Type.BigInt()
|
||||
])
|
||||
Assert.IsEqual(Value.Check(T, 'A1'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'A22'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'A333'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'A4444'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'X'), false)
|
||||
})
|
||||
it('Should validate infinite pattern 8', () => {
|
||||
// prettier-ignore
|
||||
const T = Type.TemplateLiteral([
|
||||
Type.Literal('A'),
|
||||
Type.String()
|
||||
])
|
||||
Assert.IsEqual(Value.Check(T, 'A1'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'A22'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'A333'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'A4444'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'Aa'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'Abb'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'Accc'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'Adddd'), true)
|
||||
Assert.IsEqual(Value.Check(T, 'X'), false)
|
||||
})
|
||||
})
|
||||
40
test/runtime/value/check/tuple.ts
Normal file
40
test/runtime/value/check/tuple.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Tuple', () => {
|
||||
it('Should pass tuple', () => {
|
||||
const T = Type.Tuple([Type.Number(), Type.Number()])
|
||||
const value = [1, 2]
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
|
||||
it('Should fail when tuple is less than length', () => {
|
||||
const T = Type.Tuple([Type.Number(), Type.Number()])
|
||||
const value = [1]
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
|
||||
it('Should fail when tuple is greater than length', () => {
|
||||
const T = Type.Tuple([Type.Number(), Type.Number()])
|
||||
const value = [1, 1, 2]
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
|
||||
it('Should pass empty tuple', () => {
|
||||
const T = Type.Tuple([])
|
||||
const value = [] as any[]
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
|
||||
it('Should fail empty tuple', () => {
|
||||
const T = Type.Tuple([])
|
||||
const value = [1]
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
})
|
||||
33
test/runtime/value/check/uint8array.ts
Normal file
33
test/runtime/value/check/uint8array.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Uint8Array', () => {
|
||||
it('Should pass Uint8Array', () => {
|
||||
const T = Type.Uint8Array()
|
||||
const value = new Uint8Array(4)
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
|
||||
it('Should fail Uint8Array', () => {
|
||||
const T = Type.Uint8Array()
|
||||
const value = [0, 1, 2, 3]
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
|
||||
it('Should fail Uint8Array with undefined', () => {
|
||||
const T = Type.Uint8Array()
|
||||
const value = undefined
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
|
||||
it('Should fail Uint8Array with null', () => {
|
||||
const T = Type.Uint8Array()
|
||||
const value = null
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
})
|
||||
47
test/runtime/value/check/undefined.ts
Normal file
47
test/runtime/value/check/undefined.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Undefined', () => {
|
||||
const T = Type.Undefined()
|
||||
it('Should fail string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail number', () => {
|
||||
const value = 1
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail null', () => {
|
||||
const value = null
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should pass undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should fail object', () => {
|
||||
const value = { a: 1 }
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail array', () => {
|
||||
const value = [1, 2]
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail Date', () => {
|
||||
const value = new Date()
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
})
|
||||
77
test/runtime/value/check/union.ts
Normal file
77
test/runtime/value/check/union.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Union', () => {
|
||||
const A = Type.Object({
|
||||
type: Type.Literal('A'),
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
})
|
||||
|
||||
const B = Type.Object({
|
||||
type: Type.Literal('B'),
|
||||
x: Type.Boolean(),
|
||||
y: Type.Boolean(),
|
||||
})
|
||||
|
||||
const T = Type.Union([A, B])
|
||||
|
||||
it('Should pass union A', () => {
|
||||
const value = { type: 'A', x: 1, y: 1 }
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
|
||||
it('Should pass union B', () => {
|
||||
const value = { type: 'B', x: true, y: false }
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
|
||||
it('Should fail union A', () => {
|
||||
const value = { type: 'A', x: true, y: false }
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
|
||||
it('Should fail union B', () => {
|
||||
const value = { type: 'B', x: 1, y: 1 }
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
|
||||
it('Should pass union A with optional properties', () => {
|
||||
const A = Type.Object({
|
||||
type: Type.Literal('A'),
|
||||
x: Type.Optional(Type.Number()),
|
||||
y: Type.Optional(Type.Number()),
|
||||
})
|
||||
const B = Type.Object({
|
||||
type: Type.Literal('B'),
|
||||
x: Type.Boolean(),
|
||||
y: Type.Boolean(),
|
||||
})
|
||||
const T = Type.Union([A, B])
|
||||
const value = { type: 'A' }
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
|
||||
it('Should fail union A with invalid optional properties', () => {
|
||||
const A = Type.Object({
|
||||
type: Type.Literal('A'),
|
||||
x: Type.Optional(Type.Number()),
|
||||
y: Type.Optional(Type.Number()),
|
||||
})
|
||||
const B = Type.Object({
|
||||
type: Type.Literal('B'),
|
||||
x: Type.Boolean(),
|
||||
y: Type.Boolean(),
|
||||
})
|
||||
const T = Type.Union([A, B])
|
||||
const value = { type: 'A', x: true, y: false }
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
})
|
||||
47
test/runtime/value/check/unknown.ts
Normal file
47
test/runtime/value/check/unknown.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Unknown', () => {
|
||||
const T = Type.Any()
|
||||
it('Should pass string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass number', () => {
|
||||
const value = 1
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass null', () => {
|
||||
const value = null
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass object', () => {
|
||||
const value = { a: 1 }
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass array', () => {
|
||||
const value = [1, 2]
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should pass Date', () => {
|
||||
const value = new Date()
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
})
|
||||
47
test/runtime/value/check/void.ts
Normal file
47
test/runtime/value/check/void.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/check/Void', () => {
|
||||
const T = Type.Void()
|
||||
it('Should fail string', () => {
|
||||
const value = 'hello'
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail number', () => {
|
||||
const value = 1
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail boolean', () => {
|
||||
const value = true
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should pass null', () => {
|
||||
const value = null
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should pass undefined', () => {
|
||||
const value = undefined
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, true)
|
||||
})
|
||||
it('Should fail object', () => {
|
||||
const value = { a: 1 }
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail array', () => {
|
||||
const value = [1, 2]
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
it('Should fail Date', () => {
|
||||
const value = new Date()
|
||||
const result = Value.Check(T, value)
|
||||
Assert.IsEqual(result, false)
|
||||
})
|
||||
})
|
||||
11
test/runtime/value/clean/any.ts
Normal file
11
test/runtime/value/clean/any.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/clean/Any', () => {
|
||||
it('Should clean 1', () => {
|
||||
const T = Type.Any()
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
})
|
||||
21
test/runtime/value/clean/array.ts
Normal file
21
test/runtime/value/clean/array.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/clean/Array', () => {
|
||||
it('Should clean 1', () => {
|
||||
const T = Type.Any()
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
it('Should clean 2', () => {
|
||||
const T = Type.Array(
|
||||
Type.Object({
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
}),
|
||||
)
|
||||
const R = Value.Clean(T, [undefined, null, { x: 1 }, { x: 1, y: 2 }, { x: 1, y: 2, z: 3 }])
|
||||
Assert.IsEqual(R, [undefined, null, { x: 1 }, { x: 1, y: 2 }, { x: 1, y: 2 }])
|
||||
})
|
||||
})
|
||||
11
test/runtime/value/clean/async-iterator.ts
Normal file
11
test/runtime/value/clean/async-iterator.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/clean/AsyncIterator', () => {
|
||||
it('Should clean 1', () => {
|
||||
const T = Type.AsyncIterator(Type.Number())
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
})
|
||||
11
test/runtime/value/clean/bigint.ts
Normal file
11
test/runtime/value/clean/bigint.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/clean/BigInt', () => {
|
||||
it('Should clean 1', () => {
|
||||
const T = Type.BigInt()
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
})
|
||||
11
test/runtime/value/clean/boolean.ts
Normal file
11
test/runtime/value/clean/boolean.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/clean/Boolean', () => {
|
||||
it('Should clean 1', () => {
|
||||
const T = Type.Boolean()
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
})
|
||||
11
test/runtime/value/clean/composite.ts
Normal file
11
test/runtime/value/clean/composite.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/clean/Composite', () => {
|
||||
it('Should clean 1', () => {
|
||||
const T = Type.Composite([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })])
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
})
|
||||
11
test/runtime/value/clean/constructor.ts
Normal file
11
test/runtime/value/clean/constructor.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/clean/Constructor', () => {
|
||||
it('Should clean 1', () => {
|
||||
const T = Type.Constructor([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })], Type.Object({ z: Type.Number() }))
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
})
|
||||
11
test/runtime/value/clean/date.ts
Normal file
11
test/runtime/value/clean/date.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/clean/Date', () => {
|
||||
it('Should clean 1', () => {
|
||||
const T = Type.Date()
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
})
|
||||
11
test/runtime/value/clean/enum.ts
Normal file
11
test/runtime/value/clean/enum.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/clean/Enum', () => {
|
||||
it('Should clean 1', () => {
|
||||
const T = Type.Enum({ x: 1, y: 2 })
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
})
|
||||
11
test/runtime/value/clean/function.ts
Normal file
11
test/runtime/value/clean/function.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/clean/Function', () => {
|
||||
it('Should clean 1', () => {
|
||||
const T = Type.Function([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })], Type.Object({ z: Type.Number() }))
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
})
|
||||
203
test/runtime/value/clean/import.ts
Normal file
203
test/runtime/value/clean/import.ts
Normal file
@@ -0,0 +1,203 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/clean/Import', () => {
|
||||
// ----------------------------------------------------------------
|
||||
// Clean
|
||||
// ----------------------------------------------------------------
|
||||
it('Should clean 1', () => {
|
||||
const T = Type.Module({ A: Type.Object({ x: Type.Number() }) }).Import('A')
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
it('Should clean 2', () => {
|
||||
const T = Type.Module({ A: Type.Object({ x: Type.Number() }) }).Import('A')
|
||||
const R = Value.Clean(T, {})
|
||||
Assert.IsEqual(R, {})
|
||||
})
|
||||
it('Should clean 3', () => {
|
||||
const T = Type.Module({ A: Type.Object({ x: Type.Number() }) }).Import('A')
|
||||
const R = Value.Clean(T, { x: 1 })
|
||||
Assert.IsEqual(R, { x: 1 })
|
||||
})
|
||||
it('Should clean 4', () => {
|
||||
const T = Type.Module({ A: Type.Object({ x: Type.Number() }) }).Import('A')
|
||||
const R = Value.Clean(T, { x: null })
|
||||
Assert.IsEqual(R, { x: null })
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Nested
|
||||
// ----------------------------------------------------------------
|
||||
it('Should clean nested 1', () => {
|
||||
const T = Type.Module({
|
||||
A: Type.Object({
|
||||
x: Type.Object({
|
||||
y: Type.Number(),
|
||||
}),
|
||||
}),
|
||||
}).Import('A')
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
it('Should clean nested 2', () => {
|
||||
const T = Type.Module({
|
||||
A: Type.Object({
|
||||
x: Type.Object({
|
||||
y: Type.Number(),
|
||||
}),
|
||||
}),
|
||||
}).Import('A')
|
||||
const R = Value.Clean(T, {})
|
||||
Assert.IsEqual(R, {})
|
||||
})
|
||||
it('Should clean nested 3', () => {
|
||||
const T = Type.Module({
|
||||
A: Type.Object({
|
||||
x: Type.Object({
|
||||
y: Type.Number(),
|
||||
}),
|
||||
}),
|
||||
}).Import('A')
|
||||
|
||||
const R = Value.Clean(T, { x: null })
|
||||
Assert.IsEqual(R, { x: null })
|
||||
})
|
||||
it('Should clean nested 4', () => {
|
||||
const T = Type.Module({
|
||||
A: Type.Object({
|
||||
x: Type.Object({
|
||||
y: Type.Number(),
|
||||
}),
|
||||
}),
|
||||
}).Import('A')
|
||||
const R = Value.Clean(T, { x: { y: null } })
|
||||
Assert.IsEqual(R, { x: { y: null } })
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Additional Properties
|
||||
// ----------------------------------------------------------------
|
||||
it('Should clean additional properties 1', () => {
|
||||
const T = Type.Module({
|
||||
A: Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
},
|
||||
{
|
||||
additionalProperties: Type.String(),
|
||||
},
|
||||
),
|
||||
}).Import('A')
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
it('Should clean additional properties 2', () => {
|
||||
const T = Type.Module({
|
||||
A: Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
},
|
||||
{
|
||||
additionalProperties: Type.String(),
|
||||
},
|
||||
),
|
||||
}).Import('A')
|
||||
const R = Value.Clean(T, {})
|
||||
Assert.IsEqual(R, {})
|
||||
})
|
||||
it('Should clean additional properties 3', () => {
|
||||
const T = Type.Module({
|
||||
A: Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
},
|
||||
{
|
||||
additionalProperties: Type.String(),
|
||||
},
|
||||
),
|
||||
}).Import('A')
|
||||
const R = Value.Clean(T, { x: 1 })
|
||||
Assert.IsEqual(R, { x: 1 })
|
||||
})
|
||||
it('Should clean additional properties 4', () => {
|
||||
const T = Type.Module({
|
||||
A: Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
},
|
||||
{
|
||||
additionalProperties: Type.String(),
|
||||
},
|
||||
),
|
||||
}).Import('A')
|
||||
const R = Value.Clean(T, { x: 1, y: 2 })
|
||||
Assert.IsEqual(R, { x: 1, y: 2 })
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Additional Properties Discard
|
||||
// ----------------------------------------------------------------
|
||||
it('Should clean additional properties discard 1', () => {
|
||||
const T = Type.Module({
|
||||
A: Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
},
|
||||
{
|
||||
additionalProperties: Type.String(),
|
||||
},
|
||||
),
|
||||
}).Import('A')
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
it('Should clean additional properties discard 2', () => {
|
||||
const T = Type.Module({
|
||||
A: Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
},
|
||||
{
|
||||
additionalProperties: Type.String(),
|
||||
},
|
||||
),
|
||||
}).Import('A')
|
||||
const R = Value.Clean(T, { k: '', d: null })
|
||||
Assert.IsEqual(R, { k: '' })
|
||||
})
|
||||
it('Should clean additional properties discard 3', () => {
|
||||
const T = Type.Module({
|
||||
A: Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
},
|
||||
{
|
||||
additionalProperties: Type.String(),
|
||||
},
|
||||
),
|
||||
}).Import('A')
|
||||
const R = Value.Clean(T, { k: '', d: null, x: 1 })
|
||||
Assert.IsEqual(R, { k: '', x: 1 })
|
||||
})
|
||||
it('Should clean additional properties discard 4', () => {
|
||||
const T = Type.Module({
|
||||
A: Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
},
|
||||
{
|
||||
additionalProperties: Type.String(),
|
||||
},
|
||||
),
|
||||
}).Import('A')
|
||||
const R = Value.Clean(T, { k: '', d: null, x: 1, y: 2 })
|
||||
Assert.IsEqual(R, { k: '', x: 1, y: 2 })
|
||||
})
|
||||
})
|
||||
35
test/runtime/value/clean/index.ts
Normal file
35
test/runtime/value/clean/index.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import './any'
|
||||
import './array'
|
||||
import './async-iterator'
|
||||
import './bigint'
|
||||
import './boolean'
|
||||
import './composite'
|
||||
import './constructor'
|
||||
import './date'
|
||||
import './enum'
|
||||
import './function'
|
||||
import './import'
|
||||
import './integer'
|
||||
import './intersect'
|
||||
import './iterator'
|
||||
import './keyof'
|
||||
import './kind'
|
||||
import './literal'
|
||||
import './never'
|
||||
import './not'
|
||||
import './null'
|
||||
import './object'
|
||||
import './promise'
|
||||
import './record'
|
||||
import './recursive'
|
||||
import './ref'
|
||||
import './regexp'
|
||||
import './string'
|
||||
import './symbol'
|
||||
import './template-literal'
|
||||
import './tuple'
|
||||
import './uint8array'
|
||||
import './undefined'
|
||||
import './union'
|
||||
import './unknown'
|
||||
import './void'
|
||||
11
test/runtime/value/clean/integer.ts
Normal file
11
test/runtime/value/clean/integer.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/clean/Integer', () => {
|
||||
it('Should clean 1', () => {
|
||||
const T = Type.Integer()
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
})
|
||||
346
test/runtime/value/clean/intersect.ts
Normal file
346
test/runtime/value/clean/intersect.ts
Normal file
@@ -0,0 +1,346 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
// prettier-ignore
|
||||
describe('value/clean/Intersect', () => {
|
||||
// ----------------------------------------------------------------
|
||||
// Intersect
|
||||
// ----------------------------------------------------------------
|
||||
it('Should clean 1', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() })
|
||||
])
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
it('Should clean 2', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() })
|
||||
])
|
||||
const R = Value.Clean(T, {})
|
||||
Assert.IsEqual(R, {})
|
||||
})
|
||||
it('Should clean 3', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() })
|
||||
])
|
||||
const R = Value.Clean(T, { x: 1, y: 2 })
|
||||
Assert.IsEqual(R, { x: 1, y: 2 })
|
||||
})
|
||||
it('Should clean 4', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() })
|
||||
])
|
||||
const R = Value.Clean(T, { x: 1, y: 2, z: 3 })
|
||||
Assert.IsEqual(R, { x: 1, y: 2 })
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Intersect Discard
|
||||
// ----------------------------------------------------------------
|
||||
it('Should clean discard 1', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() })
|
||||
])
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
it('Should clean discard 2', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() })
|
||||
])
|
||||
const R = Value.Clean(T, { u: null })
|
||||
Assert.IsEqual(R, {})
|
||||
})
|
||||
it('Should clean discard 3', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() })
|
||||
])
|
||||
const R = Value.Clean(T, { u: null, x: 1, y: 2 })
|
||||
Assert.IsEqual(R, { x: 1, y: 2 })
|
||||
})
|
||||
it('Should clean discard 4', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() })
|
||||
])
|
||||
const R = Value.Clean(T, { u: null, x: 1, y: 2 })
|
||||
Assert.IsEqual(R, { x: 1, y: 2 })
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Intersect Deep
|
||||
// ----------------------------------------------------------------
|
||||
it('Should clear intersect deep 1', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() })
|
||||
]),
|
||||
Type.Intersect([
|
||||
Type.Object({ z: Type.Number() }),
|
||||
Type.Object({ w: Type.Number() })
|
||||
])
|
||||
])
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
it('Should clear intersect deep 2', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() })
|
||||
]),
|
||||
Type.Intersect([
|
||||
Type.Object({ z: Type.Number() }),
|
||||
Type.Object({ w: Type.Number() })
|
||||
])
|
||||
])
|
||||
const R = Value.Clean(T, {})
|
||||
Assert.IsEqual(R, {})
|
||||
})
|
||||
it('Should clear intersect deep 3', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() })
|
||||
]),
|
||||
Type.Intersect([
|
||||
Type.Object({ z: Type.Number() }),
|
||||
Type.Object({ w: Type.Number() })
|
||||
])
|
||||
])
|
||||
const R = Value.Clean(T, { x: 1 })
|
||||
Assert.IsEqual(R, { x: 1 })
|
||||
})
|
||||
it('Should clear intersect deep 4', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() })
|
||||
]),
|
||||
Type.Intersect([
|
||||
Type.Object({ z: Type.Number() }),
|
||||
Type.Object({ w: Type.Number() })
|
||||
])
|
||||
])
|
||||
const R = Value.Clean(T, { x: 1, y: 2 })
|
||||
Assert.IsEqual(R, { x: 1, y: 2 })
|
||||
})
|
||||
it('Should clear intersect deep 5', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() })
|
||||
]),
|
||||
Type.Intersect([
|
||||
Type.Object({ z: Type.Number() }),
|
||||
Type.Object({ w: Type.Number() })
|
||||
])
|
||||
])
|
||||
const R = Value.Clean(T, { x: 1, y: 2, z: 3 })
|
||||
Assert.IsEqual(R, { x: 1, y: 2, z: 3 })
|
||||
})
|
||||
it('Should clear intersect deep 6', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() })
|
||||
]),
|
||||
Type.Intersect([
|
||||
Type.Object({ z: Type.Number() }),
|
||||
Type.Object({ w: Type.Number() })
|
||||
])
|
||||
])
|
||||
const R = Value.Clean(T, { x: 1, y: 2, z: 3, w: 3 })
|
||||
Assert.IsEqual(R, { x: 1, y: 2, z: 3, w: 3 })
|
||||
})
|
||||
it('Should clear intersect deep 7', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() })
|
||||
]),
|
||||
Type.Intersect([
|
||||
Type.Object({ z: Type.Number() }),
|
||||
Type.Object({ w: Type.Number() })
|
||||
])
|
||||
])
|
||||
const R = Value.Clean(T, { x: 1, y: 2, z: 3, w: 3 })
|
||||
Assert.IsEqual(R, { x: 1, y: 2, z: 3, w: 3 })
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Intersect Deep Discard
|
||||
// ----------------------------------------------------------------
|
||||
it('Should clear intersect discard deep 1', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() })
|
||||
]),
|
||||
Type.Intersect([
|
||||
Type.Object({ z: Type.Number() }),
|
||||
Type.Object({ w: Type.Number() })
|
||||
])
|
||||
])
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
it('Should clear intersect discard deep 2', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() })
|
||||
]),
|
||||
Type.Intersect([
|
||||
Type.Object({ z: Type.Number() }),
|
||||
Type.Object({ w: Type.Number() })
|
||||
])
|
||||
])
|
||||
const R = Value.Clean(T, { u: null })
|
||||
Assert.IsEqual(R, {})
|
||||
})
|
||||
it('Should clear intersect discard deep 3', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() })
|
||||
]),
|
||||
Type.Intersect([
|
||||
Type.Object({ z: Type.Number() }),
|
||||
Type.Object({ w: Type.Number() })
|
||||
])
|
||||
])
|
||||
const R = Value.Clean(T, { u: null, x: 1 })
|
||||
Assert.IsEqual(R, { x: 1 })
|
||||
})
|
||||
it('Should clear intersect discard deep 4', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() })
|
||||
]),
|
||||
Type.Intersect([
|
||||
Type.Object({ z: Type.Number() }),
|
||||
Type.Object({ w: Type.Number() })
|
||||
])
|
||||
])
|
||||
const R = Value.Clean(T, { u: null, x: 1, y: 2 })
|
||||
Assert.IsEqual(R, { x: 1, y: 2 })
|
||||
})
|
||||
it('Should clear intersect discard deep 5', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() })
|
||||
]),
|
||||
Type.Intersect([
|
||||
Type.Object({ z: Type.Number() }),
|
||||
Type.Object({ w: Type.Number() })
|
||||
])
|
||||
])
|
||||
const R = Value.Clean(T, { u: null, x: 1, y: 2, z: 3 })
|
||||
Assert.IsEqual(R, { x: 1, y: 2, z: 3 })
|
||||
})
|
||||
it('Should clear intersect discard deep 6', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() })
|
||||
]),
|
||||
Type.Intersect([
|
||||
Type.Object({ z: Type.Number() }),
|
||||
Type.Object({ w: Type.Number() })
|
||||
])
|
||||
])
|
||||
const R = Value.Clean(T, { u: null, x: 1, y: 2, z: 3, w: 3 })
|
||||
Assert.IsEqual(R, { x: 1, y: 2, z: 3, w: 3 })
|
||||
})
|
||||
it('Should clear intersect discard deep 7', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.Number() })
|
||||
]),
|
||||
Type.Intersect([
|
||||
Type.Object({ z: Type.Number() }),
|
||||
Type.Object({ w: Type.Number() })
|
||||
])
|
||||
])
|
||||
const R = Value.Clean(T, { u: null, x: 1, y: 2, z: 3, w: 3, a: 1 })
|
||||
Assert.IsEqual(R, { x: 1, y: 2, z: 3, w: 3 })
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Intersect Invalid
|
||||
// ----------------------------------------------------------------
|
||||
it('Should clean intersect invalid 1', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.String() })
|
||||
])
|
||||
const R = Value.Clean(T, { x: 1, y: 2 })
|
||||
Assert.IsEqual(R, { x: 1, y: 2 }) // types are ignored
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Intersect Unevaluted Properties
|
||||
// ----------------------------------------------------------------
|
||||
it('Should clean intersect unevaluated properties 1', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Object({ x: Type.Number() }),
|
||||
Type.Object({ y: Type.String() })
|
||||
], {
|
||||
unevaluatedProperties: Type.String()
|
||||
})
|
||||
const R = Value.Clean(T, { x: 1, y: 2, a: 1, b: '' })
|
||||
Assert.IsEqual(R, { x: 1, y: 2, b: '' })
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Intersect Illogical
|
||||
// ----------------------------------------------------------------
|
||||
it('Should clean illogical 1', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Number(),
|
||||
Type.Object({ x: Type.Number() })
|
||||
])
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
it('Should clean illogical 2', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Number(),
|
||||
Type.Object({ x: Type.Number() })
|
||||
])
|
||||
const R = Value.Clean(T, 1)
|
||||
Assert.IsEqual(R, 1)
|
||||
})
|
||||
it('Should clean illogical 3', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Number(),
|
||||
Type.Object({ x: Type.Number() })
|
||||
])
|
||||
const R = Value.Clean(T, {})
|
||||
Assert.IsEqual(R, {})
|
||||
})
|
||||
it('Should clean illogical 4', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Number(),
|
||||
Type.Object({ x: Type.Number() })
|
||||
])
|
||||
const R = Value.Clean(T, { x: 1 })
|
||||
Assert.IsEqual(R, { x: 1 })
|
||||
})
|
||||
it('Should clean illogical 5', () => {
|
||||
const T = Type.Intersect([
|
||||
Type.Number(),
|
||||
Type.Object({ x: Type.Number() }),
|
||||
])
|
||||
const R = Value.Clean(T, { u: null, x: 1 })
|
||||
Assert.IsEqual(R, { u: null, x: 1 }) // u retained from Number
|
||||
})
|
||||
})
|
||||
11
test/runtime/value/clean/iterator.ts
Normal file
11
test/runtime/value/clean/iterator.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/clean/Iterator', () => {
|
||||
it('Should clean 1', () => {
|
||||
const T = Type.Iterator(Type.String())
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
})
|
||||
11
test/runtime/value/clean/keyof.ts
Normal file
11
test/runtime/value/clean/keyof.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/clean/KeyOf', () => {
|
||||
it('Should clean 1', () => {
|
||||
const T = Type.KeyOf(Type.Object({ x: Type.Number(), y: Type.Number() }))
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
})
|
||||
11
test/runtime/value/clean/kind.ts
Normal file
11
test/runtime/value/clean/kind.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type, Kind } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/clean/Kind', () => {
|
||||
it('Should clean 1', () => {
|
||||
const T = Type.Unsafe({ [Kind]: 'Unknown' })
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
})
|
||||
11
test/runtime/value/clean/literal.ts
Normal file
11
test/runtime/value/clean/literal.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/clean/Literal', () => {
|
||||
it('Should clean 1', () => {
|
||||
const T = Type.Literal(1)
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
})
|
||||
11
test/runtime/value/clean/never.ts
Normal file
11
test/runtime/value/clean/never.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/clean/Never', () => {
|
||||
it('Should clean 1', () => {
|
||||
const T = Type.Never()
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
})
|
||||
11
test/runtime/value/clean/not.ts
Normal file
11
test/runtime/value/clean/not.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/clean/Not', () => {
|
||||
it('Should clean 1', () => {
|
||||
const T = Type.Not(Type.Any())
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
})
|
||||
11
test/runtime/value/clean/null.ts
Normal file
11
test/runtime/value/clean/null.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/clean/Null', () => {
|
||||
it('Should clean 1', () => {
|
||||
const T = Type.Null()
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
})
|
||||
11
test/runtime/value/clean/number.ts
Normal file
11
test/runtime/value/clean/number.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/clean/Number', () => {
|
||||
it('Should clean 1', () => {
|
||||
const T = Type.Number()
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
})
|
||||
178
test/runtime/value/clean/object.ts
Normal file
178
test/runtime/value/clean/object.ts
Normal file
@@ -0,0 +1,178 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/clean/Object', () => {
|
||||
// ----------------------------------------------------------------
|
||||
// Clean
|
||||
// ----------------------------------------------------------------
|
||||
it('Should clean 1', () => {
|
||||
const T = Type.Object({ x: Type.Number() })
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
it('Should clean 2', () => {
|
||||
const T = Type.Object({ x: Type.Number() })
|
||||
const R = Value.Clean(T, {})
|
||||
Assert.IsEqual(R, {})
|
||||
})
|
||||
it('Should clean 3', () => {
|
||||
const T = Type.Object({ x: Type.Number() })
|
||||
const R = Value.Clean(T, { x: 1 })
|
||||
Assert.IsEqual(R, { x: 1 })
|
||||
})
|
||||
it('Should clean 4', () => {
|
||||
const T = Type.Object({ x: Type.Number() })
|
||||
const R = Value.Clean(T, { x: null })
|
||||
Assert.IsEqual(R, { x: null })
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Nested
|
||||
// ----------------------------------------------------------------
|
||||
it('Should clean nested 1', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Object({
|
||||
y: Type.Number(),
|
||||
}),
|
||||
})
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
it('Should clean nested 2', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Object({
|
||||
y: Type.Number(),
|
||||
}),
|
||||
})
|
||||
const R = Value.Clean(T, {})
|
||||
Assert.IsEqual(R, {})
|
||||
})
|
||||
it('Should clean nested 3', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Object({
|
||||
y: Type.Number(),
|
||||
}),
|
||||
})
|
||||
const R = Value.Clean(T, { x: null })
|
||||
Assert.IsEqual(R, { x: null })
|
||||
})
|
||||
it('Should clean nested 4', () => {
|
||||
const T = Type.Object({
|
||||
x: Type.Object({
|
||||
y: Type.Number(),
|
||||
}),
|
||||
})
|
||||
const R = Value.Clean(T, { x: { y: null } })
|
||||
Assert.IsEqual(R, { x: { y: null } })
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Additional Properties
|
||||
// ----------------------------------------------------------------
|
||||
it('Should clean additional properties 1', () => {
|
||||
const T = Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
},
|
||||
{
|
||||
additionalProperties: Type.String(),
|
||||
},
|
||||
)
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
it('Should clean additional properties 2', () => {
|
||||
const T = Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
},
|
||||
{
|
||||
additionalProperties: Type.String(),
|
||||
},
|
||||
)
|
||||
const R = Value.Clean(T, {})
|
||||
Assert.IsEqual(R, {})
|
||||
})
|
||||
it('Should clean additional properties 3', () => {
|
||||
const T = Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
},
|
||||
{
|
||||
additionalProperties: Type.String(),
|
||||
},
|
||||
)
|
||||
const R = Value.Clean(T, { x: 1 })
|
||||
Assert.IsEqual(R, { x: 1 })
|
||||
})
|
||||
it('Should clean additional properties 4', () => {
|
||||
const T = Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
},
|
||||
{
|
||||
additionalProperties: Type.String(),
|
||||
},
|
||||
)
|
||||
const R = Value.Clean(T, { x: 1, y: 2 })
|
||||
Assert.IsEqual(R, { x: 1, y: 2 })
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Additional Properties Discard
|
||||
// ----------------------------------------------------------------
|
||||
it('Should clean additional properties discard 1', () => {
|
||||
const T = Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
},
|
||||
{
|
||||
additionalProperties: Type.String(),
|
||||
},
|
||||
)
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
it('Should clean additional properties discard 2', () => {
|
||||
const T = Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
},
|
||||
{
|
||||
additionalProperties: Type.String(),
|
||||
},
|
||||
)
|
||||
const R = Value.Clean(T, { k: '', d: null })
|
||||
Assert.IsEqual(R, { k: '' })
|
||||
})
|
||||
it('Should clean additional properties discard 3', () => {
|
||||
const T = Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
},
|
||||
{
|
||||
additionalProperties: Type.String(),
|
||||
},
|
||||
)
|
||||
const R = Value.Clean(T, { k: '', d: null, x: 1 })
|
||||
Assert.IsEqual(R, { k: '', x: 1 })
|
||||
})
|
||||
it('Should clean additional properties discard 4', () => {
|
||||
const T = Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
y: Type.Number(),
|
||||
},
|
||||
{
|
||||
additionalProperties: Type.String(),
|
||||
},
|
||||
)
|
||||
const R = Value.Clean(T, { k: '', d: null, x: 1, y: 2 })
|
||||
Assert.IsEqual(R, { k: '', x: 1, y: 2 })
|
||||
})
|
||||
})
|
||||
11
test/runtime/value/clean/promise.ts
Normal file
11
test/runtime/value/clean/promise.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/clean/Promise', () => {
|
||||
it('Should clean 1', () => {
|
||||
const T = Type.Promise(Type.Any())
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
})
|
||||
114
test/runtime/value/clean/record.ts
Normal file
114
test/runtime/value/clean/record.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/clean/Record', () => {
|
||||
// ----------------------------------------------------------------
|
||||
// Clean
|
||||
// ----------------------------------------------------------------
|
||||
it('Should clean 1', () => {
|
||||
const T = Type.Record(Type.Number(), Type.String())
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
it('Should clean 2', () => {
|
||||
const T = Type.Record(Type.Number(), Type.String())
|
||||
const R = Value.Clean(T, {})
|
||||
Assert.IsEqual(R, {})
|
||||
})
|
||||
it('Should clean 3', () => {
|
||||
const T = Type.Record(Type.Number(), Type.String())
|
||||
const R = Value.Clean(T, { 0: null })
|
||||
Assert.IsEqual(R, { 0: null })
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Clean Discard
|
||||
// ----------------------------------------------------------------
|
||||
it('Should clean discard 1', () => {
|
||||
const T = Type.Record(Type.Number(), Type.String())
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
it('Should clean discard 2', () => {
|
||||
const T = Type.Record(Type.Number(), Type.String())
|
||||
const R = Value.Clean(T, { a: 1 })
|
||||
Assert.IsEqual(R, {})
|
||||
})
|
||||
it('Should clean discard 3', () => {
|
||||
const T = Type.Record(Type.Number(), Type.String())
|
||||
const R = Value.Clean(T, { a: 1, 0: null })
|
||||
Assert.IsEqual(R, { 0: null })
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Additional Properties
|
||||
// ----------------------------------------------------------------
|
||||
it('Should clean additional properties 1', () => {
|
||||
const T = Type.Record(Type.Number(), Type.String(), {
|
||||
additionalProperties: Type.Boolean(),
|
||||
})
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
it('Should clean additional properties 2', () => {
|
||||
const T = Type.Record(Type.Number(), Type.String(), {
|
||||
additionalProperties: Type.Boolean(),
|
||||
})
|
||||
const R = Value.Clean(T, {})
|
||||
Assert.IsEqual(R, {})
|
||||
})
|
||||
it('Should clean additional properties 3', () => {
|
||||
const T = Type.Record(Type.Number(), Type.String(), {
|
||||
additionalProperties: Type.Boolean(),
|
||||
})
|
||||
const R = Value.Clean(T, { 0: null })
|
||||
Assert.IsEqual(R, { 0: null })
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Additional Properties Discard
|
||||
// ----------------------------------------------------------------
|
||||
it('Should clean additional properties discard 1', () => {
|
||||
const T = Type.Record(Type.Number(), Type.String(), {
|
||||
additionalProperties: Type.Boolean(),
|
||||
})
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
it('Should clean additional properties discard 2', () => {
|
||||
const T = Type.Record(Type.Number(), Type.String(), {
|
||||
additionalProperties: Type.Boolean(),
|
||||
})
|
||||
const R = Value.Clean(T, { a: null })
|
||||
Assert.IsEqual(R, {})
|
||||
})
|
||||
it('Should clean additional properties discard 3', () => {
|
||||
const T = Type.Record(Type.Number(), Type.String(), {
|
||||
additionalProperties: Type.Boolean(),
|
||||
})
|
||||
const R = Value.Clean(T, { a: null, 0: null })
|
||||
Assert.IsEqual(R, { 0: null })
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Additional Properties Keep
|
||||
// ----------------------------------------------------------------
|
||||
it('Should clean additional properties keep 1', () => {
|
||||
const T = Type.Record(Type.Number(), Type.String(), {
|
||||
additionalProperties: Type.Boolean(),
|
||||
})
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
it('Should clean additional properties keep 2', () => {
|
||||
const T = Type.Record(Type.Number(), Type.String(), {
|
||||
additionalProperties: Type.Boolean(),
|
||||
})
|
||||
const R = Value.Clean(T, { a: true })
|
||||
Assert.IsEqual(R, { a: true })
|
||||
})
|
||||
it('Should clean additional properties keep 3', () => {
|
||||
const T = Type.Record(Type.Number(), Type.String(), {
|
||||
additionalProperties: Type.Boolean(),
|
||||
})
|
||||
const R = Value.Clean(T, { a: true, 0: null })
|
||||
Assert.IsEqual(R, { a: true, 0: null })
|
||||
})
|
||||
})
|
||||
112
test/runtime/value/clean/recursive.ts
Normal file
112
test/runtime/value/clean/recursive.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/clean/Recursive', () => {
|
||||
// ----------------------------------------------------------------
|
||||
// Clean
|
||||
// ----------------------------------------------------------------
|
||||
it('Should clean 1', () => {
|
||||
const T = Type.Recursive((This) =>
|
||||
Type.Object({
|
||||
id: Type.String(),
|
||||
nodes: Type.Array(This),
|
||||
}),
|
||||
)
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
it('Should clean 2', () => {
|
||||
const T = Type.Recursive((This) =>
|
||||
Type.Object({
|
||||
id: Type.String(),
|
||||
nodes: Type.Array(This),
|
||||
}),
|
||||
)
|
||||
const R = Value.Clean(T, { id: null })
|
||||
Assert.IsEqual(R, { id: null })
|
||||
})
|
||||
it('Should clean 3', () => {
|
||||
const T = Type.Recursive((This) =>
|
||||
Type.Object({
|
||||
id: Type.String(),
|
||||
nodes: Type.Array(This),
|
||||
}),
|
||||
)
|
||||
const R = Value.Clean(T, { id: null, nodes: null })
|
||||
Assert.IsEqual(R, { id: null, nodes: null })
|
||||
})
|
||||
it('Should clean 4', () => {
|
||||
const T = Type.Recursive((This) =>
|
||||
Type.Object({
|
||||
id: Type.String(),
|
||||
nodes: Type.Array(This),
|
||||
}),
|
||||
)
|
||||
const R = Value.Clean(T, { id: null, nodes: [] })
|
||||
Assert.IsEqual(R, { id: null, nodes: [] })
|
||||
})
|
||||
it('Should clean 5', () => {
|
||||
const T = Type.Recursive((This) =>
|
||||
Type.Object({
|
||||
id: Type.String(),
|
||||
nodes: Type.Array(This),
|
||||
}),
|
||||
)
|
||||
const R = Value.Clean(T, { id: null, nodes: [{ id: null }] })
|
||||
Assert.IsEqual(R, { id: null, nodes: [{ id: null }] })
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Clean Discard
|
||||
// ----------------------------------------------------------------
|
||||
it('Should clean discard 1', () => {
|
||||
const T = Type.Recursive((This) =>
|
||||
Type.Object({
|
||||
id: Type.String(),
|
||||
nodes: Type.Array(This),
|
||||
}),
|
||||
)
|
||||
const R = Value.Clean(T, null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
it('Should clean discard 2', () => {
|
||||
const T = Type.Recursive((This) =>
|
||||
Type.Object({
|
||||
id: Type.String(),
|
||||
nodes: Type.Array(This),
|
||||
}),
|
||||
)
|
||||
const R = Value.Clean(T, { u: null, id: null })
|
||||
Assert.IsEqual(R, { id: null })
|
||||
})
|
||||
it('Should clean discard 3', () => {
|
||||
const T = Type.Recursive((This) =>
|
||||
Type.Object({
|
||||
id: Type.String(),
|
||||
nodes: Type.Array(This),
|
||||
}),
|
||||
)
|
||||
const R = Value.Clean(T, { u: null, id: null, nodes: null })
|
||||
Assert.IsEqual(R, { id: null, nodes: null })
|
||||
})
|
||||
it('Should clean discard 4', () => {
|
||||
const T = Type.Recursive((This) =>
|
||||
Type.Object({
|
||||
id: Type.String(),
|
||||
nodes: Type.Array(This),
|
||||
}),
|
||||
)
|
||||
const R = Value.Clean(T, { u: null, id: null, nodes: [] })
|
||||
Assert.IsEqual(R, { id: null, nodes: [] })
|
||||
})
|
||||
it('Should clean discard 5', () => {
|
||||
const T = Type.Recursive((This) =>
|
||||
Type.Object({
|
||||
id: Type.String(),
|
||||
nodes: Type.Array(This),
|
||||
}),
|
||||
)
|
||||
const R = Value.Clean(T, { u: null, id: null, nodes: [{ u: null, id: null }] })
|
||||
Assert.IsEqual(R, { id: null, nodes: [{ id: null }] })
|
||||
})
|
||||
})
|
||||
78
test/runtime/value/clean/ref.ts
Normal file
78
test/runtime/value/clean/ref.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { Assert } from '../../assert/index'
|
||||
|
||||
describe('value/clean/Ref', () => {
|
||||
// ----------------------------------------------------------------
|
||||
// Clean
|
||||
// ----------------------------------------------------------------
|
||||
it('Should clean 1', () => {
|
||||
const A = Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
},
|
||||
{ $id: 'A' },
|
||||
)
|
||||
const T = Type.Ref('A')
|
||||
const R = Value.Clean(T, [A], null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
it('Should clean 2', () => {
|
||||
const A = Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
},
|
||||
{ $id: 'A' },
|
||||
)
|
||||
const T = Type.Ref('A')
|
||||
const R = Value.Clean(T, [A], {})
|
||||
Assert.IsEqual(R, {})
|
||||
})
|
||||
it('Should clean 3', () => {
|
||||
const A = Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
},
|
||||
{ $id: 'A' },
|
||||
)
|
||||
const T = Type.Ref('A')
|
||||
const R = Value.Clean(T, [A], { x: null })
|
||||
Assert.IsEqual(R, { x: null })
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Clean Discard
|
||||
// ----------------------------------------------------------------
|
||||
it('Should clean discard 1', () => {
|
||||
const A = Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
},
|
||||
{ $id: 'A' },
|
||||
)
|
||||
const T = Type.Ref('A')
|
||||
const R = Value.Clean(T, [A], null)
|
||||
Assert.IsEqual(R, null)
|
||||
})
|
||||
it('Should clean discard 2', () => {
|
||||
const A = Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
},
|
||||
{ $id: 'A' },
|
||||
)
|
||||
const T = Type.Ref('A')
|
||||
const R = Value.Clean(T, [A], { a: null })
|
||||
Assert.IsEqual(R, {})
|
||||
})
|
||||
it('Should clean discard 3', () => {
|
||||
const A = Type.Object(
|
||||
{
|
||||
x: Type.Number(),
|
||||
},
|
||||
{ $id: 'A' },
|
||||
)
|
||||
const T = Type.Ref('A')
|
||||
const R = Value.Clean(T, [A], { a: null, x: null })
|
||||
Assert.IsEqual(R, { x: null })
|
||||
})
|
||||
})
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user