Problem/Motivation
Accidentally, we commited a transformed version of test file. The ES6 builder (Babel) removed some test cases from this file.
Proposed resolution
- Restore the test cases we removed
Remaining tasks
- Review
| Comment | File | Size | Author |
|---|---|---|---|
| #51 | interdiff-44-51.txt | 1.16 KB | effulgentsia |
| #51 | 2889600-51.patch | 7.2 KB | effulgentsia |
| #49 | 2889600-8.patch | 3.54 KB | wim leers |
Comments
Comment #2
droplet commentedOr change the file ext? Will it work?
Comment #3
GrandmaGlassesRopeMan@droplet
Great. Since this this now blocking #2880007: Auto-fix ESLint errors and warnings, and this is a pretty simple fix. 🚀👍
Comment #4
droplet commentedComment #5
droplet commentedComment #6
gábor hojtsyLet's review the wording here. Eg. it is definitely not the Locate module :), etc.
Comment #7
GrandmaGlassesRopeMan- fix comment.
Comment #8
GrandmaGlassesRopeMan-
for testing purposesComment #9
nod_good to go.
Comment #10
gábor hojtsyThanks for fixing these. Now that the comment is clear, let me ask why it was a problem that the file got processed. If the ES6 processing breaks the source string parsing that Locale module does, than why would it not break for all the other JS files in core?
Comment #11
droplet commentedBabelJS breaks the TESTs (data) we setup, not the parser. I thought the test data should be always in plain format, no matter in whatever languages. (unless we're going to test the processed result)
Comment #12
gábor hojtsyDrupal parses the processed result at runtime doesn't it?
Comment #13
droplet commentedNope, I don't think babel is a must in all drupal development. On another hand, Minifier may change the code syntax also. We parsing all valid Javascript syntax, so that we also need to test all possible variants to ensure we do not miss anyone.
Comment #14
gábor hojtsyDiscussed the issue with @drpal in chat. Posting for transparency. I believe we would need to parse the file as Drupal will encounter it, otherwise we are not really testing that Drupal is capable of extracting translatable strings from its JS and consequently that it can translate JS strings, but we are just testing that some JS file could be parsed.
Comment #15
gábor hojtsy@droplet: why is it failing on the bot then?
Comment #16
droplet commentedI scan the suuuuuuper long chat quickly.
Basically, you should forget all ES6, Babel, other issues bot failing first. With or without those things don't matter.
The point is we made a STRICT test to Loose test.
We do not forced all Drupaler to use babel in their develoment. This is very important, we never announce it and I think we will not do it also. Typescript is also a super cool tool :p. And we able to use min.js in Contrib also. I don't know and will not predict how the JS file looks like.
What we should care:
1. The parser able to parse all strings in valid Javascript code
2. The tests able to catch all possible cases in #1.
So, give you an example.
B1. I code my module's JS this way:
`
Drupal
.
t
(
"Whitespace Call t"
)
;
`
B2. I submit a patch to refactor the locale parser and accepted because the bot is GREEN. In my patch I will remove the regex to capture B1 syntax.
B3. my module doesn't work.
Is it a bug?
Let's me know if I need to explain it further more :) (I'm sure I can't explain it any better way. hehe)
Comment #17
droplet commentedIf you think,... OH Babel may get things more UGLY than we predicted, then we must add an extra test to test babel processed code also.
Comment #18
gábor hojtsySo looks like we don't force a tool but we did make a choice of a tool on the testing server which is why it failed? Is that a fair understanding?
What would this tool or other tools do that would fail our JS parsing? While @drpal said it is futile to add more effort to our existing JS testing infrastructure when we are about to drop it, what happens here is we *need to parse JS in PHP* so we'll need to keep testing that parsing in PHP regardless of what happens to the testing of the JS itself. Because we need to test our PHP code in terms of how it behaves with our JS code. Looks like now with the JS tools where we don't force the hands of our devs the variety of what could happen to our JS grew which is why the test failed.
Do we have a copy of what babel (or whatever the tool used on testbot) did/does to the file that broke the tests? Ie. how does the JS look like that failed? (not from that specific fail, but as reproducible locally)?
Do we have a list of "mostly used JS processors" that can run on the sample JS file and see if they make changes to the file that would be incompatible with what we parse in PHP? This last thing I would not hold against this patch because its a bit open ended to be honest. But for the previous point it would be important to ensure that at least the processor that our testing infrastructure runs with produces files that are compatible with the PHP parser in Drupal that parses the JS at runtime.
Comment #19
droplet commentedCorrect.
Ahh I think you misunderstood @drpal's word. The failture on #2880007: Auto-fix ESLint errors and warnings is caused by ESLint.
The patch in this issue is to restore the test cases.
This is 2 different issues. Please @see IS.
Will it make more sense?
Personally, I perferred the first patch I've uploaded. The seoncd patch just making the commiters happier and less confuse in the future: https://www.drupal.org/node/2880007#comment-12143062
This is why `.js.fake`, not `.js`
Comment #20
gábor hojtsyOk looked at the issue summary again. It says:
Comparing the two files, it looks like these were transformed to be on one line each:
Otherwise test cases were not removed were they? The quoted quotes, etc. are still the same. The test fails @drpal pointed me to are failing on the lack of quoted quotes.
Also the issue summary says
but it does not seem to currently have anything around the quote problems that @drpal pointed to as being failures on testbot. So what is being run on the file additionally in the test environment that transforms the quoted quotes and makes it fail?
Comment #21
droplet commentedWell.. Both strings in JS and Test's PHP should be identical. The ESLint remove the "escape" in SOURCE FILE, that's why the test is failed.
This is how ESLint autofix does:
This is orginal code and defined in TESTS
You should count the failtures tests on #2880007: Auto-fix ESLint errors and warnings is a INCORRECT PATCH. We DID NOT find any new bug around the test case. No additional tests will be requried.
Comment #22
droplet commentedComment #23
droplet commentedThis step is prevent a script to reduce our tests. This is NOT skipped to test a failed test case. See the differences?
Comment #24
gábor hojtsyWill Drupal encounter the eslinted files though at runtime or will it encounter the untouched files as this test wants to make it appear like? If it will encounter the eslinted files, then we should have a way to test that the PHP code that Drupal runs works fine with those eslinted files. Otherwise we are testing Drupal's PHP parsing JS that is not really Drupal's JS.
Where will that eslint run? On commit? On Drupal sites? Will it run for contrib modules? As per #2880007: Auto-fix ESLint errors and warnings it seems like this is a one-time manual run. Can we update the testing JS in this issue to keep the escaping intact. Eg. add a single quote as well to the double quoted escaped string to make it not transform to a single quote wrapped string? Ie.
Comment #25
droplet commentedGábor,
You lost and still not jump out of the incorrect patch in that issue. Again, this is 2 isolated issues. (@drpal made a wrong comment)
Drupal works fine with those eslinted files. After patching, we still testing the SAME thing as before patch and more.
This is what I'm doing now on this issue. (move to .fake)
All of your suggestions have already covered in my patch above.
We defined a test and doing string comparsion:
Single Quote \'Escaped\' tCorrect:
JS:
Drupal.t('Single Quote \'Escaped\' t');PHP matches:
Single Quote \'Escaped\' tResult: GREEN, this is matched with the test case. Two strings are identical.
Incorrect:
Incorrect patch:
Drupal.t("Single Quote 'Escaped' t");PHP matches:
Single Quote 'Escaped' tResult: RED, the string does not match the test case. Now, we found we made an INCORRECT patch.
Comment #26
gábor hojtsyOk I tried keeping myself from submitting a patch here because that now makes me ineligible to commit this. But since there does not seem to be another way to move this forward there you go.
Once again I am not claiming it would not work fine with those files now. What I am saying is we should let the tested JS file go through the same linting / optimization / build steps whatever there going to be (whatever the name of the tool and regardless of whether it runs on the client or server or testbot or in the build process or on github or whatever). Because that is the JS file that Drupal will ultimately see when it parses the JS file for source strings.
The test is ensuring that what JS file Drupal encounters will be possible to parse with the regex in the PHP code so the translations can be pulled and put into the response. If we remove this test JS file from the process pipelines because the pipeline modifies it in a way that is inappropriate, we are creating a dead end where the file will not be picked up by any of the build tools, linters, whatevers and we would never know if the actual final JS files that Drupal encounters will be possible to parse with our PHP code. We will only know the JS file that we purposefully created and fixed in place (before build tools and linters were on the table) can be parsed by our PHP. That is of little assurance that Drupal can also parse the live JS it encounters. These are two different things.
That is why I am once again advocating to find ways to make this JS file keep (some of) the characteristics we are testing for. Can we at least explore this direction before we discard it?
What would the eslint patch do to JS modified like this? (Only setting to needs review for testbot, not claiming this is ready).
Comment #28
gábor hojtsyPost phpunit conversion variant so it applies.
Comment #29
droplet commentedYou made things really wrong. You could call your patch adding a mixed single & double test. But I think it's useless.
You have to understand what
\Drupal\Tests\locale\Functional\LocaleJavascriptTranslationTestdoes at first place.Comment #30
droplet commentedAnd this is JavaScript syntax, even PHP is same. Only 2 (4) formats:
You made it mixed:
is equal to test it separately
If we intented to add mixed test. It should be below, not modify every lines:
Comment #31
gábor hojtsy@droplet: As far as I see it checks that the Drupal side PHP can parse the JS file with various syntaxes and it finds the translation source strings regardless of what syntax quirks are in the JS file (eg. escaped quotes, whitespace, concatenation, etc). What am I missing?
Comment #32
droplet commentedGábor Hojtsy
You right! Then I don't understand why you don't get my points... (or I don't get your point)
We should ask nod_ for help. Needs someone to explain it in a new way :)
Comment #33
gábor hojtsyComment #34
droplet commentedWell. You point is my comment #17. Let's do in a new issue thread. The additional tests can be no escaped quotes. Basically, only whitespace testing. When we chose BabelJS, we trust babeljs itself test engine also. It won't modify the STRING CONTENT.
Besides that, most of time, we able to draw an equals sign

Comment #35
droplet commentedWe able to enhance the test cases like this:
(imagine large spacing is TAB, I don't know how to add TAB here.)
Abouslotely a new task.
Comment #36
droplet commentedIt's a big topic:
#2892150: Decide if we parse wired code style syntax in Locale JS strings
Comment #37
GrandmaGlassesRopeManThis issue is blocking #2880007: Auto-fix ESLint errors and warnings, and is potentially blocked by #2892150: Decide if we parse wired code style syntax in Locale JS strings.
Comment #38
wim leersI think Gábor Hojtsy & droplet were mostly talking past each other. Here's my feedback.
I'd RTBC this issue, but I first want to see that they both +1 what I'm saying.
Doesn't that mean the test coverage itself was not strict enough?
Indeed. By renaming
locale_test.jstolocale_test.es6.jsand compiling it tolocale_test.jsin #2818825: Rename all JS files to *.es6.js and compile them , we made the test a loose one, since Babel did some processing on the variousDrupal.t()calls andDrupal.formatPlural()calls … and those calls are the edge cases that were being tested in\Drupal\Tests\locale\Functional\LocaleJavascriptTranslationTest::testFileParsing().Further indication that this happened by accident:
core/.eslintignorelistsmodules/locale/tests/locale_test.jsexplicitly as one of the files to ignore!This is exactly what the patch in #8 does. Although I think it'd be better to not name it
*.js.fake, but just*.js. That then actually reflects reality for e.g. contrib & custom code. Can we make Babel skip this file some other way? According to https://babeljs.io/docs/usage/babelrc/ we could do something like:It wasn't a "problem" that the file was processed. The only problem here is that the effective test coverage of
\Drupal\Tests\locale\Functional\LocaleJavascriptTranslationTest::testFileParsing()was undermined: it was no longer testing many edge cases, but only a few, because Babel's processing simplified many of the special cases, to a degree where they weren't edge cases anymore, but common cases, which of course defeats the purpose of\Drupal\Tests\locale\Functional\LocaleJavascriptTranslationTest::testFileParsing()giving us the assurance that even edge cases were being parsed correctly by our PHP code that is parsing translatable strings from JS. That's all!Except that's not really true. Contrib/custom modules that don't use
.es6.jsfiles, but just.jsfiles, will not get these transformations (transpilations) applied.I do understand that you also want to test the results of those transpiled files. But those transpiled files use a strict subset of the crazy edge cases you could construct manually, which is exactly what
locale_test.jsin HEAD shows: because it removes some "craziness", brings more uniformity, we lost test coverage. That's all there is.Comment #39
GrandmaGlassesRopeManAs of right now, our transformations are specific to what's in the
core/directory.I think actually makes sense to not test the results from Babel. If we are always going to be second-guessing the output from the transpiler, we should probably have just not done this process at all. I do think we should actually be testing the
.es6.jsfiles.This is probably a better idea.
Overall, ➕1️⃣ on RTBC.
Comment #40
droplet commentedHmmm... not really I think... Since we only care if it parses the raw STRINGs (translatable string).
EDITED: BabelJS will not change the String literals, only remove the spacing in this case.
That's why ESLint autofix will fail the bots.
EDITED: ESLint autofix will change the String literals. To remove escape character.
The test data is static data already. We need not validate the test data.
I'm fine with it and it's my preferred way, my first patch of this issue :) and we need not change babel.rc. We will remove ES6 version.
The reason to rename it to .fake is bypass committers githook:
https://www.drupal.org/node/2818825#comment-12092438
Comment #41
gábor hojtsyGiven that #2880007: Auto-fix ESLint errors and warnings was just committed, I think its hard to argue this is blocking #2880007: Auto-fix ESLint errors and warnings :)
Comment #42
gábor hojtsyAll I am arguing in this issue since day 1 is how do we know that there are not NEW syntaxes introduced by transpilers that core is not testing against? Did we check that? For all the transpilers we support? A sure-fire way to ensure that is done is to test the transpiled files. Or at least have a file that is tested transpiled and one that is tested verbatim (to ensure that quirks removed by the transpiler are tested). But also ensure that quirks possibly ADDED by the transpiler are also covered.
Comment #43
gábor hojtsyAnd when I wrote transpiler understand it as "whatever changes the JS code from what it was", as in the figure in #33.
Comment #44
droplet commentedEasier life, even neater :P
Please alter my code comments directly if it doesn't explain things well and upload a patch. :P
Comment #45
droplet commentedComment #46
wim leersI think all the permutations in
locale_test.jsare pretty much all the possible permutations already, including the ones that transpilers might create. I think this is why nobody thought of adding explicit additional test coverage. This is also why I'm arguing that just keeping the existinglocale_test.jsas it was before the ES6 conversion should be enough.Comment #47
wim leersI think we can proceed here?
Comment #48
wim leersPer @xjm, promoting to major.
Comment #49
wim leersGábor's concern is that if we have transpilation, are we
locale_test.es6.js?i.e.:
The answers:
locale_test.es6.jsmade a strict test a loose test, because the original file (locale_test.es6.js) has many more edge cases, the transpiled file (locale_test.js) is normalized.locale_test.es6.jsstill contains all the exotic cases, but rather than testing that, we're testinglocale_test.js, which has far fewer exotic cases (because they've been normalized away) This is the regression that was introduced in #2818825: Rename all JS files to *.es6.js and compile them .locale_test.js), but it would be a subset of the syntaxes used bylocale_test.es6.js, so it'd be kind of pointless to test this.The solution is therefore to either:
locale_test.jstolocale_test.es6.js, and not have a transpiled file. This is what #8 does.LocaleJavascriptTranslationTestto test bothlocale_test.es6.jsandlocale_test.js, even though the second file will be a subset of the former and therefore be a kind of pointless test. This is what #44 does.I think #8 makes most sense. So reuploading that file and RTBC'ing.
Comment #51
effulgentsia commentedNot true. HEAD's
locale_test.jscontains{ context:(space after brace), whereaslocale_test.es6.jscontains{context:(no space after brace). Potentially the best thing to do would be to add all the permutations of possible spacings tolocale_test.es6.js, but it would be really hard to ensure that we've really caught all possible permutations. Therefore, I think testing the transpiled version in addition to the ES6 version is helpful as an extra double check.Therefore, of all the patches on this issue, I like #44 the most. Here's just an addition of a code comment explaining to future readers why we're testing both files.
Comment #52
GrandmaGlassesRopeManAlright. I think that #51 is most appropriate resolution. Testing both variations gives us good coverage for most of the variations. 👍🍕
Comment #56
catchCommitted/pushed to 8.5.x and cherry-picked to 8.4.x. Thanks!