Skip to main content
Glama
nullable.test.js11.6 kB
'use strict' const { test } = require('node:test') const build = require('..') const nullable = true const complexObject = { type: 'object', properties: { nullableString: { type: 'string', nullable }, nullableNumber: { type: 'number', nullable }, nullableInteger: { type: 'integer', nullable }, nullableBoolean: { type: 'boolean', nullable }, nullableNull: { type: 'null', nullable }, nullableArray: { type: 'array', nullable: true, items: {} }, nullableObject: { type: 'object', nullable: true }, objectWithNullableProps: { type: 'object', nullable: false, additionalProperties: true, properties: { nullableString: { type: 'string', nullable }, nullableNumber: { type: 'number', nullable }, nullableInteger: { type: 'integer', nullable }, nullableBoolean: { type: 'boolean', nullable }, nullableNull: { type: 'null', nullable }, nullableArray: { type: 'array', nullable: true, items: {} } } }, arrayWithNullableItems: { type: 'array', nullable: true, items: { type: ['integer', 'string'], nullable: true } } } } const complexData = { nullableString: null, nullableNumber: null, nullableInteger: null, nullableBoolean: null, nullableNull: null, nullableArray: null, nullableObject: null, objectWithNullableProps: { additionalProp: null, nullableString: null, nullableNumber: null, nullableInteger: null, nullableBoolean: null, nullableNull: null, nullableArray: null }, arrayWithNullableItems: [1, 2, null] } const complexExpectedResult = { nullableString: null, nullableNumber: null, nullableInteger: null, nullableBoolean: null, nullableNull: null, nullableArray: null, nullableObject: null, objectWithNullableProps: { additionalProp: null, nullableString: null, nullableNumber: null, nullableInteger: null, nullableBoolean: null, nullableNull: null, nullableArray: null }, arrayWithNullableItems: [1, 2, null] } const testSet = { nullableString: [{ type: 'string', nullable }, null, null], nullableNumber: [{ type: 'number', nullable }, null, null], nullableInteger: [{ type: 'integer', nullable }, null, null], nullableBoolean: [{ type: 'boolean', nullable }, null, null], nullableNull: [{ type: 'null', nullable }, null, null], nullableArray: [{ type: 'array', nullable: true, items: {} }, null, null], nullableObject: [{ type: 'object', nullable: true }, null, null], complexObject: [complexObject, complexData, complexExpectedResult, { ajv: { allowUnionTypes: true } }] } Object.keys(testSet).forEach(key => { test(`handle nullable:true in ${key} correctly`, (t) => { t.plan(1) const [ schema, data, expected, extraOptions ] = testSet[key] const stringifier = build(schema, extraOptions) const result = stringifier(data) t.assert.deepStrictEqual(JSON.parse(result), expected) }) }) test('handle nullable number correctly', (t) => { t.plan(2) const schema = { type: 'number', nullable: true } const stringify = build(schema) const data = null const result = stringify(data) t.assert.equal(result, JSON.stringify(data)) t.assert.equal(JSON.parse(result), data) }) test('handle nullable integer correctly', (t) => { t.plan(2) const schema = { type: 'integer', nullable: true } const stringify = build(schema) const data = null const result = stringify(data) t.assert.equal(result, JSON.stringify(data)) t.assert.equal(JSON.parse(result), data) }) test('handle nullable boolean correctly', (t) => { t.plan(2) const schema = { type: 'boolean', nullable: true } const stringify = build(schema) const data = null const result = stringify(data) t.assert.equal(result, JSON.stringify(data)) t.assert.equal(JSON.parse(result), data) }) test('handle nullable string correctly', (t) => { t.plan(2) const schema = { type: 'string', nullable: true } const stringify = build(schema) const data = null const result = stringify(data) t.assert.equal(result, JSON.stringify(data)) t.assert.equal(JSON.parse(result), data) }) test('handle nullable date-time correctly', (t) => { t.plan(2) const schema = { type: 'string', format: 'date-time', nullable: true } const stringify = build(schema) const data = null const result = stringify(data) t.assert.equal(result, JSON.stringify(data)) t.assert.equal(JSON.parse(result), data) }) test('handle nullable date correctly', (t) => { t.plan(2) const schema = { type: 'string', format: 'date', nullable: true } const stringify = build(schema) const data = null const result = stringify(data) t.assert.equal(result, JSON.stringify(data)) t.assert.equal(JSON.parse(result), data) }) test('handle nullable time correctly', (t) => { t.plan(2) const schema = { type: 'string', format: 'time', nullable: true } const stringify = build(schema) const data = null const result = stringify(data) t.assert.equal(result, JSON.stringify(data)) t.assert.equal(JSON.parse(result), data) }) test('large array of nullable strings with default mechanism', (t) => { t.plan(2) const schema = { type: 'object', properties: { ids: { type: 'array', items: { type: 'string', nullable: true } } } } const options = { largeArraySize: 2e4, largeArrayMechanism: 'default' } const stringify = build(schema, options) const data = { ids: new Array(2e4).fill(null) } const result = stringify(data) t.assert.equal(result, JSON.stringify(data)) t.assert.deepStrictEqual(JSON.parse(result), data) }) test('large array of nullable date-time strings with default mechanism', (t) => { t.plan(2) const schema = { type: 'object', properties: { ids: { type: 'array', items: { type: 'string', format: 'date-time', nullable: true } } } } const options = { largeArraySize: 2e4, largeArrayMechanism: 'default' } const stringify = build(schema, options) const data = { ids: new Array(2e4).fill(null) } const result = stringify(data) t.assert.equal(result, JSON.stringify(data)) t.assert.deepStrictEqual(JSON.parse(result), data) }) test('large array of nullable date-time strings with default mechanism', (t) => { t.plan(2) const schema = { type: 'object', properties: { ids: { type: 'array', items: { type: 'string', format: 'date', nullable: true } } } } const options = { largeArraySize: 2e4, largeArrayMechanism: 'default' } const stringify = build(schema, options) const data = { ids: new Array(2e4).fill(null) } const result = stringify(data) t.assert.equal(result, JSON.stringify(data)) t.assert.deepStrictEqual(JSON.parse(result), data) }) test('large array of nullable date-time strings with default mechanism', (t) => { t.plan(2) const schema = { type: 'object', properties: { ids: { type: 'array', items: { type: 'string', format: 'time', nullable: true } } } } const options = { largeArraySize: 2e4, largeArrayMechanism: 'default' } const stringify = build(schema, options) const data = { ids: new Array(2e4).fill(null) } const result = stringify(data) t.assert.equal(result, JSON.stringify(data)) t.assert.deepStrictEqual(JSON.parse(result), data) }) test('large array of nullable numbers with default mechanism', (t) => { t.plan(2) const schema = { type: 'object', properties: { ids: { type: 'array', items: { type: 'number', nullable: true } } } } const options = { largeArraySize: 2e4, largeArrayMechanism: 'default' } const stringify = build(schema, options) const data = { ids: new Array(2e4).fill(null) } const result = stringify(data) t.assert.equal(result, JSON.stringify(data)) t.assert.deepStrictEqual(JSON.parse(result), data) }) test('large array of nullable integers with default mechanism', (t) => { t.plan(2) const schema = { type: 'object', properties: { ids: { type: 'array', items: { type: 'integer', nullable: true } } } } const options = { largeArraySize: 2e4, largeArrayMechanism: 'default' } const stringify = build(schema, options) const data = { ids: new Array(2e4).fill(null) } const result = stringify(data) t.assert.equal(result, JSON.stringify(data)) t.assert.deepStrictEqual(JSON.parse(result), data) }) test('large array of nullable booleans with default mechanism', (t) => { t.plan(2) const schema = { type: 'object', properties: { ids: { type: 'array', items: { type: 'boolean', nullable: true } } } } const options = { largeArraySize: 2e4, largeArrayMechanism: 'default' } const stringify = build(schema, options) const data = { ids: new Array(2e4).fill(null) } const result = stringify(data) t.assert.equal(result, JSON.stringify(data)) t.assert.deepStrictEqual(JSON.parse(result), data) }) test('nullable type in the schema', (t) => { t.plan(2) const schema = { type: ['object', 'null'], properties: { foo: { type: 'string' } } } const stringify = build(schema) const data = { foo: 'bar' } t.assert.equal(stringify(data), JSON.stringify(data)) t.assert.equal(stringify(null), JSON.stringify(null)) }) test('throw an error if the value doesn\'t match the type', (t) => { t.plan(2) const schema = { type: 'object', additionalProperties: false, required: ['data'], properties: { data: { type: 'array', minItems: 1, items: { oneOf: [ { type: 'string' }, { type: 'number' } ] } } } } const stringify = build(schema) const validData = { data: [1, 'testing'] } t.assert.equal(stringify(validData), JSON.stringify(validData)) const invalidData = { data: [false, 'testing'] } t.assert.throws(() => stringify(invalidData)) }) test('nullable value in oneOf', (t) => { t.plan(1) const schema = { type: 'object', properties: { data: { oneOf: [ { type: 'array', items: { type: 'object', properties: { id: { type: 'integer', minimum: 1 } }, additionalProperties: false, required: ['id'] } }, { type: 'array', items: { type: 'object', properties: { job: { type: 'string', nullable: true } }, additionalProperties: false, required: ['job'] } } ] } }, required: ['data'], additionalProperties: false } const stringify = build(schema) const data = { data: [{ job: null }] } t.assert.equal(stringify(data), JSON.stringify(data)) })

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/krtw00/search-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server