Sync defaultMessage from lokalise * Enhance translation sync functionality and tests - Added logging for found component files during sync. - Introduced tests for handling complex components with replacements. - Updated regex in syncIntlFormatMessage to support optional second arguments. - Removed unused test files. * feat(syncDefaultMessage): add script for syncing default message with lokalise * feat(syncDefaultMessage): add script for syncing default message with lokalise Approved-by: Matilda Landström
138 lines
4.5 KiB
TypeScript
138 lines
4.5 KiB
TypeScript
import { vi, it, expect, beforeEach, afterEach, describe } from "vitest";
|
|
|
|
describe("syncFile", () => {
|
|
beforeEach(() => {
|
|
vi.resetModules();
|
|
vi.mock("fs", () => {
|
|
const existsMock = vi.fn();
|
|
const readMock = vi.fn();
|
|
const writeMock = vi.fn();
|
|
return {
|
|
existsSync: existsMock,
|
|
readFileSync: readMock,
|
|
writeFileSync: writeMock,
|
|
default: {
|
|
existsSync: existsMock,
|
|
readFileSync: readMock,
|
|
writeFileSync: writeMock,
|
|
},
|
|
};
|
|
});
|
|
});
|
|
|
|
afterEach(() => {
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
it("throws if file does not exist", async () => {
|
|
const fsMock = (await import("fs")) as any;
|
|
fsMock.existsSync.mockReturnValue(false);
|
|
|
|
const { syncFile } = await import("./syncFile");
|
|
|
|
expect(() =>
|
|
syncFile({ path: "missing.ts", translations: {} })
|
|
).toThrow("File not found: missing.ts");
|
|
|
|
expect(fsMock.readFileSync).not.toHaveBeenCalled();
|
|
expect(fsMock.writeFileSync).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("reads file, calls syncIntlFormatMessage, writes updated content and returns it", async () => {
|
|
const fsMock = (await import("fs")) as any;
|
|
|
|
fsMock.existsSync.mockReturnValue(true);
|
|
fsMock.readFileSync.mockReturnValue(
|
|
createMockComponent("myKey", "old message")
|
|
);
|
|
|
|
const { syncFile } = await import("./syncFile");
|
|
|
|
const { fileContent: result } = syncFile({
|
|
path: "file.ts",
|
|
translations: { myKey: "new message" },
|
|
});
|
|
|
|
expect(fsMock.readFileSync).toHaveBeenCalledWith("file.ts", "utf-8");
|
|
expect(fsMock.writeFileSync).toHaveBeenCalled();
|
|
expect(result).toEqual(createMockComponent("myKey", "new message"));
|
|
});
|
|
|
|
it("reads file, calls syncIntlFormatMessage, ignores content if there are no matching keys, writes updated content and returns it", async () => {
|
|
const fsMock = (await import("fs")) as any;
|
|
|
|
fsMock.existsSync.mockReturnValue(true);
|
|
fsMock.readFileSync.mockReturnValue(
|
|
createMockComponent("myKey", "old message")
|
|
);
|
|
|
|
const { syncFile } = await import("./syncFile");
|
|
|
|
const { fileContent: result } = syncFile({
|
|
path: "file.ts",
|
|
translations: { someOtherKey: "not present" },
|
|
});
|
|
|
|
expect(fsMock.readFileSync).toHaveBeenCalledWith("file.ts", "utf-8");
|
|
// expect(fsMock.writeFileSync).toHaveBeenCalled();
|
|
expect(result).toEqual(createMockComponent("myKey", "old message"));
|
|
});
|
|
|
|
it("updates complex components with replacements", async () => {
|
|
const fsMock = (await import("fs")) as any;
|
|
|
|
fsMock.existsSync.mockReturnValue(true);
|
|
fsMock.readFileSync.mockReturnValue(
|
|
createComplexMockComponent(
|
|
"complexKey",
|
|
"Yes, I accept the general <termsAndConditionsLink>Booking & Cancellation Terms</termsAndConditionsLink>, and understand that Scandic will process my personal data in accordance with <privacyPolicyLink>Scandic's Privacy policy</privacyPolicyLink>."
|
|
)
|
|
);
|
|
|
|
const { syncFile } = await import("./syncFile");
|
|
|
|
const { fileContent: result } = syncFile({
|
|
path: "file.ts",
|
|
translations: { complexKey: "replace this text" },
|
|
});
|
|
|
|
expect(fsMock.readFileSync).toHaveBeenCalledWith("file.ts", "utf-8");
|
|
// expect(fsMock.writeFileSync).toHaveBeenCalled();
|
|
expect(result).toContain("replace this text");
|
|
});
|
|
});
|
|
|
|
function createMockComponent(translationId: string, defaultMessage: string) {
|
|
return `export function TestComponent() {
|
|
const { intl } = useIntl();
|
|
|
|
const message = intl.formatMessage({
|
|
id: "${translationId}",
|
|
defaultMessage: "${defaultMessage}",
|
|
});
|
|
return <div>{message}</div>;
|
|
}`;
|
|
}
|
|
|
|
function createComplexMockComponent(
|
|
translationId: string,
|
|
defaultMessage: string
|
|
) {
|
|
return `export function TestComponent() {
|
|
const intl = useIntl();
|
|
return (
|
|
<div>
|
|
{intl.formatMessage(
|
|
{
|
|
id: "${translationId}",
|
|
defaultMessage: "${defaultMessage}",
|
|
},
|
|
{
|
|
replacement: (str) => <a href="#">{str}</a>,
|
|
}
|
|
)}
|
|
</div>
|
|
);
|
|
}`;
|
|
}
|