Path: blob/main/src/vs/base/test/common/jsonFormatter.test.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/4import assert from 'assert';5import * as Formatter from '../../common/jsonFormatter.js';6import { ensureNoDisposablesAreLeakedInTestSuite } from './utils.js';78suite('JSON - formatter', () => {910ensureNoDisposablesAreLeakedInTestSuite();1112function format(content: string, expected: string, insertSpaces = true) {13let range: Formatter.Range | undefined = undefined;14const rangeStart = content.indexOf('|');15const rangeEnd = content.lastIndexOf('|');16if (rangeStart !== -1 && rangeEnd !== -1) {17content = content.substring(0, rangeStart) + content.substring(rangeStart + 1, rangeEnd) + content.substring(rangeEnd + 1);18range = { offset: rangeStart, length: rangeEnd - rangeStart };19}2021const edits = Formatter.format(content, range, { tabSize: 2, insertSpaces: insertSpaces, eol: '\n' });2223let lastEditOffset = content.length;24for (let i = edits.length - 1; i >= 0; i--) {25const edit = edits[i];26assert(edit.offset >= 0 && edit.length >= 0 && edit.offset + edit.length <= content.length);27assert(typeof edit.content === 'string');28assert(lastEditOffset >= edit.offset + edit.length); // make sure all edits are ordered29lastEditOffset = edit.offset;30content = content.substring(0, edit.offset) + edit.content + content.substring(edit.offset + edit.length);31}3233assert.strictEqual(content, expected);34}3536test('object - single property', () => {37const content = [38'{"x" : 1}'39].join('\n');4041const expected = [42'{',43' "x": 1',44'}'45].join('\n');4647format(content, expected);48});49test('object - multiple properties', () => {50const content = [51'{"x" : 1, "y" : "foo", "z" : true}'52].join('\n');5354const expected = [55'{',56' "x": 1,',57' "y": "foo",',58' "z": true',59'}'60].join('\n');6162format(content, expected);63});64test('object - no properties ', () => {65const content = [66'{"x" : { }, "y" : {}}'67].join('\n');6869const expected = [70'{',71' "x": {},',72' "y": {}',73'}'74].join('\n');7576format(content, expected);77});78test('object - nesting', () => {79const content = [80'{"x" : { "y" : { "z" : { }}, "a": true}}'81].join('\n');8283const expected = [84'{',85' "x": {',86' "y": {',87' "z": {}',88' },',89' "a": true',90' }',91'}'92].join('\n');9394format(content, expected);95});9697test('array - single items', () => {98const content = [99'["[]"]'100].join('\n');101102const expected = [103'[',104' "[]"',105']'106].join('\n');107108format(content, expected);109});110111test('array - multiple items', () => {112const content = [113'[true,null,1.2]'114].join('\n');115116const expected = [117'[',118' true,',119' null,',120' 1.2',121']'122].join('\n');123124format(content, expected);125});126127test('array - no items', () => {128const content = [129'[ ]'130].join('\n');131132const expected = [133'[]'134].join('\n');135136format(content, expected);137});138139test('array - nesting', () => {140const content = [141'[ [], [ [ {} ], "a" ] ]'142].join('\n');143144const expected = [145'[',146' [],',147' [',148' [',149' {}',150' ],',151' "a"',152' ]',153']',154].join('\n');155156format(content, expected);157});158159test('syntax errors', () => {160const content = [161'[ null 1.2 ]'162].join('\n');163164const expected = [165'[',166' null 1.2',167']',168].join('\n');169170format(content, expected);171});172173test('empty lines', () => {174const content = [175'{',176'"a": true,',177'',178'"b": true',179'}',180].join('\n');181182const expected = [183'{',184'\t"a": true,',185'\t"b": true',186'}',187].join('\n');188189format(content, expected, false);190});191test('single line comment', () => {192const content = [193'[ ',194'//comment',195'"foo", "bar"',196'] '197].join('\n');198199const expected = [200'[',201' //comment',202' "foo",',203' "bar"',204']',205].join('\n');206207format(content, expected);208});209test('block line comment', () => {210const content = [211'[{',212' /*comment*/ ',213'"foo" : true',214'}] '215].join('\n');216217const expected = [218'[',219' {',220' /*comment*/',221' "foo": true',222' }',223']',224].join('\n');225226format(content, expected);227});228test('single line comment on same line', () => {229const content = [230' { ',231' "a": {}// comment ',232' } '233].join('\n');234235const expected = [236'{',237' "a": {} // comment ',238'}',239].join('\n');240241format(content, expected);242});243test('single line comment on same line 2', () => {244const content = [245'{ //comment',246'}'247].join('\n');248249const expected = [250'{ //comment',251'}'252].join('\n');253254format(content, expected);255});256test('block comment on same line', () => {257const content = [258'{ "a": {}, /*comment*/ ',259' /*comment*/ "b": {}, ',260' "c": {/*comment*/} } ',261].join('\n');262263const expected = [264'{',265' "a": {}, /*comment*/',266' /*comment*/ "b": {},',267' "c": { /*comment*/}',268'}',269].join('\n');270271format(content, expected);272});273274test('block comment on same line advanced', () => {275const content = [276' { "d": [',277' null',278' ] /*comment*/',279' ,"e": /*comment*/ [null] }',280].join('\n');281282const expected = [283'{',284' "d": [',285' null',286' ] /*comment*/,',287' "e": /*comment*/ [',288' null',289' ]',290'}',291].join('\n');292293format(content, expected);294});295296test('multiple block comments on same line', () => {297const content = [298'{ "a": {} /*comment*/, /*comment*/ ',299' /*comment*/ "b": {} /*comment*/ } '300].join('\n');301302const expected = [303'{',304' "a": {} /*comment*/, /*comment*/',305' /*comment*/ "b": {} /*comment*/',306'}',307].join('\n');308309format(content, expected);310});311test('multiple mixed comments on same line', () => {312const content = [313'[ /*comment*/ /*comment*/ // comment ',314']'315].join('\n');316317const expected = [318'[ /*comment*/ /*comment*/ // comment ',319']'320].join('\n');321322format(content, expected);323});324325test('range', () => {326const content = [327'{ "a": {},',328'|"b": [null, null]|',329'} '330].join('\n');331332const expected = [333'{ "a": {},',334'"b": [',335' null,',336' null',337']',338'} ',339].join('\n');340341format(content, expected);342});343344test('range with existing indent', () => {345const content = [346'{ "a": {},',347' |"b": [null],',348'"c": {}',349'}|'350].join('\n');351352const expected = [353'{ "a": {},',354' "b": [',355' null',356' ],',357' "c": {}',358'}',359].join('\n');360361format(content, expected);362});363364test('range with existing indent - tabs', () => {365const content = [366'{ "a": {},',367'| "b": [null], ',368'"c": {}',369'} | '370].join('\n');371372const expected = [373'{ "a": {},',374'\t"b": [',375'\t\tnull',376'\t],',377'\t"c": {}',378'}',379].join('\n');380381format(content, expected, false);382});383384385test('block comment none-line breaking symbols', () => {386const content = [387'{ "a": [ 1',388'/* comment */',389', 2',390'/* comment */',391']',392'/* comment */',393',',394' "b": true',395'/* comment */',396'}'397].join('\n');398399const expected = [400'{',401' "a": [',402' 1',403' /* comment */',404' ,',405' 2',406' /* comment */',407' ]',408' /* comment */',409' ,',410' "b": true',411' /* comment */',412'}',413].join('\n');414415format(content, expected);416});417test('line comment after none-line breaking symbols', () => {418const content = [419'{ "a":',420'// comment',421'null,',422' "b"',423'// comment',424': null',425'// comment',426'}'427].join('\n');428429const expected = [430'{',431' "a":',432' // comment',433' null,',434' "b"',435' // comment',436' : null',437' // comment',438'}',439].join('\n');440441format(content, expected);442});443444test('toFormattedString', () => {445const obj = {446a: { b: 1, d: ['hello'] }447};448449450const getExpected = (tab: string, eol: string) => {451return [452`{`,453`${tab}"a": {`,454`${tab}${tab}"b": 1,`,455`${tab}${tab}"d": [`,456`${tab}${tab}${tab}"hello"`,457`${tab}${tab}]`,458`${tab}}`,459'}'460].join(eol);461};462463let actual = Formatter.toFormattedString(obj, { insertSpaces: true, tabSize: 2, eol: '\n' });464assert.strictEqual(actual, getExpected(' ', '\n'));465466actual = Formatter.toFormattedString(obj, { insertSpaces: true, tabSize: 2, eol: '\r\n' });467assert.strictEqual(actual, getExpected(' ', '\r\n'));468469actual = Formatter.toFormattedString(obj, { insertSpaces: false, eol: '\r\n' });470assert.strictEqual(actual, getExpected('\t', '\r\n'));471});472});473474475