Skip to content

Commit

Permalink
feature(format): support for external formatters
Browse files Browse the repository at this point in the history
  • Loading branch information
timofei-iatsenko committed Mar 14, 2023
1 parent c86a438 commit 39b9a2d
Show file tree
Hide file tree
Showing 17 changed files with 428 additions and 326 deletions.
18 changes: 5 additions & 13 deletions packages/cli/src/api/catalog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,8 @@ import normalize from "normalize-path"

import { LinguiConfigNormalized, OrderBy } from "@lingui/conf"

import {
getFormat,
CatalogFormatOptionsInternal,
CatalogFormatter,
} from "./formats"
import { getFormat } from "./formats"
import { CatalogFormatter } from "@lingui/conf"
import { CliExtractOptions } from "../lingui-extract"
import { CliExtractTemplateOptions } from "../lingui-extract-template"
import { CompiledCatalogNamespace } from "./compile"
Expand Down Expand Up @@ -73,7 +70,7 @@ export class Catalog {
this.path = normalizeRelativePath(path)
this.include = include.map(normalizeRelativePath)
this.exclude = [this.localeDir, ...exclude.map(normalizeRelativePath)]
this.format = getFormat(config.format)
this.format = getFormat(config.format, config.formatOptions)
this.templateFile = templatePath || getTemplatePath(this.format, this.path)
}

Expand Down Expand Up @@ -182,9 +179,8 @@ export class Catalog {
replacePlaceholders(this.path, { locale }) + this.format.catalogExtension

const created = !fs.existsSync(filename)
const options = { ...this.config.formatOptions, locale }

this.format.write(filename, messages, options)
this.format.write(filename, messages, { locale })
return [created, filename]
}

Expand All @@ -194,11 +190,7 @@ export class Catalog {

writeTemplate(messages: CatalogType) {
const filename = this.templateFile
const options: CatalogFormatOptionsInternal = {
...this.config.formatOptions,
locale: undefined,
}
this.format.write(filename, messages, options)
this.format.write(filename, messages, { locale: undefined })
}

writeCompiled(
Expand Down
183 changes: 104 additions & 79 deletions packages/cli/src/api/catalog/getCatalogs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,19 @@ describe("getCatalogs", () => {
},
],
})
expect(getCatalogs(config)).toEqual([
new Catalog(
{
name: null,
path: "src/locales/{locale}",
include: ["src/"],
exclude: [],
},
config
),
])
expect(cleanCatalog(getCatalogs(config)[0])).toEqual(
cleanCatalog(
new Catalog(
{
name: null,
path: "src/locales/{locale}",
include: ["src/"],
exclude: [],
},
config
)
)
)
})

it("should have catalog name and ignore patterns", () => {
Expand All @@ -56,17 +58,19 @@ describe("getCatalogs", () => {
},
],
})
expect(getCatalogs(config)).toEqual([
new Catalog(
{
name: "all",
path: "src/locales/{locale}/all",
include: ["src/", "/absolute/path/"],
exclude: ["node_modules/"],
},
config
),
])
expect(cleanCatalog(getCatalogs(config)[0])).toEqual(
cleanCatalog(
new Catalog(
{
name: "all",
path: "src/locales/{locale}/all",
include: ["src/", "/absolute/path/"],
exclude: ["node_modules/"],
},
config
)
)
)
})

it("should expand {name} for matching directories", () => {
Expand All @@ -87,24 +91,31 @@ describe("getCatalogs", () => {
},
],
})
expect(getCatalogs(config)).toEqual([
new Catalog(
{
name: "componentA",
path: "componentA/locales/{locale}",
include: ["componentA/"],
exclude: [],
},
config
expect([
cleanCatalog(getCatalogs(config)[0]),
cleanCatalog(getCatalogs(config)[1]),
]).toEqual([
cleanCatalog(
new Catalog(
{
name: "componentA",
path: "componentA/locales/{locale}",
include: ["componentA/"],
exclude: [],
},
config
)
),
new Catalog(
{
name: "componentB",
path: "componentB/locales/{locale}",
include: ["componentB/"],
exclude: [],
},
config
cleanCatalog(
new Catalog(
{
name: "componentB",
path: "componentB/locales/{locale}",
include: ["componentB/"],
exclude: [],
},
config
)
),
])
})
Expand All @@ -124,17 +135,19 @@ describe("getCatalogs", () => {
},
],
})
expect(getCatalogs(config)).toEqual([
new Catalog(
{
name: "componentA",
path: "componentA/locales/{locale}/componentA_messages_{locale}",
include: ["componentA/"],
exclude: [],
},
config
),
])
expect(cleanCatalog(getCatalogs(config)[0])).toEqual(
cleanCatalog(
new Catalog(
{
name: "componentA",
path: "componentA/locales/{locale}/componentA_messages_{locale}",
include: ["componentA/"],
exclude: [],
},
config
)
)
)
})

