Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/base/test/common/jsonFormatter.test.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
import assert from 'assert';
6
import * as Formatter from '../../common/jsonFormatter.js';
7
import { ensureNoDisposablesAreLeakedInTestSuite } from './utils.js';
8
9
suite('JSON - formatter', () => {
10
11
ensureNoDisposablesAreLeakedInTestSuite();
12
13
function format(content: string, expected: string, insertSpaces = true) {
14
let range: Formatter.Range | undefined = undefined;
15
const rangeStart = content.indexOf('|');
16
const rangeEnd = content.lastIndexOf('|');
17
if (rangeStart !== -1 && rangeEnd !== -1) {
18
content = content.substring(0, rangeStart) + content.substring(rangeStart + 1, rangeEnd) + content.substring(rangeEnd + 1);
19
range = { offset: rangeStart, length: rangeEnd - rangeStart };
20
}
21
22
const edits = Formatter.format(content, range, { tabSize: 2, insertSpaces: insertSpaces, eol: '\n' });
23
24
let lastEditOffset = content.length;
25
for (let i = edits.length - 1; i >= 0; i--) {
26
const edit = edits[i];
27
assert(edit.offset >= 0 && edit.length >= 0 && edit.offset + edit.length <= content.length);
28
assert(typeof edit.content === 'string');
29
assert(lastEditOffset >= edit.offset + edit.length); // make sure all edits are ordered
30
lastEditOffset = edit.offset;
31
content = content.substring(0, edit.offset) + edit.content + content.substring(edit.offset + edit.length);
32
}
33
34
assert.strictEqual(content, expected);
35
}
36
37
test('object - single property', () => {
38
const content = [
39
'{"x" : 1}'
40
].join('\n');
41
42
const expected = [
43
'{',
44
' "x": 1',
45
'}'
46
].join('\n');
47
48
format(content, expected);
49
});
50
test('object - multiple properties', () => {
51
const content = [
52
'{"x" : 1, "y" : "foo", "z" : true}'
53
].join('\n');
54
55
const expected = [
56
'{',
57
' "x": 1,',
58
' "y": "foo",',
59
' "z": true',
60
'}'
61
].join('\n');
62
63
format(content, expected);
64
});
65
test('object - no properties ', () => {
66
const content = [
67
'{"x" : { }, "y" : {}}'
68
].join('\n');
69
70
const expected = [
71
'{',
72
' "x": {},',
73
' "y": {}',
74
'}'
75
].join('\n');
76
77
format(content, expected);
78
});
79
test('object - nesting', () => {
80
const content = [
81
'{"x" : { "y" : { "z" : { }}, "a": true}}'
82
].join('\n');
83
84
const expected = [
85
'{',
86
' "x": {',
87
' "y": {',
88
' "z": {}',
89
' },',
90
' "a": true',
91
' }',
92
'}'
93
].join('\n');
94
95
format(content, expected);
96
});
97
98
test('array - single items', () => {
99
const content = [
100
'["[]"]'
101
].join('\n');
102
103
const expected = [
104
'[',
105
' "[]"',
106
']'
107
].join('\n');
108
109
format(content, expected);
110
});
111
112
test('array - multiple items', () => {
113
const content = [
114
'[true,null,1.2]'
115
].join('\n');
116
117
const expected = [
118
'[',
119
' true,',
120
' null,',
121
' 1.2',
122
']'
123
].join('\n');
124
125
format(content, expected);
126
});
127
128
test('array - no items', () => {
129
const content = [
130
'[ ]'
131
].join('\n');
132
133
const expected = [
134
'[]'
135
].join('\n');
136
137
format(content, expected);
138
});
139
140
test('array - nesting', () => {
141
const content = [
142
'[ [], [ [ {} ], "a" ] ]'
143
].join('\n');
144
145
const expected = [
146
'[',
147
' [],',
148
' [',
149
' [',
150
' {}',
151
' ],',
152
' "a"',
153
' ]',
154
']',
155
].join('\n');
156
157
format(content, expected);
158
});
159
160
test('syntax errors', () => {
161
const content = [
162
'[ null 1.2 ]'
163
].join('\n');
164
165
const expected = [
166
'[',
167
' null 1.2',
168
']',
169
].join('\n');
170
171
format(content, expected);
172
});
173
174
test('empty lines', () => {
175
const content = [
176
'{',
177
'"a": true,',
178
'',
179
'"b": true',
180
'}',
181
].join('\n');
182
183
const expected = [
184
'{',
185
'\t"a": true,',
186
'\t"b": true',
187
'}',
188
].join('\n');
189
190
format(content, expected, false);
191
});
192
test('single line comment', () => {
193
const content = [
194
'[ ',
195
'//comment',
196
'"foo", "bar"',
197
'] '
198
].join('\n');
199
200
const expected = [
201
'[',
202
' //comment',
203
' "foo",',
204
' "bar"',
205
']',
206
].join('\n');
207
208
format(content, expected);
209
});
210
test('block line comment', () => {
211
const content = [
212
'[{',
213
' /*comment*/ ',
214
'"foo" : true',
215
'}] '
216
].join('\n');
217
218
const expected = [
219
'[',
220
' {',
221
' /*comment*/',
222
' "foo": true',
223
' }',
224
']',
225
].join('\n');
226
227
format(content, expected);
228
});
229
test('single line comment on same line', () => {
230
const content = [
231
' { ',
232
' "a": {}// comment ',
233
' } '
234
].join('\n');
235
236
const expected = [
237
'{',
238
' "a": {} // comment ',
239
'}',
240
].join('\n');
241
242
format(content, expected);
243
});
244
test('single line comment on same line 2', () => {
245
const content = [
246
'{ //comment',
247
'}'
248
].join('\n');
249
250
const expected = [
251
'{ //comment',
252
'}'
253
].join('\n');
254
255
format(content, expected);
256
});
257
test('block comment on same line', () => {
258
const content = [
259
'{ "a": {}, /*comment*/ ',
260
' /*comment*/ "b": {}, ',
261
' "c": {/*comment*/} } ',
262
].join('\n');
263
264
const expected = [
265
'{',
266
' "a": {}, /*comment*/',
267
' /*comment*/ "b": {},',
268
' "c": { /*comment*/}',
269
'}',
270
].join('\n');
271
272
format(content, expected);
273
});
274
275
test('block comment on same line advanced', () => {
276
const content = [
277
' { "d": [',
278
' null',
279
' ] /*comment*/',
280
' ,"e": /*comment*/ [null] }',
281
].join('\n');
282
283
const expected = [
284
'{',
285
' "d": [',
286
' null',
287
' ] /*comment*/,',
288
' "e": /*comment*/ [',
289
' null',
290
' ]',
291
'}',
292
].join('\n');
293
294
format(content, expected);
295
});
296
297
test('multiple block comments on same line', () => {
298
const content = [
299
'{ "a": {} /*comment*/, /*comment*/ ',
300
' /*comment*/ "b": {} /*comment*/ } '
301
].join('\n');
302
303
const expected = [
304
'{',
305
' "a": {} /*comment*/, /*comment*/',
306
' /*comment*/ "b": {} /*comment*/',
307
'}',
308
].join('\n');
309
310
format(content, expected);
311
});
312
test('multiple mixed comments on same line', () => {
313
const content = [
314
'[ /*comment*/ /*comment*/ // comment ',
315
']'
316
].join('\n');
317
318
const expected = [
319
'[ /*comment*/ /*comment*/ // comment ',
320
']'
321
].join('\n');
322
323
format(content, expected);
324
});
325
326
test('range', () => {
327
const content = [
328
'{ "a": {},',
329
'|"b": [null, null]|',
330
'} '
331
].join('\n');
332
333
const expected = [
334
'{ "a": {},',
335
'"b": [',
336
' null,',
337
' null',
338
']',
339
'} ',
340
].join('\n');
341
342
format(content, expected);
343
});
344
345
test('range with existing indent', () => {
346
const content = [
347
'{ "a": {},',
348
' |"b": [null],',
349
'"c": {}',
350
'}|'
351
].join('\n');
352
353
const expected = [
354
'{ "a": {},',
355
' "b": [',
356
' null',
357
' ],',
358
' "c": {}',
359
'}',
360
].join('\n');
361
362
format(content, expected);
363
});
364
365
test('range with existing indent - tabs', () => {
366
const content = [
367
'{ "a": {},',
368
'| "b": [null], ',
369
'"c": {}',
370
'} | '
371
].join('\n');
372
373
const expected = [
374
'{ "a": {},',
375
'\t"b": [',
376
'\t\tnull',
377
'\t],',
378
'\t"c": {}',
379
'}',
380
].join('\n');
381
382
format(content, expected, false);
383
});
384
385
386
test('block comment none-line breaking symbols', () => {
387
const content = [
388
'{ "a": [ 1',
389
'/* comment */',
390
', 2',
391
'/* comment */',
392
']',
393
'/* comment */',
394
',',
395
' "b": true',
396
'/* comment */',
397
'}'
398
].join('\n');
399
400
const expected = [
401
'{',
402
' "a": [',
403
' 1',
404
' /* comment */',
405
' ,',
406
' 2',
407
' /* comment */',
408
' ]',
409
' /* comment */',
410
' ,',
411
' "b": true',
412
' /* comment */',
413
'}',
414
].join('\n');
415
416
format(content, expected);
417
});
418
test('line comment after none-line breaking symbols', () => {
419
const content = [
420
'{ "a":',
421
'// comment',
422
'null,',
423
' "b"',
424
'// comment',
425
': null',
426
'// comment',
427
'}'
428
].join('\n');
429
430
const expected = [
431
'{',
432
' "a":',
433
' // comment',
434
' null,',
435
' "b"',
436
' // comment',
437
' : null',
438
' // comment',
439
'}',
440
].join('\n');
441
442
format(content, expected);
443
});
444
445
test('toFormattedString', () => {
446
const obj = {
447
a: { b: 1, d: ['hello'] }
448
};
449
450
451
const getExpected = (tab: string, eol: string) => {
452
return [
453
`{`,
454
`${tab}"a": {`,
455
`${tab}${tab}"b": 1,`,
456
`${tab}${tab}"d": [`,
457
`${tab}${tab}${tab}"hello"`,
458
`${tab}${tab}]`,
459
`${tab}}`,
460
'}'
461
].join(eol);
462
};
463
464
let actual = Formatter.toFormattedString(obj, { insertSpaces: true, tabSize: 2, eol: '\n' });
465
assert.strictEqual(actual, getExpected(' ', '\n'));
466
467
actual = Formatter.toFormattedString(obj, { insertSpaces: true, tabSize: 2, eol: '\r\n' });
468
assert.strictEqual(actual, getExpected(' ', '\r\n'));
469
470
actual = Formatter.toFormattedString(obj, { insertSpaces: false, eol: '\r\n' });
471
assert.strictEqual(actual, getExpected('\t', '\r\n'));
472
});
473
});
474
475