Skip to content

Commit

Permalink
support labeled expressions in macro methods arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
timofei-iatsenko committed Dec 23, 2024
1 parent 4a708e7 commit 2a76ac2
Show file tree
Hide file tree
Showing 13 changed files with 288 additions and 38 deletions.
4 changes: 0 additions & 4 deletions packages/babel-plugin-lingui-macro/src/macroJsAst.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,10 +301,6 @@ export function expressionToArgument(
if (t.isIdentifier(exp)) {
return exp.name
}

if (t.isStringLiteral(exp)) {
return exp.value
}
return String(ctx.getExpressionIndex())
}

Expand Down
24 changes: 8 additions & 16 deletions packages/babel-plugin-lingui-macro/src/macroJsx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ export class MacroJSX {
)(attr.node)
})

const token: Token = {
let token: Token = {
type: "arg",
format,
name: null,
Expand All @@ -321,10 +321,12 @@ export class MacroJSX {
| NodePath<JSXExpressionContainer>

if (name === "value") {
const exp = value.isLiteral() ? value : value.get("expression")

token.name = this.expressionToArgument(exp)
token.value = exp.node as Expression
token = {
...token,
...this.tokenizeExpression(
value.isLiteral() ? value : value.get("expression")
),
}
} else if (format !== "select" && name === "offset") {
// offset is static parameter, so it must be either string or number
token.options.offset =
Expand Down Expand Up @@ -394,11 +396,7 @@ export class MacroJSX {
},
})

return {
type: "arg",
name: this.expressionToArgument(exp),
value: exp.node,
}
return this.tokenizeExpression(exp)
}

tokenizeText = (value: string): TextToken => {
Expand All @@ -408,12 +406,6 @@ export class MacroJSX {
}
}

expressionToArgument(path: NodePath<Expression | Node>): string {
return path.isIdentifier()
? path.node.name
: String(this.ctx.getExpressionIndex())
}

isLinguiComponent = (
path: NodePath,
name: JsxMacroName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,78 @@ _i18n._(
`;
exports[`Macro with labeled expression as value 1`] = `
import { plural } from "@lingui/core/macro";
const a = plural(
{ count: getCount() },
{
one: \`# book\`,
other: "# books",
}
);
↓ ↓ ↓ ↓ ↓ ↓
import { i18n as _i18n } from "@lingui/core";
const a = _i18n._(
/*i18n*/
{
id: "esnaQO",
message: "{count, plural, one {# book} other {# books}}",
values: {
count: getCount(),
},
}
);
`;
exports[`Macro with labeled expression as value 2`] = `
import { plural, ph } from "@lingui/core/macro";
const a = plural(ph({ count: getCount() }), {
one: \`# book\`,
other: "# books",
});
↓ ↓ ↓ ↓ ↓ ↓
import { i18n as _i18n } from "@lingui/core";
const a = _i18n._(
/*i18n*/
{
id: "esnaQO",
message: "{count, plural, one {# book} other {# books}}",
values: {
count: getCount(),
},
}
);
`;
exports[`Macro with labeled expression with \`as\` expression 1`] = `
import { plural } from "@lingui/core/macro";
const a = plural({ count: getCount() } as any, {
one: \`# book\`,
other: "# books",
});
↓ ↓ ↓ ↓ ↓ ↓
import { i18n as _i18n } from "@lingui/core";
const a = _i18n._(
/*i18n*/
{
id: "esnaQO",
message: "{count, plural, one {# book} other {# books}}",
values: {
count: getCount(),
},
}
);
`;
exports[`Macro with offset and exact matches 1`] = `
import { plural } from "@lingui/core/macro";
plural(users.length, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,3 +261,62 @@ import { Trans as _Trans } from "@lingui/react";
/>;
`;
exports[`With labeled expression as value 1`] = `
import { Plural } from "@lingui/react/macro";
<Plural
value={{ count: getCount() }}
one={"oneText"}
other={<a href="/more">A lot of them</a>}
/>;
↓ ↓ ↓ ↓ ↓ ↓
import { Trans as _Trans } from "@lingui/react";
<_Trans
{
/*i18n*/
...{
id: "blU5AK",
message: "{count, plural, one {oneText} other {<0>A lot of them</0>}}",
values: {
count: getCount(),
},
components: {
0: <a href="/more" />,
},
}
}
/>;
`;
exports[`With labeled expression as value with ph 1`] = `
import { Plural } from "@lingui/react/macro";
import { ph } from "@lingui/core/macro";
<Plural
value={ph({ count: getCount() })}
one={"oneText"}
other={<a href="/more">A lot of them</a>}
/>;
↓ ↓ ↓ ↓ ↓ ↓
import { Trans as _Trans } from "@lingui/react";
<_Trans
{
/*i18n*/
...{
id: "blU5AK",
message: "{count, plural, one {oneText} other {<0>A lot of them</0>}}",
values: {
count: getCount(),
},
components: {
0: <a href="/more" />,
},
}
}
/>;
`;
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { macroTester } from "./macroTester"
describe.skip("", () => {})

macroTester({
cases: [
Expand Down
34 changes: 34 additions & 0 deletions packages/babel-plugin-lingui-macro/test/js-plural.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { macroTester } from "./macroTester"
describe.skip("", () => {})

macroTester({
cases: [
Expand Down Expand Up @@ -46,5 +47,38 @@ macroTester({
});
`,
},
{
name: "Macro with labeled expression as value",
code: `
import { plural } from '@lingui/core/macro'
const a = plural({ count: getCount() }, {
"one": \`# book\`,
other: "# books"
});
`,
},

{
name: "Macro with labeled expression as value",
code: `
import { plural, ph } from '@lingui/core/macro'
const a = plural(ph({ count: getCount() }), {
"one": \`# book\`,
other: "# books"
});
`,
},

{
useTypescriptPreset: true,
name: "Macro with labeled expression with `as` expression",
code: `
import { plural } from '@lingui/core/macro'
const a = plural({ count: getCount() } as any, {
"one": \`# book\`,
other: "# books"
});
`,
},
],
})
1 change: 1 addition & 0 deletions packages/babel-plugin-lingui-macro/test/js-select.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { macroTester } from "./macroTester"
describe.skip("", () => {})

macroTester({
cases: [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { macroTester } from "./macroTester"
describe.skip("", () => {})

macroTester({
cases: [
Expand Down
24 changes: 24 additions & 0 deletions packages/babel-plugin-lingui-macro/test/jsx-plural.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,30 @@ macroTester({
/>;
`,
},
{
name: "With labeled expression as value",
code: `
import { Plural } from '@lingui/react/macro';
<Plural
value={{count: getCount()}}
one={"oneText"}
other={<a href="/more">A lot of them</a>}
/>;
`,
},
{
name: "With labeled expression as value with ph",
code: `
import { Plural } from '@lingui/react/macro';
import { ph } from '@lingui/core/macro';
<Plural
value={ph({count: getCount()})}
one={"oneText"}
other={<a href="/more">A lot of them</a>}
/>;
`,
},

{
filename: `jsx-plural-select-nested.js`,
},
Expand Down
2 changes: 2 additions & 0 deletions packages/babel-plugin-lingui-macro/test/jsx-select.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { macroTester } from "./macroTester"
describe.skip("", () => {})

macroTester({
cases: [
Expand Down Expand Up @@ -27,6 +28,7 @@ macroTester({
`,
},
{
only: true,
name: "Select should support JSX elements in cases",
code: `
import { Select, Trans } from '@lingui/react/macro';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { macroTester } from "./macroTester"
describe.skip("", () => {})

macroTester({
cases: [
Expand Down
58 changes: 58 additions & 0 deletions packages/core/macro/__typetests__/index.test-d.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,25 @@ expectType<string>(
})
)

// with labeled value
expectType<string>(
plural(
{ count: 5 },
{
one: "...",
other: "...",
}
)
)

// with labeled value with ph helper
expectType<string>(
plural(ph({ count: 5 }), {
one: "...",
other: "...",
})
)

expectType<string>(
plural(5, {
// @ts-expect-error: should accept only strings
Expand Down Expand Up @@ -224,6 +243,25 @@ expectType<string>(
})
)

// with labeled value
expectType<string>(
selectOrdinal(
{ count: 5 },
{
one: "...",
other: "...",
}
)
)

// with labeled value with ph helper
expectType<string>(
selectOrdinal(ph({ count: 5 }), {
one: "...",
other: "...",
})
)

///////////////////
//// Select
///////////////////
Expand Down Expand Up @@ -251,6 +289,26 @@ expectType<string>(
})
)

// with labeled value
expectType<string>(
select(
// @ts-expect-error value could be strings only
{ count: 5 },
{
male: "...",
other: "...",
}
)
)

// with labeled value with ph helper
expectType<string>(
select(ph({ value: "one" }), {
male: "...",
other: "...",
})
)

expectType<string>(
select("male", {
// @ts-expect-error: should accept only strings
Expand Down
Loading

0 comments on commit 2a76ac2

Please sign in to comment.