269 lines
7.3 KiB
TypeScript
269 lines
7.3 KiB
TypeScript
import assert from 'node:assert';
|
|
import { describe, test } from 'vitest';
|
|
import { fixJson } from './fix-json';
|
|
|
|
test('should handle empty input', () => {
|
|
assert.strictEqual(fixJson(''), '');
|
|
});
|
|
|
|
describe('literals', () => {
|
|
test('should handle incomplete null', () => {
|
|
assert.strictEqual(fixJson('nul'), 'null');
|
|
});
|
|
|
|
test('should handle incomplete true', () => {
|
|
assert.strictEqual(fixJson('t'), 'true');
|
|
});
|
|
|
|
test('should handle incomplete false', () => {
|
|
assert.strictEqual(fixJson('fals'), 'false');
|
|
});
|
|
});
|
|
|
|
describe('number', () => {
|
|
test('should handle incomplete numbers', () => {
|
|
assert.strictEqual(fixJson('12.'), '12');
|
|
});
|
|
|
|
test('should handle numbers with dot', () => {
|
|
assert.strictEqual(fixJson('12.2'), '12.2');
|
|
});
|
|
|
|
test('should handle negative numbers', () => {
|
|
assert.strictEqual(fixJson('-12'), '-12');
|
|
});
|
|
|
|
test('should handle incomplete negative numbers', () => {
|
|
assert.strictEqual(fixJson('-'), '');
|
|
});
|
|
|
|
test('should handle e-notation numbers', () => {
|
|
assert.strictEqual(fixJson('2.5e'), '2.5');
|
|
assert.strictEqual(fixJson('2.5e-'), '2.5');
|
|
assert.strictEqual(fixJson('2.5e3'), '2.5e3');
|
|
assert.strictEqual(fixJson('-2.5e3'), '-2.5e3');
|
|
});
|
|
|
|
test('should handle uppercase e-notation numbers', () => {
|
|
assert.strictEqual(fixJson('2.5E'), '2.5');
|
|
assert.strictEqual(fixJson('2.5E-'), '2.5');
|
|
assert.strictEqual(fixJson('2.5E3'), '2.5E3');
|
|
assert.strictEqual(fixJson('-2.5E3'), '-2.5E3');
|
|
});
|
|
|
|
test('should handle incomplete numbers', () => {
|
|
assert.strictEqual(fixJson('12.e'), '12');
|
|
assert.strictEqual(fixJson('12.34e'), '12.34');
|
|
assert.strictEqual(fixJson('5e'), '5');
|
|
});
|
|
});
|
|
|
|
describe('string', () => {
|
|
test('should handle incomplete strings', () => {
|
|
assert.strictEqual(fixJson('"abc'), '"abc"');
|
|
});
|
|
|
|
test('should handle escape sequences', () => {
|
|
assert.strictEqual(
|
|
fixJson('"value with \\"quoted\\" text and \\\\ escape'),
|
|
'"value with \\"quoted\\" text and \\\\ escape"',
|
|
);
|
|
});
|
|
|
|
test('should handle incomplete escape sequences', () => {
|
|
assert.strictEqual(fixJson('"value with \\'), '"value with "');
|
|
});
|
|
|
|
test('should handle unicode characters', () => {
|
|
assert.strictEqual(
|
|
fixJson('"value with unicode \u003C"'),
|
|
'"value with unicode \u003C"',
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('array', () => {
|
|
test('should handle incomplete array', () => {
|
|
assert.strictEqual(fixJson('['), '[]');
|
|
});
|
|
|
|
test('should handle closing bracket after number in array', () => {
|
|
assert.strictEqual(fixJson('[[1], [2'), '[[1], [2]]');
|
|
});
|
|
|
|
test('should handle closing bracket after string in array', () => {
|
|
assert.strictEqual(fixJson(`[["1"], ["2`), `[["1"], ["2"]]`);
|
|
});
|
|
|
|
test('should handle closing bracket after literal in array', () => {
|
|
assert.strictEqual(fixJson('[[false], [nu'), '[[false], [null]]');
|
|
});
|
|
|
|
test('should handle closing bracket after array in array', () => {
|
|
assert.strictEqual(fixJson('[[[]], [[]'), '[[[]], [[]]]');
|
|
});
|
|
|
|
test('should handle closing bracket after object in array', () => {
|
|
assert.strictEqual(fixJson('[[{}], [{'), '[[{}], [{}]]');
|
|
});
|
|
|
|
test('should handle trailing comma', () => {
|
|
assert.strictEqual(fixJson('[1, '), '[1]');
|
|
});
|
|
|
|
test('should handle closing array', () => {
|
|
assert.strictEqual(fixJson('[[], 123'), '[[], 123]');
|
|
});
|
|
});
|
|
|
|
describe('object', () => {
|
|
test('should handle keys without values', () => {
|
|
assert.strictEqual(fixJson('{"key":'), '{}');
|
|
});
|
|
|
|
test('should handle closing brace after number in object', () => {
|
|
assert.strictEqual(
|
|
fixJson('{"a": {"b": 1}, "c": {"d": 2'),
|
|
'{"a": {"b": 1}, "c": {"d": 2}}',
|
|
);
|
|
});
|
|
|
|
test('should handle closing brace after string in object', () => {
|
|
assert.strictEqual(
|
|
fixJson('{"a": {"b": "1"}, "c": {"d": 2'),
|
|
'{"a": {"b": "1"}, "c": {"d": 2}}',
|
|
);
|
|
});
|
|
|
|
test('should handle closing brace after literal in object', () => {
|
|
assert.strictEqual(
|
|
fixJson('{"a": {"b": false}, "c": {"d": 2'),
|
|
'{"a": {"b": false}, "c": {"d": 2}}',
|
|
);
|
|
});
|
|
|
|
test('should handle closing brace after array in object', () => {
|
|
assert.strictEqual(
|
|
fixJson('{"a": {"b": []}, "c": {"d": 2'),
|
|
'{"a": {"b": []}, "c": {"d": 2}}',
|
|
);
|
|
});
|
|
|
|
test('should handle closing brace after object in object', () => {
|
|
assert.strictEqual(
|
|
fixJson('{"a": {"b": {}}, "c": {"d": 2'),
|
|
'{"a": {"b": {}}, "c": {"d": 2}}',
|
|
);
|
|
});
|
|
|
|
test('should handle partial keys (first key)', () => {
|
|
assert.strictEqual(fixJson('{"ke'), '{}');
|
|
});
|
|
|
|
test('should handle partial keys (second key)', () => {
|
|
assert.strictEqual(fixJson('{"k1": 1, "k2'), '{"k1": 1}');
|
|
});
|
|
|
|
test('should handle partial keys with colon (second key)', () => {
|
|
assert.strictEqual(fixJson('{"k1": 1, "k2":'), '{"k1": 1}');
|
|
});
|
|
|
|
test('should handle trailing whitespaces', () => {
|
|
assert.strictEqual(fixJson('{"key": "value" '), '{"key": "value"}');
|
|
});
|
|
});
|
|
|
|
describe('nesting', () => {
|
|
test('should handle nested arrays with numbers', () => {
|
|
assert.strictEqual(fixJson('[1, [2, 3, ['), '[1, [2, 3, []]]');
|
|
});
|
|
|
|
test('should handle nested arrays with literals', () => {
|
|
assert.strictEqual(fixJson('[false, [true, ['), '[false, [true, []]]');
|
|
});
|
|
|
|
test('should handle nested objects', () => {
|
|
assert.strictEqual(fixJson('{"key": {"subKey":'), '{"key": {}}');
|
|
});
|
|
|
|
test('should handle nested objects with numbers', () => {
|
|
assert.strictEqual(
|
|
fixJson('{"key": 123, "key2": {"subKey":'),
|
|
'{"key": 123, "key2": {}}',
|
|
);
|
|
});
|
|
|
|
test('should handle nested objects with literals', () => {
|
|
assert.strictEqual(
|
|
fixJson('{"key": null, "key2": {"subKey":'),
|
|
'{"key": null, "key2": {}}',
|
|
);
|
|
});
|
|
|
|
test('should handle arrays within objects', () => {
|
|
assert.strictEqual(fixJson('{"key": [1, 2, {'), '{"key": [1, 2, {}]}');
|
|
});
|
|
|
|
test('should handle objects within arrays', () => {
|
|
assert.strictEqual(
|
|
fixJson('[1, 2, {"key": "value",'),
|
|
'[1, 2, {"key": "value"}]',
|
|
);
|
|
});
|
|
|
|
test('should handle nested arrays and objects', () => {
|
|
assert.strictEqual(
|
|
fixJson('{"a": {"b": ["c", {"d": "e",'),
|
|
'{"a": {"b": ["c", {"d": "e"}]}}',
|
|
);
|
|
});
|
|
|
|
test('should handle deeply nested objects', () => {
|
|
assert.strictEqual(
|
|
fixJson('{"a": {"b": {"c": {"d":'),
|
|
'{"a": {"b": {"c": {}}}}',
|
|
);
|
|
});
|
|
|
|
test('should handle potential nested arrays or objects', () => {
|
|
assert.strictEqual(fixJson('{"a": 1, "b": ['), '{"a": 1, "b": []}');
|
|
assert.strictEqual(fixJson('{"a": 1, "b": {'), '{"a": 1, "b": {}}');
|
|
assert.strictEqual(fixJson('{"a": 1, "b": "'), '{"a": 1, "b": ""}');
|
|
});
|
|
});
|
|
|
|
describe('regression', () => {
|
|
test('should handle complex nesting 1', () => {
|
|
assert.strictEqual(
|
|
fixJson(
|
|
[
|
|
'{',
|
|
' "a": [',
|
|
' {',
|
|
' "a1": "v1",',
|
|
' "a2": "v2",',
|
|
` "a3": "v3"`,
|
|
' }',
|
|
' ],',
|
|
' "b": [',
|
|
' {',
|
|
' "b1": "n',
|
|
].join('\n'),
|
|
),
|
|
[
|
|
'{',
|
|
' "a": [',
|
|
' {',
|
|
' "a1": "v1",',
|
|
' "a2": "v2",',
|
|
` "a3": "v3"`,
|
|
' }',
|
|
' ],',
|
|
' "b": [',
|
|
' {',
|
|
' "b1": "n"}]}',
|
|
].join('\n'),
|
|
);
|
|
});
|
|
});
|