Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ST-5114: Handle cases when only the token is in the base string #13

Merged
merged 2 commits into from
Aug 23, 2023

Conversation

dominicfraser
Copy link

Previously given a base string containing only a token the plugin would not replace the translate function.

Given the test:

('Should replace the token using the custom pattern', () => {
    const source = `t('key_hello', { name: 'Rob' });`;

    const expected = `"Rob";`;

    const { code } = transformSync(source, {
        babelrc: false,
        plugins: [
            [
                i18nPlugin,
                {
                    delimiter: '@@',
                    dictionary: {
                        key_hello: '@@name@@',    <----- only the token
                    },
                },
            ],
        ],
    });

    expect(code).toBe(expected);
});

It fails, and leaves the function in the code:

    - Expected  - 1
    + Received  + 3

    - "Rob";
    + t('key_hello', {
    +   name: 'Rob'
    + });

While token-only strings are likely a bug in itself, the plugin should be able to handle them, as trying the call the translate function when it is left in the bundle causes worse problems.

This PR addresses that need.

@@ -121,7 +121,7 @@ module.exports = function i18nPlugin({ types: t }) {
previousNode,
currentNode,
);
});
}, '');
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was no initial value set for the reduce function.

In the case of there only being a token then the array the reducer was being called on would only contain one item:

['{name}']

When there is no initial value and only one item in the array reduce does not execute.

Screenshot 2023-08-18 at 13 35 27

This is a problem, as getNodeForValue called on every item that reduce executes on is also the function to transform it (from {name} to Rob).

By adding an initial value the reducer uses the first item in the array as its first current value, setting its first run to index 0, and allowing us inside the reducer.

Screenshot 2023-08-18 at 13 41 46

We then need to make sure to do the 'previousNode' check on the initial value (moving its index check from 1 to 0, as when using an initial value it starts at 0, when not using an initial value it starts at 1).

If initialValue is specified, callbackFn starts executing with the first value in the array as currentValue. If initialValue is not specified, accumulator is initialized to the first value in the array, and callbackFn starts executing with the second value in the array as currentValue

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

Copy link

@james-od james-od left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, wasn't aware of that nuance r.e indexing.
Fix makes sense to me 👍

Copy link

@alakbarz alakbarz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving @james-od's approval ✅

@dominicfraser dominicfraser merged commit f88f9f7 into main Aug 23, 2023
1 check passed
@dominicfraser dominicfraser deleted the ST-5114_when_only_token branch August 23, 2023 09:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants