Skip to content
This repository was archived by the owner on Feb 2, 2021. It is now read-only.

Commit 8bb173c

Browse files
Merge pull request #805 from telerik/milanov/keep-indentation-in-json-files
Keep the current indentation of json files
2 parents a3bfb06 + d96a91e commit 8bb173c

File tree

4 files changed

+116
-2
lines changed

4 files changed

+116
-2
lines changed

file-system.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import * as shelljs from "shelljs";
99

1010
@injector.register("fs")
1111
export class FileSystem implements IFileSystem {
12+
private static DEFAULT_INDENTATION_CHARACTER = "\t";
13+
private static JSON_OBJECT_REGEXP = new RegExp(`{\\r*\\n*(\\W*)"`, "m");
14+
1215
constructor(private $injector: IInjector) { }
1316

1417
//TODO: try 'archiver' module for zipping
@@ -269,7 +272,11 @@ export class FileSystem implements IFileSystem {
269272
return future;
270273
}
271274

272-
public writeJson(filename: string, data: any, space: string = "\t", encoding?: string): IFuture<void> {
275+
public writeJson(filename: string, data: any, space?: string, encoding?: string): IFuture<void> {
276+
if (!space) {
277+
space = this.getIndentationCharacter(filename).wait();
278+
}
279+
273280
return this.writeFile(filename, JSON.stringify(data, null, space), encoding);
274281
}
275282

@@ -523,4 +530,23 @@ export class FileSystem implements IFileSystem {
523530
}
524531
}).future<void>()();
525532
}
533+
534+
private getIndentationCharacter(filePath: string): IFuture<string> {
535+
return ((): string => {
536+
if (!this.exists(filePath).wait()) {
537+
return FileSystem.DEFAULT_INDENTATION_CHARACTER;
538+
}
539+
540+
let fileContent = this.readText(filePath).wait().trim();
541+
let matches = fileContent.match(FileSystem.JSON_OBJECT_REGEXP);
542+
543+
if (!matches || !matches[1]) {
544+
return FileSystem.DEFAULT_INDENTATION_CHARACTER;
545+
}
546+
547+
let indentation = matches[1];
548+
549+
return indentation[0] === " " ? indentation : FileSystem.DEFAULT_INDENTATION_CHARACTER;
550+
}).future<string>()();
551+
}
526552
}

services/user-settings-service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export class UserSettingsServiceBase implements IUserSettingsService {
4141
this.userSettingsData[propertyName] = data[propertyName];
4242
});
4343

44-
this.$fs.writeJson(this.userSettingsFilePath, this.userSettingsData, "\t").wait();
44+
this.$fs.writeJson(this.userSettingsFilePath, this.userSettingsData).wait();
4545
}).future<void>()();
4646
}
4747

test/unit-tests/file-system.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,57 @@ function isOsCaseSensitive(testInjector: IInjector): boolean {
1818
};
1919
temp.track();
2020

21+
function createWriteJsonTestCases(): { exists: boolean, text: string, testCondition: string, expectedIndentation: string }[] {
22+
return [
23+
{
24+
exists: true,
25+
text: `{\n\t"a" : 5 }`,
26+
testCondition: "when the indentation is tab",
27+
expectedIndentation: "\t"
28+
}, {
29+
exists: true,
30+
text: `{\n "a" : 5 }`,
31+
testCondition: "when the indentation is space",
32+
expectedIndentation: " "
33+
}, {
34+
exists: true,
35+
text: `{\n "a" : 5 }`,
36+
testCondition: "when the indentation is two spaces",
37+
expectedIndentation: " "
38+
}, {
39+
exists: false,
40+
text: `{\n "a" : 5 }`,
41+
testCondition: "when the file does not exist",
42+
expectedIndentation: "\t"
43+
}, {
44+
exists: true,
45+
text: `"just-string"`,
46+
testCondition: "when the the content is string",
47+
expectedIndentation: "\t"
48+
}, {
49+
exists: true,
50+
text: `{ "a" : 5 }`,
51+
testCondition: "when the content does not have new line after the {",
52+
expectedIndentation: " "
53+
}, {
54+
exists: true,
55+
text: `{"a" : 5 }`,
56+
testCondition: "when the content is not correctly formatted",
57+
expectedIndentation: "\t"
58+
}, {
59+
exists: true,
60+
text: `{\r\n "a" : 5 }`,
61+
testCondition: "when the new line is in Windows format",
62+
expectedIndentation: " "
63+
}, {
64+
exists: true,
65+
text: `{\r\n\t"a" : 5 }`,
66+
testCondition: "when the new line is in Windows format",
67+
expectedIndentation: "\t"
68+
}
69+
];
70+
}
71+
2172
function createTestInjector(): IInjector {
2273
let testInjector = new Yok();
2374

@@ -226,4 +277,37 @@ describe("FileSystem", () => {
226277
assert.deepEqual(emptyDirectories, _.reverse(removedDirectories));
227278
});
228279
});
280+
281+
describe("writeJson", () => {
282+
let testCases = createWriteJsonTestCases(),
283+
testInjector: IInjector,
284+
fs: IFileSystem;
285+
286+
beforeEach(() => {
287+
testInjector = createTestInjector();
288+
289+
fs = testInjector.resolve("fs");
290+
});
291+
292+
_.each(testCases, (testCase) => {
293+
it(`should use the correct indentation ${testCase.testCondition}.`, () => {
294+
fs.readText = () => Future.fromResult(testCase.text);
295+
fs.exists = () => Future.fromResult(testCase.exists);
296+
fs.writeFile = () => Future.fromResult();
297+
298+
let actualIndentation: string;
299+
let originalJsonStringify = JSON.stringify;
300+
301+
(<any>JSON).stringify = (value: any, replacer: any[], space: string | number) => {
302+
actualIndentation = <string>space;
303+
};
304+
305+
fs.writeJson("", testCase.text).wait();
306+
307+
JSON.stringify = originalJsonStringify;
308+
309+
assert.deepEqual(actualIndentation, testCase.expectedIndentation);
310+
});
311+
});
312+
});
229313
});

test/unit-tests/mobile/android-device-file-system.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ describe("Android device file system tests", () => {
146146
isDirectory: () => false,
147147
isFile: () => true
148148
});
149+
fs.readText = () => Future.fromResult("");
149150

150151
let androidDeviceFileSystem = createAndroidDeviceFileSystem(injector);
151152
androidDeviceFileSystem.transferFile = (localPath: string, devicePath: string) => {
@@ -173,6 +174,7 @@ describe("Android device file system tests", () => {
173174
isDirectory: () => false,
174175
isFile: () => true
175176
});
177+
fs.readText = () => Future.fromResult("");
176178

177179
let androidDeviceFileSystem = createAndroidDeviceFileSystem(injector);
178180
let transferedFilesOnDevice: string[] = [];
@@ -206,6 +208,7 @@ describe("Android device file system tests", () => {
206208
isDirectory: () => false,
207209
isFile: () => true
208210
});
211+
fs.readText = () => Future.fromResult("");
209212

210213
let androidDeviceFileSystem = createAndroidDeviceFileSystem(injector);
211214
androidDeviceFileSystem.transferFile = (localPath: string, devicePath: string) => {
@@ -233,6 +236,7 @@ describe("Android device file system tests", () => {
233236
isDirectory: () => false,
234237
isFile: () => true
235238
});
239+
fs.readText = () => Future.fromResult("");
236240

237241
let androidDeviceFileSystem = createAndroidDeviceFileSystem(injector);
238242
androidDeviceFileSystem.transferFile = (localPath: string, devicePath: string) => {

0 commit comments

Comments
 (0)