This commit is contained in:
sinclair
2025-12-24 15:44:34 +09:00
commit 13d553220c
1047 changed files with 80931 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
import './policy/index'
import './type/index'

View File

@@ -0,0 +1,65 @@
import { Ok, Fail } from '../../compiler/validate'
import { TypeSystemPolicy } from '@sinclair/typebox/system'
import { Type } from '@sinclair/typebox'
describe('system/TypeSystemPolicy/AllowArrayObject', () => {
beforeEach(() => {
TypeSystemPolicy.AllowArrayObject = true
})
afterEach(() => {
TypeSystemPolicy.AllowArrayObject = false
})
// ---------------------------------------------------------------
// Object
// ---------------------------------------------------------------
it('Should validate arrays with empty objects', () => {
const T = Type.Object({})
Ok(T, [0, 1, 2])
})
it('Should validate arrays with objects with length property', () => {
const T = Type.Object({ length: Type.Number() })
Ok(T, [0, 1, 2])
})
it('Should validate arrays with objects with additionalProperties false when array has no elements', () => {
const T = Type.Object({ length: Type.Number() }, { additionalProperties: false })
Ok(T, [])
})
it('Should not validate arrays with objects with additionalProperties false when array has elements', () => {
const T = Type.Object({ length: Type.Number() }, { additionalProperties: false })
Fail(T, [0, 1, 2])
})
it('Should not validate arrays with objects when length property is string', () => {
const T = Type.Object({ length: Type.String() })
Fail(T, [0, 1, 2])
})
// ---------------------------------------------------------------
// Record
// ---------------------------------------------------------------
it('Should validate arrays as Records with String Keys', () => {
const T = Type.Record(Type.String(), Type.Number())
Ok(T, [0, 1, 2])
})
it('Should validate arrays as Records with Number Keys', () => {
const T = Type.Record(Type.Number(), Type.Number())
Ok(T, [0, 1, 2])
})
it('Should validate arrays as Records with Integer Keys', () => {
const T = Type.Record(Type.Integer(), Type.Number())
Ok(T, [0, 1, 2])
})
it('Should not validate arrays as Records with Object Values', () => {
const T = Type.Record(
Type.String(),
Type.Object({
x: Type.Number(),
y: Type.Number(),
z: Type.Number(),
}),
)
Ok(T, [
{ x: 1, y: 1, z: 1 },
{ x: 1, y: 1, z: 1 },
{ x: 1, y: 1, z: 1 },
])
})
})

View File

@@ -0,0 +1,62 @@
import { Ok, Fail } from '../../compiler/validate'
import { TypeSystemPolicy } from '@sinclair/typebox/system'
import { Type } from '@sinclair/typebox'
describe('system/TypeSystemPolicy/AllowNaN', () => {
beforeEach(() => {
TypeSystemPolicy.AllowNaN = true
})
afterEach(() => {
TypeSystemPolicy.AllowNaN = false
})
// ---------------------------------------------------------------
// Number
// ---------------------------------------------------------------
it('Should validate number with NaN', () => {
const T = Type.Number()
Ok(T, NaN)
})
it('Should validate number with +Infinity', () => {
const T = Type.Number()
Ok(T, Infinity)
})
it('Should validate number with -Infinity', () => {
const T = Type.Number()
Ok(T, -Infinity)
})
// ---------------------------------------------------------------
// Integer
//
// Note: The Number.isInteger() test will fail for NaN. Because
// of this we cannot reasonably override NaN handling for integers.
// ---------------------------------------------------------------
it('Should not validate integer with NaN', () => {
const T = Type.Integer()
Fail(T, NaN)
})
it('Should not validate integer with +Infinity', () => {
const T = Type.Integer()
Fail(T, Infinity)
})
it('Should not validate integer with -Infinity', () => {
const T = Type.Integer()
Fail(T, -Infinity)
})
// ---------------------------------------------------------------
// BigInt
//
// Note: We expect failures here as bigint isn't IEEE754
// ---------------------------------------------------------------
it('Should not validate bigint with NaN', () => {
const T = Type.BigInt()
Fail(T, NaN)
})
it('Should not validate bigint with +Infinity', () => {
const T = Type.BigInt()
Fail(T, Infinity)
})
it('Should not validate bigint with -Infinity', () => {
const T = Type.BigInt()
Fail(T, -Infinity)
})
})

View File

