import assert from 'node:assert/strict' import { test } from 'node:test' import { toJsonValue } from '../lib/json.js' test('drops undefined properties, which is the shape that broke status', () => { const value = toJsonValue({ ok: true, error: undefined, url: 'http://x' }) assert.deepEqual(value, { ok: true, url: 'http://x' }) assert.equal(Object.hasOwn(value, 'error'), false) }) test('the result survives a JSON round trip unchanged', () => { const value = toJsonValue({ nested: { keep: 1, drop: undefined, deeper: { alsoDrop: undefined } }, list: [1, 'two', { three: true, four: undefined }], }) assert.deepEqual(value, JSON.parse(JSON.stringify(value))) }) test('an undefined array slot becomes null rather than shifting the indices', () => { assert.deepEqual(toJsonValue([1, undefined, 3]), [1, null, 3]) }) test('non-finite numbers become null, exactly as JSON.stringify would', () => { assert.deepEqual(toJsonValue({ a: Number.NaN, b: Infinity, c: -Infinity, d: 1.5 }), { a: null, b: null, c: null, d: 1.5, }) }) test('functions, symbols and undefined vanish; bigints become strings', () => { const value = toJsonValue({ fn: () => {}, sym: Symbol('x'), gone: undefined, big: 10n, keep: 'yes' }) assert.deepEqual(value, { big: '10', keep: 'yes' }) }) test('null and primitives pass through', () => { assert.equal(toJsonValue(null), null) assert.equal(toJsonValue('a'), 'a') assert.equal(toJsonValue(0), 0) assert.equal(toJsonValue(false), false) }) test('a circular value is refused rather than recursed into', () => { const circular = { name: 'loop' } circular.self = circular assert.throws(() => toJsonValue(circular), /circular/) }) test('a repeated but non-circular reference is fine', () => { const shared = { id: 1 } assert.deepEqual(toJsonValue({ a: shared, b: shared }), { a: { id: 1 }, b: { id: 1 } }) }) test('an already-clean value is returned unchanged in value', () => { const clean = { kind: 'foreground', ok: true, exitCode: 0, report: 'cluster 1:' } assert.deepEqual(toJsonValue(clean), clean) })