UNPKG

multiconf

Version:

Work with JSON configs

282 lines (260 loc) 7.46 kB
const assert = require('node:assert'); const test = require('node:test'); const JSONCParser = require('../lib/jsonc-parser'); test.describe('JSONCParser', () => { test.describe('Basic JSONC parsing', () => { test.it('should parse simple JSONC with single-line comments', () => { const jsonc = `{ // This is a comment "key": "value", }`; const result = JSONCParser.parse(jsonc); assert.deepStrictEqual(result, { key: 'value' }); }); test.it('should parse JSONC with multi-line comments', () => { const jsonc = `{ /* This is a multi-line comment */ "key": "value", }`; const result = JSONCParser.parse(jsonc); assert.deepStrictEqual(result, { key: 'value' }); }); test.it('should parse JSONC with trailing commas', () => { const jsonc = `{ "key": "value", "array": [1, 2, 3,], "object": { "nested": "value", }, }`; const result = JSONCParser.parse(jsonc); assert.deepStrictEqual(result, { key: 'value', array: [1, 2, 3], object: { nested: 'value' }, }); }); }); test.describe('Complex JSONC cases', () => { test.it('should handle nested comments', () => { const jsonc = `{ /* Outer comment /* Nested comment */ Still in outer comment */ "key": "value", }`; const result = JSONCParser.parse(jsonc); assert.deepStrictEqual(result, { key: 'value' }); }); test.it('should handle comments in strings', () => { const jsonc = `{ "key": "value // not a comment", "key2": "value /* still not a comment */", }`; const result = JSONCParser.parse(jsonc); assert.deepStrictEqual(result, { key: 'value // not a comment', key2: 'value /* still not a comment */', }); }); test.it('should handle escaped quotes in strings', () => { const jsonc = `{ "key": "value with \\"quotes\\"", "key2": "value with \\\\" // comment }`; const result = JSONCParser.parse(jsonc); assert.deepStrictEqual(result, { key: 'value with "quotes"', key2: 'value with \\', }); }); }); test.describe('Edge cases', () => { test.it('should handle empty JSONC', () => { const jsonc = '{}'; const result = JSONCParser.parse(jsonc); assert.deepStrictEqual(result, {}); }); test.it('should handle JSONC with only comments', () => { const jsonc = `{ // Only comments here /* No actual data */ }`; const result = JSONCParser.parse(jsonc); assert.deepStrictEqual(result, {}); }); test.it('should handle JSONC with multiple trailing commas', () => { const jsonc = `{ "array": [1, 2, 3,,,], "object": { "key": "value",,,, },,, }`; const result = JSONCParser.parse(jsonc); assert.deepStrictEqual(result, { array: [1, 2, 3], object: { key: 'value' }, }); }); }); test.describe('Error handling', () => { test.it('should throw TypeError for non-string input', () => { assert.throws( () => JSONCParser.parse(null), { name: 'TypeError', message: 'Input must be a string', }, ); }); test.it('should throw SyntaxError for invalid JSON after comment removal', () => { const jsonc = `{ "key": "value" // Missing closing brace `; assert.throws( () => JSONCParser.parse(jsonc), { name: 'SyntaxError', }, ); }); test.it('should throw SyntaxError for unclosed multi-line comment', () => { const jsonc = `{ "key": "value" /* Unclosed comment }`; assert.throws( () => JSONCParser.parse(jsonc), { name: 'SyntaxError', }, ); }); }); test.describe('Real-world examples', () => { test.it('should parse VS Code settings-like JSONC', () => { const jsonc = `{ // Editor settings "editor.fontSize": 14, "editor.tabSize": 2, "editor.wordWrap": "on", // Git settings "git.enableSmartCommit": true, "git.confirmSync": false, // Terminal settings "terminal.integrated.fontSize": 12, "terminal.integrated.shell.osx": "/bin/zsh", // Extensions "extensions.ignoreRecommendations": false, // Workbench "workbench.colorTheme": "Default Dark+", "workbench.iconTheme": "vs-seti", }`; const result = JSONCParser.parse(jsonc); assert.deepStrictEqual(result, { 'editor.fontSize': 14, 'editor.tabSize': 2, 'editor.wordWrap': 'on', 'git.enableSmartCommit': true, 'git.confirmSync': false, 'terminal.integrated.fontSize': 12, 'terminal.integrated.shell.osx': '/bin/zsh', 'extensions.ignoreRecommendations': false, 'workbench.colorTheme': 'Default Dark+', 'workbench.iconTheme': 'vs-seti', }); }); test.it('should parse complex configuration with nested objects and arrays', () => { const jsonc = `{ // Server configuration "server": { "host": "localhost", "port": 8080, "ssl": { "enabled": true, "cert": "/path/to/cert.pem", "key": "/path/to/key.pem", }, }, // Database configuration "database": { "type": "postgres", "host": "db.example.com", "port": 5432, "credentials": { "username": "admin", "password": "secret", }, "pool": { "min": 2, "max": 10, }, }, // Feature flags "features": [ "auth", "logging", "metrics", "caching", ], // Logging configuration "logging": { "level": "info", "transports": [ { "type": "console", "format": "pretty", }, { "type": "file", "path": "/var/log/app.log", "maxSize": "100m", }, ], }, }`; const result = JSONCParser.parse(jsonc); assert.deepStrictEqual(result, { server: { host: 'localhost', port: 8080, ssl: { enabled: true, cert: '/path/to/cert.pem', key: '/path/to/key.pem', }, }, database: { type: 'postgres', host: 'db.example.com', port: 5432, credentials: { username: 'admin', password: 'secret', }, pool: { min: 2, max: 10, }, }, features: ['auth', 'logging', 'metrics', 'caching'], logging: { level: 'info', transports: [ { type: 'console', format: 'pretty', }, { type: 'file', path: '/var/log/app.log', maxSize: '100m', }, ], }, }); }); }); });