it("shouldn't expand {name} for ignored directories", () => {
Expand All @@ -156,17 +169,19 @@ describe("getCatalogs", () => {
},
],
})
expect(getCatalogs(config)).toEqual([
new Catalog(
{
name: "componentA",
path: "componentA/locales/{locale}",
include: ["componentA/"],
exclude: ["componentB/"],
},
config
),
])
expect(cleanCatalog(getCatalogs(config)[0])).toEqual(
cleanCatalog(
new Catalog(
{
name: "componentA",
path: "componentA/locales/{locale}",
include: ["componentA/"],
exclude: ["componentB/"],
},
config
)
)
)
})

it("should warn if catalogPath is a directory", () => {
Expand Down Expand Up @@ -216,6 +231,12 @@ describe("getCatalogs", () => {
})
})

// remove non-serializable properties, which are not subject of a test
function cleanCatalog(catalog: Catalog) {
delete catalog.config
delete catalog.format
return catalog
}
describe("getCatalogForMerge", () => {
afterEach(() => {
mockFs.restore()
Expand All @@ -225,15 +246,17 @@ describe("getCatalogForMerge", () => {
const config = mockConfig({
catalogsMergePath: "locales/{locale}",
})
expect(getCatalogForMerge(config)).toEqual(
new Catalog(
{
name: null,
path: "locales/{locale}",
include: [],
exclude: [],
},
config
expect(cleanCatalog(getCatalogForMerge(config))).toEqual(
cleanCatalog(
new Catalog(
{
name: null,
path: "locales/{locale}",
include: [],
exclude: [],
},
config
)
)
)
})
Expand All @@ -242,15 +265,17 @@ describe("getCatalogForMerge", () => {
const config = mockConfig({
catalogsMergePath: "locales/{locale}/my/dir",
})
expect(getCatalogForMerge(config)).toEqual(
new Catalog(
{
name: "dir",
path: "locales/{locale}/my/dir",
include: [],
exclude: [],
},
config
expect(cleanCatalog(getCatalogForMerge(config))).toStrictEqual(
cleanCatalog(
new Catalog(
{
name: "dir",
path: "locales/{locale}/my/dir",
include: [],
exclude: [],
},
config
)
)
)
})
Expand Down
5 changes: 4 additions & 1 deletion packages/cli/src/api/catalog/getCatalogs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,10 @@ function validateCatalogPath(path: string, config: LinguiConfigNormalized) {
return
}

const extension = getFormat(config.format).catalogExtension
const extension = getFormat(
config.format,
config.formatOptions
).catalogExtension
const correctPath = path.slice(0, -1)
const examplePath =
replacePlaceholders(correctPath, {
Expand Down
14 changes: 8 additions & 6 deletions packages/cli/src/api/formats/csv.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ import fs from "fs"
import path from "path"
import mockFs from "mock-fs"

import format from "./csv"
import createFormatter from "./csv"

describe("csv format", () => {
const format = createFormatter()

describe("csv format", function () {
afterEach(() => {
mockFs.restore()
})

it("should write catalog in csv format", function () {
it("should write catalog in csv format", () => {
mockFs({
locale: {
en: mockFs.directory(),
Expand All @@ -34,7 +36,7 @@ describe("csv format", function () {
expect(csv).toMatchSnapshot()
})

it("should not throw if directory not exists", function () {
it("should not throw if directory not exists", () => {
mockFs({})
const filename = path.join("locale", "en", "messages.csv")
const catalog = {
Expand All @@ -49,7 +51,7 @@ describe("csv format", function () {
expect(content).toBeTruthy()
})

it("should read catalog in csv format", function () {
it("should read catalog in csv format", () => {
const csv = fs
.readFileSync(
path.join(path.resolve(__dirname), "fixtures", "messages.csv")
Expand Down Expand Up @@ -79,7 +81,7 @@ describe("csv format", function () {
expect(actual).toBeNull()
})

it("should write the same catalog as it was read", function () {
it("should write the same catalog as it was read", () => {
const csv = fs
.readFileSync(
path.join(path.resolve(__dirname), "fixtures", "messages.csv")
Expand Down
Loading

0 comments on commit 39b9a2d

Please sign in to comment.