lokalise-file-exchange
Version:
Exchange translation files with Lokalise TMS
217 lines (194 loc) • 6.61 kB
text/typescript
import path from "node:path";
import mock from "mock-fs";
import { FakeLokaliseUpload } from "../../fixtures/fake_classes/FakeLokaliseUpload.js";
import { afterEach, beforeEach, describe, expect, it } from "../../setup.js";
describe("LokaliseUpload: collectFiles()", () => {
const projectId = "803826145ba90b42d5d860.46800099";
const apiKey = process.env.API_KEY as string;
let lokaliseUpload: FakeLokaliseUpload;
beforeEach(() => {
lokaliseUpload = new FakeLokaliseUpload({ apiKey }, { projectId });
mock({
"./locales": {
"en.json": '{"key": "value"}',
"fr.json": '{"clé": "valeur"}',
"backup.txt": "Not a JSON file",
subdir: {
"es.json": '{"clave": "valor"}',
nested: {
"de.json": '{"schlüssel": "wert"}',
"ignored.js": "// Some JS code",
},
},
},
"./node_modules": {
"module.js": "// This should be excluded",
},
"./dist": {
"build.json": '{"build": true}',
},
});
});
afterEach(() => {
mock.restore();
});
const fullPath = (p: string) => path.resolve(p);
describe("General Behavior", () => {
it("should collect all JSON files recursively by default", async () => {
const files = await lokaliseUpload.collectFiles();
const expectedFiles = [
fullPath("./locales/en.json"),
fullPath("./locales/fr.json"),
fullPath("./locales/backup.txt"),
fullPath("./locales/subdir/es.json"),
fullPath("./locales/subdir/nested/de.json"),
fullPath("./locales/subdir/nested/ignored.js"),
];
expect(files).toEqual(expect.arrayContaining(expectedFiles));
expect(files).toHaveLength(expectedFiles.length);
});
it("should handle non-recursive mode", async () => {
const files = await lokaliseUpload.collectFiles({
recursive: false,
});
const expectedFiles = [
fullPath("./locales/en.json"),
fullPath("./locales/fr.json"),
fullPath("./locales/backup.txt"),
];
expect(files).toEqual(expect.arrayContaining(expectedFiles));
expect(files).toHaveLength(expectedFiles.length);
});
it("should return an empty array when inputDirs is empty", async () => {
const files = await lokaliseUpload.collectFiles({
inputDirs: [],
});
expect(files).toEqual([]);
expect(files).toHaveLength(0);
});
});
describe("Filtering", () => {
it("should filter files by extensions", async () => {
const files = await lokaliseUpload.collectFiles({
extensions: [".json"],
});
const expectedFiles = [
fullPath("./locales/en.json"),
fullPath("./locales/fr.json"),
fullPath("./locales/subdir/es.json"),
fullPath("./locales/subdir/nested/de.json"),
];
expect(files).toEqual(expect.arrayContaining(expectedFiles));
expect(files).toHaveLength(expectedFiles.length);
});
it("should handle mixed file extensions correctly", async () => {
const files = await lokaliseUpload.collectFiles({
extensions: [".json", ".js"],
});
const expectedFiles = [
fullPath("./locales/en.json"),
fullPath("./locales/fr.json"),
fullPath("./locales/subdir/es.json"),
fullPath("./locales/subdir/nested/de.json"),
fullPath("./locales/subdir/nested/ignored.js"),
];
expect(files).toEqual(expect.arrayContaining(expectedFiles));
expect(files).toHaveLength(expectedFiles.length);
});
it("should filter files by fileNamePattern", async () => {
const files = await lokaliseUpload.collectFiles({
fileNamePattern: "^en.*",
});
const expectedFiles = [fullPath("./locales/en.json")];
expect(files).toEqual(expect.arrayContaining(expectedFiles));
expect(files).toHaveLength(expectedFiles.length);
});
it("should filter files by both fileNamePattern and extensions", async () => {
const files = await lokaliseUpload.collectFiles({
extensions: [".json"],
fileNamePattern: /^en.*/,
});
const expectedFiles = [fullPath("./locales/en.json")];
expect(files).toEqual(expect.arrayContaining(expectedFiles));
expect(files).toHaveLength(expectedFiles.length);
});
});
describe("Exclusions", () => {
it("should respect the excludePatterns option", async () => {
const files = await lokaliseUpload.collectFiles({
excludePatterns: ["nested", "backup"],
});
const expectedFiles = [
fullPath("./locales/en.json"),
fullPath("./locales/fr.json"),
fullPath("./locales/subdir/es.json"),
];
expect(files).toEqual(expect.arrayContaining(expectedFiles));
expect(files).toHaveLength(expectedFiles.length);
});
it("should exclude directories and apply file filters simultaneously", async () => {
const files = await lokaliseUpload.collectFiles({
excludePatterns: [/locales\\subdir/, /locales\/subdir/, /en\.json$/i],
extensions: [".json"],
});
const expectedFiles = [fullPath("./locales/fr.json")];
expect(files).toEqual(expect.arrayContaining(expectedFiles));
expect(files).toHaveLength(expectedFiles.length);
});
});
describe("Edge Cases", () => {
it("should throw an error for invalid fileNamePattern", async () => {
await expect(
lokaliseUpload.collectFiles({
fileNamePattern: "[invalid(",
}),
).rejects.toThrow("Invalid fileNamePattern");
});
it("should throw an error for invalid excludePatterns", async () => {
await expect(
lokaliseUpload.collectFiles({
excludePatterns: ["[invalid("],
}),
).rejects.toThrow("Invalid excludePatterns: SyntaxError");
});
it("should handle invalid or inaccessible directories gracefully", async () => {
mock({
"./locales": mock.directory({
mode: 0o000, // No read permissions
}),
});
const files = await lokaliseUpload.collectFiles({
inputDirs: ["./locales"],
});
expect(files).toEqual([]);
expect(files).toHaveLength(0);
});
it("should return an empty array when no files match filters", async () => {
const files = await lokaliseUpload.collectFiles({
extensions: [".txt"],
fileNamePattern: "^nonexistent.*",
});
expect(files).toEqual([]);
expect(files).toHaveLength(0);
});
it("should process multiple input directories", async () => {
mock({
"./locales": {
"en.json": '{"key": "value"}',
},
"./additional_locales": {
"fr.json": '{"clé": "valeur"}',
},
});
const files = await lokaliseUpload.collectFiles({
inputDirs: ["./locales", "./additional_locales"],
});
const expectedFiles = [
fullPath("./locales/en.json"),
fullPath("./additional_locales/fr.json"),
];
expect(files).toEqual(expect.arrayContaining(expectedFiles));
expect(files).toHaveLength(expectedFiles.length);
});
});
});