angular-gettext
angular-gettext copied to clipboard
Data-bound shorthand-if with <= breaks extraction
(Originally posted in angular-gettext-tools repo, but haven't heard back a month and a half later, so reposting here in hopes it will be seen)
tl;dr: The following breaks string-extraction: <p translate>{{ n <= 1 ? 'a' : 'b' }}</p>
When I did a quick scan through already-filed issues I couldn't find any similar to this – sorry if I missed it and this is a duplicate.
Steps to reproduction
- In an html-element with a
translate-attribute, use a smaller-than-or-equal-to operator (<=) in a data-bounds ({{ }}) expression. - Run the
nggettext_extractgrunt-task
Expected:
- Only the inner contents of the html-element should be extracted by the grunt-task. (
{{ n <= 1 ? 'a' : 'b' }})
Actual:
- Everything after the opening tag of the html-element is extracted (the extracted string might look something like
{{ n <= 1 ? 'a' : 'b' }}</p></div></section>)
Tests/code
The following will break on the 4th <p>:
<!-- test/fixtures/shorthand_if.html -->
<html>
<body>
<p translate>1 start {{ n > 1 ? 'if' : 'else' }} end</p>
<!-- comment after 1st line -->
<span>after first</span>
<p translate>2 start {{ n >= 1 ? 'if' : 'else' }} end</p>
<!-- comment after 2nd line -->
<span>after second</span>
<p translate>3 start {{ n < 1 ? 'if' : 'else' }} end</p>
<!-- comment after 3rd line -->
<span>after third</span>
<p translate>4 start {{ n <= 1 ? 'if' : 'else' }} end</p>
<!-- comment after 4th line -->
<span>after fourth</span>
</body>
</html>
// test/extract_shorthand_if.js
var assert = require('assert');
var fs = require('fs');
var Extractor = require('..').Extractor;
var testExtract = require('./utils').testExtract;
describe('String extractor', function () {
it('extracts strings with data-bound shorthand-if statements containing smaller-than-or-equal-to operators', function () {
var files = [
'test/fixtures/shorthand_if.html'
];
var paragraphs = [
"1 start {{ n > 1 ? 'if' : 'else' }} end",
"2 start {{ n >= 1 ? 'if' : 'else' }} end",
"3 start {{ n < 1 ? 'if' : 'else' }} end",
"4 start {{ n <= 1 ? 'if' : 'else' }} end"
];
var catalog = testExtract(files);
assert.equal(catalog.items.length, paragraphs.length);
for ( var i = 0; i < paragraphs.length; i++ ) {
assert.equal(catalog.items[i].msgid, paragraphs[i]);
assert.equal(catalog.items[i].msgstr, '');
assert.deepEqual(catalog.items[i].references, ['test/fixtures/shorthand_if.html:' + ( 3 + i * 3 )]);
}
});
});
Result/output
AssertionError: "4 start {{ n <= 1=\"\" ?=\"\" 'if'=\"\" :=\"\" 'else'=\"\" }}=\"\" end<=\"\" p=\"\">\n <!-- comment after 4th line -->\n == "4 start {{ n <= 1 ? 'if' : 'else' }} end"
+ expected - actual
-4 start {{ n <= 1="" ?="" 'if'="" :="" 'else'="" }}="" end<="" p="">
- <!-- comment after 4th line -->
- <span>after fourth</span>
- </=>
+4 start {{ n <= 1 ? 'if' : 'else' }} end
Workaround
Use a greater-than operator (>) and swap your ‘if’ and ‘else’ values.
angular-gettext-tools is the right project to file this against, I just haven't had time to dig into what's happening. My guess is that htmlparser2, which we use by way of cheerio, is parsing the <= as a start tag. I can't say for certain though without spending more time debugging.
Also, thanks for the awesome write up of the bug.
On Wednesday, October 14, 2015, rubenswieringa [email protected] wrote:
*(Originally posted in angular-gettext-tools repo https://github.com/rubenv/angular-gettext-tools/issues/108, but haven't heard back a month and a half later, so reposting here in hopes it will be
seen)*
tl;dr: The following breaks string-extraction:
{{ n <= 1 ? 'a' : 'b' }}
When I did a quick scan through already-filed issues I couldn't find any similar to this – sorry if I missed it and this is a duplicate. Steps to reproduction
- In an html-element with a translate-attribute, use a smaller-than-or-equal-to operator (<=) in a data-bounds ({{ }}) expression.
- Run the nggettext_extract grunt-task
Expected:
- Only the inner contents of the html-element should be extracted by the grunt-task. ({{ n <= 1 ? 'a' : 'b' }})
Actual:
- Everything after the opening tag of the html-element is extracted (the extracted string might look something like {{ n <= 1 ? 'a' : 'b' }})
Tests/code
The following will break on the 4th
:
1 start {{ n > 1 ? 'if' : 'else' }} end
after first2 start {{ n >= 1 ? 'if' : 'else' }} end
after second3 start {{ n after third
4 start {{ n after fourth
// test/extract_shorthand_if.js var assert = require('assert');var fs = require('fs');var Extractor = require('..').Extractor;var testExtract = require('./utils').testExtract;
describe('String extractor', function () { it('extracts strings with data-bound shorthand-if statements containing smaller-than-or-equal-to operators', function () { var files = [ 'test/fixtures/shorthand_if.html' ];
var paragraphs = [ "1 start {{ n > 1 ? 'if' : 'else' }} end", "2 start {{ n >= 1 ? 'if' : 'else' }} end", "3 start {{ n < 1 ? 'if' : 'else' }} end", "4 start {{ n <= 1 ? 'if' : 'else' }} end" ]; var catalog = testExtract(files); assert.equal(catalog.items.length, paragraphs.length); for ( var i = 0; i < paragraphs.length; i++ ) { assert.equal(catalog.items[i].msgid, paragraphs[i]); assert.equal(catalog.items[i].msgstr, ''); assert.deepEqual(catalog.items[i].references, ['test/fixtures/shorthand_if.html:' + ( 3 + i * 3 )]); } });});
Result/output
AssertionError: "4 start {{ n <= 1="" ?="" 'if'="" :="" 'else'="" }}="" end<="" p="">\n \n == "4 start {{ n <= 1 ? 'if' : 'else' }} end"
- expected - actual
-4 start {{ n <= 1="" ?="" 'if'="" :="" 'else'="" }}="" end<="" p="">
<!-- comment after 4th line --><span>after fourth</span>- </=> +4 start {{ n <= 1 ? 'if' : 'else' }} end
Workaround
Use a greater-than operator (>) and swap your ‘if’ and ‘else’ values.
— Reply to this email directly or view it on GitHub https://github.com/rubenv/angular-gettext/issues/230.
Alright, thanks for getting back to me. Feel free to close either one of the issues (no need to maintain two separate discussions). Do let me know if you find anything out about this :)