Skip to content

Commit 7cfe2f2

Browse files
authored
[DIT-11792][DIT-11791][DIT-11960] IOS Strings Dict, Android, ICU format additions (#130)
* Add ios-stringsdict support to BaseFormatter * Refactor IOSStringsFileFormatter into BaseExportFormatter to be shared amongst all export formats. Updated IOSStringsDict to use that class * Add android export format * Add BaseExportFormatter class tests. Updated IOSStringsFormatter tests to no longer include baseExport method tests. Updated all formats to test for correct output file creation * Update base generateQueryParams to take in filters as sole param * Add i18n test cases * Add ios-stringsdict and Android XML formatting tests to pull * Add ICU format. Update HTTP Response types to allow for JSON. Added generics to BaseFormatter to allow for parameter-ized response types * Updated ExportComponentsResponse and TextItemsResponse Zod schema * Made BaseExportFormatter abstract class * Minor: clean * Test fix and HTTP wrapper cleanup * Minor: clean * Add promise.all to fetchTextItemsMap and fetchComponentsMap for performance
1 parent 80b21ee commit 7cfe2f2

24 files changed

+1567
-930
lines changed

lib/src/commands/pull.test.ts

Lines changed: 315 additions & 257 deletions
Large diffs are not rendered by default.

lib/src/formatters/android.test.ts

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import AndroidOutputFile from "./shared/fileTypes/AndroidOutputFile";
2+
import { Output } from "../outputs";
3+
import { ProjectConfigYAML } from "../services/projectConfig";
4+
import { CommandMetaFlags } from "../http/types";
5+
import AndroidXMLFormatter from "./android";
6+
7+
// @ts-ignore
8+
class TestAndroidXMLFormatter extends AndroidXMLFormatter {
9+
public createOutputFilePublic(
10+
fileName: string,
11+
variantId: string,
12+
content: string
13+
) {
14+
// @ts-ignore
15+
return super.createOutputFile(fileName, variantId, content);
16+
}
17+
18+
public getExportFormat() {
19+
// @ts-ignore
20+
return this.exportFormat;
21+
}
22+
23+
public getOutputFiles() {
24+
// @ts-ignore
25+
return this.outputFiles;
26+
}
27+
}
28+
29+
describe("AndroidXMLFormatter", () => {
30+
// @ts-ignore
31+
const createMockOutput = (overrides: Partial<Output> = {}): Output => ({
32+
format: "android",
33+
...overrides,
34+
});
35+
36+
const createMockProjectConfig = (
37+
overrides: Partial<ProjectConfigYAML> = {}
38+
): ProjectConfigYAML => ({
39+
projects: [],
40+
variants: [],
41+
components: {
42+
folders: [],
43+
},
44+
outputs: [
45+
{
46+
format: "android",
47+
} as any,
48+
],
49+
...overrides,
50+
});
51+
52+
const createMockMeta = (): CommandMetaFlags => ({});
53+
54+
it("has export format of android", () => {
55+
const output = createMockOutput({ outDir: "/test/output" });
56+
const projectConfig = createMockProjectConfig();
57+
const formatter = new TestAndroidXMLFormatter(
58+
output,
59+
projectConfig,
60+
createMockMeta()
61+
);
62+
63+
expect(formatter.getExportFormat()).toBe("android");
64+
});
65+
66+
it("creates AndroidOutputFile with correct metadata and content", () => {
67+
const output = createMockOutput({ outDir: "/test/output" });
68+
const projectConfig = createMockProjectConfig();
69+
const formatter = new TestAndroidXMLFormatter(
70+
output,
71+
projectConfig,
72+
createMockMeta()
73+
);
74+
75+
const fileName = "cli-testing-project___spanish";
76+
const variantId = "spanish";
77+
const content = "file-content";
78+
79+
formatter.createOutputFilePublic(fileName, variantId, content);
80+
81+
const files = formatter.getOutputFiles();
82+
const file = files[fileName] as AndroidOutputFile<{
83+
variantId: string;
84+
}>;
85+
86+
expect(file).toBeInstanceOf(AndroidOutputFile);
87+
expect(file.fullPath).toBe(
88+
"/test/output/cli-testing-project___spanish.xml"
89+
);
90+
expect(file.metadata).toEqual({ variantId: "spanish" });
91+
expect(file.content).toBe("file-content");
92+
});
93+
94+
it("defaults variantId metadata to 'base' when variantId is falsy", () => {
95+
const output = createMockOutput({ outDir: "/test/output" });
96+
const projectConfig = createMockProjectConfig();
97+
const formatter = new TestAndroidXMLFormatter(
98+
output,
99+
projectConfig,
100+
createMockMeta()
101+
);
102+
103+
const fileName = "cli-testing-project___base";
104+
const content = "base-content";
105+
106+
formatter.createOutputFilePublic(fileName, "" as any, content);
107+
108+
const files = formatter.getOutputFiles();
109+
const file = files[fileName] as AndroidOutputFile<{
110+
variantId: string;
111+
}>;
112+
113+
expect(file.metadata).toEqual({ variantId: "base" });
114+
expect(file.content).toBe("base-content");
115+
});
116+
});

lib/src/formatters/android.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import BaseExportFormatter from "./shared/baseExport";
2+
import AndroidOutputFile from "./shared/fileTypes/AndroidOutputFile";
3+
import {
4+
ExportComponentsStringResponse,
5+
ExportTextItemsStringResponse,
6+
PullQueryParams,
7+
} from "../http/types";
8+
9+
export default class AndroidXMLFormatter extends BaseExportFormatter<
10+
AndroidOutputFile<{ variantId: string }>,
11+
ExportTextItemsStringResponse,
12+
ExportComponentsStringResponse
13+
> {
14+
protected exportFormat: PullQueryParams["format"] = "android";
15+
16+
protected createOutputFile(
17+
fileName: string,
18+
variantId: string,
19+
content: string
20+
): void {
21+
this.outputFiles[fileName] ??= new AndroidOutputFile({
22+
filename: fileName,
23+
path: this.outDir,
24+
metadata: { variantId: variantId || "base" },
25+
content: content,
26+
});
27+
}
28+
}

lib/src/formatters/icu.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import BaseExportFormatter from "./shared/baseExport";
2+
import ICUOutputFile from "./shared/fileTypes/ICUOutputFile";
3+
import {
4+
ExportComponentsJSONResponse,
5+
ExportTextItemsJSONResponse,
6+
PullQueryParams,
7+
} from "../http/types";
8+
9+
export default class ICUFormatter extends BaseExportFormatter<
10+
ICUOutputFile<{ variantId: string }>,
11+
ExportTextItemsJSONResponse,
12+
ExportComponentsJSONResponse
13+
> {
14+
protected exportFormat: PullQueryParams["format"] = "icu";
15+
16+
protected createOutputFile(
17+
fileName: string,
18+
variantId: string,
19+
content: Record<string, unknown>
20+
): void {
21+
this.outputFiles[fileName] ??= new ICUOutputFile({
22+
filename: fileName,
23+
path: this.outDir,
24+
metadata: { variantId: variantId || "base" },
25+
content: content,
26+
});
27+
}
28+
}

lib/src/formatters/index.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { CommandMetaFlags } from "../http/types";
22
import { Output } from "../outputs";
33
import { ProjectConfigYAML } from "../services/projectConfig";
4+
import AndroidXMLFormatter from "./android";
5+
import ICUFormatter from "./icu";
46
import IOSStringsFormatter from "./iosStrings";
7+
import IOSStringsDictFormatter from "./iosStringsDict";
58
import JSONFormatter from "./json";
69

710
export default function formatOutput(
@@ -10,10 +13,16 @@ export default function formatOutput(
1013
meta: CommandMetaFlags
1114
) {
1215
switch (output.format) {
16+
case "android":
17+
return new AndroidXMLFormatter(output, projectConfig, meta).format();
1318
case "json":
1419
return new JSONFormatter(output, projectConfig, meta).format();
1520
case "ios-strings":
1621
return new IOSStringsFormatter(output, projectConfig, meta).format();
22+
case "ios-stringsdict":
23+
return new IOSStringsDictFormatter(output, projectConfig, meta).format();
24+
case "icu":
25+
return new ICUFormatter(output, projectConfig, meta).format();
1726
default:
1827
throw new Error(`Unsupported output format: ${output}`);
1928
}

0 commit comments

Comments
 (0)