@@ -0,0 +1,31 @@
import { Ok } from '../../compiler/validate'
import { TypeSystemPolicy } from '@sinclair/typebox/system'
import { Type } from '@sinclair/typebox'
describe('system/TypeSystemPolicy/AllowNullVoid', () => {
beforeEach(() => {
TypeSystemPolicy.AllowNullVoid = true
})
afterEach(() => {
TypeSystemPolicy.AllowNullVoid = false
})
// ---------------------------------------------------------------
// Object
// ---------------------------------------------------------------
it('Should validate with null', () => {
const T = Type.Void()
Ok(T, null)
})
it('Should validate with undefined', () => {
const T = Type.Void()
Ok(T, undefined)
})
it('Should validate with void 0', () => {
const T = Type.Void()
Ok(T, void 0)
})
it('Should validate with void 1', () => {
const T = Type.Void()
Ok(T, void 1)
})
})

View File

@@ -0,0 +1,39 @@
import { Ok, Fail } from '../../compiler/validate'
import { TypeSystemPolicy } from '@sinclair/typebox/system'
import { Type } from '@sinclair/typebox'
describe('system/TypeSystemPolicy/ExactOptionalPropertyTypes', () => {
beforeEach(() => {
TypeSystemPolicy.ExactOptionalPropertyTypes = true
})
afterEach(() => {
TypeSystemPolicy.ExactOptionalPropertyTypes = false
})
// ---------------------------------------------------------------
// Number
// ---------------------------------------------------------------
it('Should not validate optional number', () => {
const T = Type.Object({
x: Type.Optional(Type.Number()),
})
Ok(T, {})
Ok(T, { x: 1 })
Fail(T, { x: undefined })
})
it('Should not validate undefined', () => {
const T = Type.Object({
x: Type.Optional(Type.Undefined()),
})
Ok(T, {})
Fail(T, { x: 1 })
Ok(T, { x: undefined })
})
it('Should validate optional number | undefined', () => {
const T = Type.Object({
x: Type.Optional(Type.Union([Type.Number(), Type.Undefined()])),
})
Ok(T, {})
Ok(T, { x: 1 })
Ok(T, { x: undefined })
})
})

View File

@@ -0,0 +1,5 @@
import './allow-array-object'
import './allow-nan'
import './allow-null-void'
import './exact-optional-property-types'
import './instance-mode'

View File

@@ -0,0 +1,34 @@
import { TypeSystemPolicy } from '@sinclair/typebox/system'
import { Type } from '@sinclair/typebox'
import { Assert } from '../../assert/index'
describe('system/TypeSystemPolicy/InstanceMode', () => {
after(() => {
TypeSystemPolicy.InstanceMode = 'freeze'
})
// ---------------------------------------------------------------
// Number
// ---------------------------------------------------------------
it('Should use instance mode default', () => {
TypeSystemPolicy.InstanceMode = 'default'
const S = Type.String()
const T = Type.Array(S)
S.$id = 'updated'
Assert.IsEqual(T.items.$id, 'updated')
})
it('Should use instance mode clone', () => {
TypeSystemPolicy.InstanceMode = 'clone'
const S = Type.String()
const T = Type.Array(S)
S.$id = 'updated'
Assert.IsEqual(T.items.$id, undefined)
})
it('Should use instance mode freeze', () => {
TypeSystemPolicy.InstanceMode = 'freeze'
Assert.Throws(() => {
const S = Type.String()
const T = Type.Array(S)
S.$id = 'updated'
})
})
})

View File

@@ -0,0 +1,19 @@
import { Ok, Fail } from '../../compiler/validate'
import { Assert } from '../../assert/index'
import { TypeSystem } from '@sinclair/typebox/system'
import { Type, FormatRegistry } from '@sinclair/typebox'
describe('system/TypeSystem/Format', () => {
it('Should create and validate a format', () => {
const Foo = TypeSystem.Format('Foo', (value) => value === 'foo')
const T = Type.String({ format: Foo })
Ok(T, 'foo')
Fail(T, 'bar')
FormatRegistry.Delete('Foo')
})
it('Should throw if registering the same type twice', () => {
TypeSystem.Format('Foo', () => true)
Assert.Throws(() => TypeSystem.Format('Foo', () => true))
FormatRegistry.Delete('Foo')
})
})

View File

@@ -0,0 +1,2 @@
import './format'
import './type'

View File

@@ -0,0 +1,22 @@
import { Ok, Fail } from '../../compiler/validate'
import { TypeSystem } from '@sinclair/typebox/system'
import { TypeRegistry } from '@sinclair/typebox'
import { Assert } from '../../assert/index'
describe('system/TypeSystem/Type', () => {
it('Should create and validate a type', () => {
const Foo = TypeSystem.Type<string>('Foo', (options, value) => {
Assert.IsEqual(options.option, 'test')
return value === 'foo'
})
const T = Foo({ option: 'test' })
Ok(T, 'foo')
Fail(T, 'bar')
TypeRegistry.Delete('Foo')
})
it('Should throw if registering the same type twice', () => {
TypeSystem.Type('Foo', () => true)
Assert.Throws(() => TypeSystem.Type('Foo', () => true))
TypeRegistry.Delete('Foo')
})
})