-
Notifications
You must be signed in to change notification settings - Fork 3.2k
[No QA] Add test for matching Translations keys #4090
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
Conversation
@iwiznia this PR is itself a test for the PR. Check this https://github.com/Expensify/Expensify.cash/pull/4090/checks?check_run_id=3080986765#step:6:722. |
Please review the translations before merging. I don't speak Spanish but took help from google. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry that I did not realize about this when creating the issue, but can we also add the opposite check? Basically to ensure we don't have tons of unused keys in the non base english files, we would also alert for any key present in non base english files that are not present on the english files.
tests/unit/TranslateTest.js
Outdated
const excludeLanguages = ['en', 'es-ES']; | ||
const languages = _.without(_.keys(originalTranslations.default), ...excludeLanguages); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make this smarter and instead of having to add es-ES
here make it skip any file that has 2 components? ie: pick up es
but not es-ES
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That was not the original Idea. After Sometime, we can decide to add more Translations. and Two component locale would be completely valid in that case. So to skip regardless of specification will lead to code change. So I think its better, not to make it smarter. It is sufficient to fulfill its purpose.
tests/unit/TranslateTest.js
Outdated
@@ -52,3 +54,38 @@ describe('translate', () => { | |||
expect(translate.translate('en', ['testKeyGroup', 'testFunction'], {testVariable})).toBe(expectedValue); | |||
}); | |||
}); | |||
|
|||
describe('Translation Keys', () => { | |||
let activeLanguage; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this "global"? Can't we pass it as a regular argument to matchKeys
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is convenient.
tests/unit/TranslateTest.js
Outdated
path += key ? `${key}.` : ''; | ||
const pathLevel = path; | ||
if (key && !_.has(target, key)) { | ||
console.debug(`🏹 ${path.slice(0, -1)} is missing from ${activeLanguage}.js`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of a debug log line, can we make it so that the test itself fails? Ideally it would show one failed test per missing key if that's possible, but if that's hard we can have one test fail that prints all missing keys.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test will fail, if key don't match. This log is just to show what is missing.
Ideally it would show one failed test per missing key if that's possible,
I don't think its a good idea to create multiple tests that basically test the same thing.
if that's hard we can have one test fail that prints all missing keys.
This can be done. We can log all the missing keys.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok cool, my main point is that it's better to have the test failure show what keys failed instead of having to look at the logs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to find way to add the missing key as failure message itself but I don't think its possible AFAIK. So we have to stick with logs. Could you please give me a hint about how to do that if possible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmmmm, I think that if you change the expect from toBeTruthy
to something like arrayContaining
would make jest to print the diff of the arrays and thus the missing keys?
Hmm, let me think about it. |
Any update here @parasharrajat? I see we are missing translations in several places and this would prevent all those errors. |
@iwiznia I am thinking to rewrite the tests with a simpler and robust implementation. I will post multiple test clauses for each language file...etc. Maybe I'll finish it today. |
@iwiznia It's ready. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, but you got conflicts. Can you:
- Resolve the conflicts
- Make some tests fail in one of your commits, so I can look at the output of the failing tests in the GH actions
Please?
@iwiznia I have made few changes to es.js which will result in a test failure. Please check https://github.com/Expensify/App/pull/4090/checks?check_run_id=3192256522#step:6:595. |
Ah damn, that's not that great as the exact failures are mixed in with other non useful logs. Making some suggestions in the PR to see if we can make it better. |
tests/unit/TranslateTest.js
Outdated
if (hasAllKeys.length) { | ||
console.debug(`🏹 [ ${hasAllKeys.join(', ')} ] are missing from ${ln}.js`); | ||
} | ||
expect(hasAllKeys.length).toBe(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, I was thinking, maybe we could do this and get a better error message?
expect(hasAllKeys.length).toBe(0); | |
expect(hasAllKeys).toBeEqual([]); |
I think this will show in the test result exactly which keys are missing, no?
(same applies to the one below)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does not show the keys that are not correct. It just shows Expected and produced output. So all the correct and wrong keys would be shown as a big string which is like 50 lines long.
Expected: 0 <-- would be all the keys on main language in green color.
Received: 2 <-- would be all the keys on matching language in red color.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested with expect.objectContaining and expect.arrayContaining
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmmmm, can we change the code to do _.without(mainLagunageKeys, ...languageKeys)
? That would return only the missing keys, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It currently only gives the missing keys. Again _.without(mainLagunageKeys, ...languageKeys)
will go in console.log
. @iwiznia
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The console log is not good enough as it is super hard to find the right message. In any case I don't think you understood what I meant, because I just tried and it works. Here's the test code:
it(`Does ${ln} locale has all the keys`, () => {
const hasAllKeys = _.without(mainLanguageKeys, ...languageKeys);
expect(hasAllKeys).toEqual([]);
});
it(`Does ${ln} locale has unused keys`, () => {
const hasAllKeys = _.without(languageKeys, ...mainLanguageKeys);
expect(hasAllKeys).toEqual([]);
});
And this is the output:
● Translation Keys › Does es locale has all the keys
expect(received).toEqual(expected) // deep equality
- Expected - 1
+ Received + 4
- Array []
+ Array [
+ "preferencesPage.mostRecent",
+ "passwordForm.error.incorrectLoginOrPassword",
+ ]
79 | it(`Does ${ln} locale has all the keys`, () => {
80 | const hasAllKeys = _.without(mainLanguageKeys, ...languageKeys);
> 81 | expect(hasAllKeys).toEqual([]);
| ^
82 | });
83 |
84 | it(`Does ${ln} locale has unused keys`, () => {
at Object.<anonymous> (tests/unit/TranslateTest.js:81:32)
● Translation Keys › Does es locale has unused keys
expect(received).toEqual(expected) // deep equality
- Expected - 1
+ Received + 4
- Array []
+ Array [
+ "initialSettingsPage.appDownloadLinks.window.label",
+ "initialSettingsPage.appDownloadLinks.Rajat.label",
+ ]
84 | it(`Does ${ln} locale has unused keys`, () => {
85 | const hasAllKeys = _.without(languageKeys, ...mainLanguageKeys);
> 86 | expect(hasAllKeys).toEqual([]);
| ^
87 | });
88 | });
89 | });
at Object.<anonymous> (tests/unit/TranslateTest.js:86:32)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh Yeah. This way I got it now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@iwiznia Check this out https://github.com/Expensify/App/actions/runs/1079637864. I added annotations.
@iwiznia Thanks for the hint. I have updated the PR with the following changes:
It's now ready to be merged. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah lovely!
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
🚀 Deployed to staging in version: 1.0.81-5🚀
|
🚀 Deployed to production in version: 1.0.82-7🚀
|
Details
Added Unit test that matches the keys from each Language file to the Main EN.js translations. If any key is missing, the test will fail. You will see a log stating the path of the key.
Fixed Issues
$ #4082