diff options
author | kpdecker <kpdecker@gmail.com> | 2015-04-16 15:42:46 -0500 |
---|---|---|
committer | kpdecker <kpdecker@gmail.com> | 2015-04-16 16:43:01 -0500 |
commit | e3d3eda2e1e03e997d417affc09974446b4ca701 (patch) | |
tree | a6513f267482b1693fd002c20488c6e92095ff2b /spec/parser.js | |
parent | 2a02261a5bc78f246c63dd8d467a12f2c1f63734 (diff) | |
download | handlebars.js-e3d3eda2e1e03e997d417affc09974446b4ca701.zip handlebars.js-e3d3eda2e1e03e997d417affc09974446b4ca701.tar.gz handlebars.js-e3d3eda2e1e03e997d417affc09974446b4ca701.tar.bz2 |
Add full support for es6
Converts the tool chain to use babel, eslint, and webpack vs. the previous proprietary solutions.
Additionally begins enforcing additional linting concerns as well as updates the code to reflect these rules.
Fixes #855
Fixes #993
Diffstat (limited to 'spec/parser.js')
-rw-r--r-- | spec/parser.js | 149 |
1 files changed, 74 insertions, 75 deletions
diff --git a/spec/parser.js b/spec/parser.js index d799e08..c378874 100644 --- a/spec/parser.js +++ b/spec/parser.js @@ -1,235 +1,234 @@ -/*global Handlebars, shouldThrow */ describe('parser', function() { if (!Handlebars.print) { return; } - function ast_for(template) { + function astFor(template) { var ast = Handlebars.parse(template); return Handlebars.print(ast); } it('parses simple mustaches', function() { - equals(ast_for('{{123}}'), "{{ NUMBER{123} [] }}\n"); - equals(ast_for('{{"foo"}}'), '{{ "foo" [] }}\n'); - equals(ast_for('{{false}}'), '{{ BOOLEAN{false} [] }}\n'); - equals(ast_for('{{true}}'), '{{ BOOLEAN{true} [] }}\n'); - equals(ast_for('{{foo}}'), "{{ PATH:foo [] }}\n"); - equals(ast_for('{{foo?}}'), "{{ PATH:foo? [] }}\n"); - equals(ast_for('{{foo_}}'), "{{ PATH:foo_ [] }}\n"); - equals(ast_for('{{foo-}}'), "{{ PATH:foo- [] }}\n"); - equals(ast_for('{{foo:}}'), "{{ PATH:foo: [] }}\n"); + equals(astFor('{{123}}'), '{{ NUMBER{123} [] }}\n'); + equals(astFor('{{"foo"}}'), '{{ "foo" [] }}\n'); + equals(astFor('{{false}}'), '{{ BOOLEAN{false} [] }}\n'); + equals(astFor('{{true}}'), '{{ BOOLEAN{true} [] }}\n'); + equals(astFor('{{foo}}'), '{{ PATH:foo [] }}\n'); + equals(astFor('{{foo?}}'), '{{ PATH:foo? [] }}\n'); + equals(astFor('{{foo_}}'), '{{ PATH:foo_ [] }}\n'); + equals(astFor('{{foo-}}'), '{{ PATH:foo- [] }}\n'); + equals(astFor('{{foo:}}'), '{{ PATH:foo: [] }}\n'); }); it('parses simple mustaches with data', function() { - equals(ast_for("{{@foo}}"), "{{ @PATH:foo [] }}\n"); + equals(astFor('{{@foo}}'), '{{ @PATH:foo [] }}\n'); }); it('parses simple mustaches with data paths', function() { - equals(ast_for("{{@../foo}}"), "{{ @PATH:foo [] }}\n"); + equals(astFor('{{@../foo}}'), '{{ @PATH:foo [] }}\n'); }); it('parses mustaches with paths', function() { - equals(ast_for("{{foo/bar}}"), "{{ PATH:foo/bar [] }}\n"); + equals(astFor('{{foo/bar}}'), '{{ PATH:foo/bar [] }}\n'); }); it('parses mustaches with this/foo', function() { - equals(ast_for("{{this/foo}}"), "{{ PATH:foo [] }}\n"); + equals(astFor('{{this/foo}}'), '{{ PATH:foo [] }}\n'); }); it('parses mustaches with - in a path', function() { - equals(ast_for("{{foo-bar}}"), "{{ PATH:foo-bar [] }}\n"); + equals(astFor('{{foo-bar}}'), '{{ PATH:foo-bar [] }}\n'); }); it('parses mustaches with parameters', function() { - equals(ast_for("{{foo bar}}"), "{{ PATH:foo [PATH:bar] }}\n"); + equals(astFor('{{foo bar}}'), '{{ PATH:foo [PATH:bar] }}\n'); }); it('parses mustaches with string parameters', function() { - equals(ast_for("{{foo bar \"baz\" }}"), '{{ PATH:foo [PATH:bar, "baz"] }}\n'); + equals(astFor('{{foo bar \"baz\" }}'), '{{ PATH:foo [PATH:bar, "baz"] }}\n'); }); it('parses mustaches with NUMBER parameters', function() { - equals(ast_for("{{foo 1}}"), "{{ PATH:foo [NUMBER{1}] }}\n"); + equals(astFor('{{foo 1}}'), '{{ PATH:foo [NUMBER{1}] }}\n'); }); it('parses mustaches with BOOLEAN parameters', function() { - equals(ast_for("{{foo true}}"), "{{ PATH:foo [BOOLEAN{true}] }}\n"); - equals(ast_for("{{foo false}}"), "{{ PATH:foo [BOOLEAN{false}] }}\n"); + equals(astFor('{{foo true}}'), '{{ PATH:foo [BOOLEAN{true}] }}\n'); + equals(astFor('{{foo false}}'), '{{ PATH:foo [BOOLEAN{false}] }}\n'); }); it('parses mustaches with undefined and null paths', function() { - equals(ast_for("{{undefined}}"), "{{ UNDEFINED [] }}\n"); - equals(ast_for("{{null}}"), "{{ NULL [] }}\n"); + equals(astFor('{{undefined}}'), '{{ UNDEFINED [] }}\n'); + equals(astFor('{{null}}'), '{{ NULL [] }}\n'); }); it('parses mustaches with undefined and null parameters', function() { - equals(ast_for("{{foo undefined null}}"), "{{ PATH:foo [UNDEFINED, NULL] }}\n"); + equals(astFor('{{foo undefined null}}'), '{{ PATH:foo [UNDEFINED, NULL] }}\n'); }); it('parses mutaches with DATA parameters', function() { - equals(ast_for("{{foo @bar}}"), "{{ PATH:foo [@PATH:bar] }}\n"); + equals(astFor('{{foo @bar}}'), '{{ PATH:foo [@PATH:bar] }}\n'); }); it('parses mustaches with hash arguments', function() { - equals(ast_for("{{foo bar=baz}}"), "{{ PATH:foo [] HASH{bar=PATH:baz} }}\n"); - equals(ast_for("{{foo bar=1}}"), "{{ PATH:foo [] HASH{bar=NUMBER{1}} }}\n"); - equals(ast_for("{{foo bar=true}}"), "{{ PATH:foo [] HASH{bar=BOOLEAN{true}} }}\n"); - equals(ast_for("{{foo bar=false}}"), "{{ PATH:foo [] HASH{bar=BOOLEAN{false}} }}\n"); - equals(ast_for("{{foo bar=@baz}}"), "{{ PATH:foo [] HASH{bar=@PATH:baz} }}\n"); + equals(astFor('{{foo bar=baz}}'), '{{ PATH:foo [] HASH{bar=PATH:baz} }}\n'); + equals(astFor('{{foo bar=1}}'), '{{ PATH:foo [] HASH{bar=NUMBER{1}} }}\n'); + equals(astFor('{{foo bar=true}}'), '{{ PATH:foo [] HASH{bar=BOOLEAN{true}} }}\n'); + equals(astFor('{{foo bar=false}}'), '{{ PATH:foo [] HASH{bar=BOOLEAN{false}} }}\n'); + equals(astFor('{{foo bar=@baz}}'), '{{ PATH:foo [] HASH{bar=@PATH:baz} }}\n'); - equals(ast_for("{{foo bar=baz bat=bam}}"), "{{ PATH:foo [] HASH{bar=PATH:baz, bat=PATH:bam} }}\n"); - equals(ast_for("{{foo bar=baz bat=\"bam\"}}"), '{{ PATH:foo [] HASH{bar=PATH:baz, bat="bam"} }}\n'); + equals(astFor('{{foo bar=baz bat=bam}}'), '{{ PATH:foo [] HASH{bar=PATH:baz, bat=PATH:bam} }}\n'); + equals(astFor('{{foo bar=baz bat="bam"}}'), '{{ PATH:foo [] HASH{bar=PATH:baz, bat="bam"} }}\n'); - equals(ast_for("{{foo bat='bam'}}"), '{{ PATH:foo [] HASH{bat="bam"} }}\n'); + equals(astFor("{{foo bat='bam'}}"), '{{ PATH:foo [] HASH{bat="bam"} }}\n'); - equals(ast_for("{{foo omg bar=baz bat=\"bam\"}}"), '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam"} }}\n'); - equals(ast_for("{{foo omg bar=baz bat=\"bam\" baz=1}}"), '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam", baz=NUMBER{1}} }}\n'); - equals(ast_for("{{foo omg bar=baz bat=\"bam\" baz=true}}"), '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam", baz=BOOLEAN{true}} }}\n'); - equals(ast_for("{{foo omg bar=baz bat=\"bam\" baz=false}}"), '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam", baz=BOOLEAN{false}} }}\n'); + equals(astFor('{{foo omg bar=baz bat=\"bam\"}}'), '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam"} }}\n'); + equals(astFor('{{foo omg bar=baz bat=\"bam\" baz=1}}'), '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam", baz=NUMBER{1}} }}\n'); + equals(astFor('{{foo omg bar=baz bat=\"bam\" baz=true}}'), '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam", baz=BOOLEAN{true}} }}\n'); + equals(astFor('{{foo omg bar=baz bat=\"bam\" baz=false}}'), '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam", baz=BOOLEAN{false}} }}\n'); }); it('parses contents followed by a mustache', function() { - equals(ast_for("foo bar {{baz}}"), "CONTENT[ \'foo bar \' ]\n{{ PATH:baz [] }}\n"); + equals(astFor('foo bar {{baz}}'), 'CONTENT[ \'foo bar \' ]\n{{ PATH:baz [] }}\n'); }); it('parses a partial', function() { - equals(ast_for("{{> foo }}"), "{{> PARTIAL:foo }}\n"); - equals(ast_for("{{> 'foo' }}"), "{{> PARTIAL:foo }}\n"); - equals(ast_for("{{> 1 }}"), "{{> PARTIAL:1 }}\n"); + equals(astFor('{{> foo }}'), '{{> PARTIAL:foo }}\n'); + equals(astFor('{{> "foo" }}'), '{{> PARTIAL:foo }}\n'); + equals(astFor('{{> 1 }}'), '{{> PARTIAL:1 }}\n'); }); it('parses a partial with context', function() { - equals(ast_for("{{> foo bar}}"), "{{> PARTIAL:foo PATH:bar }}\n"); + equals(astFor('{{> foo bar}}'), '{{> PARTIAL:foo PATH:bar }}\n'); }); it('parses a partial with hash', function() { - equals(ast_for("{{> foo bar=bat}}"), "{{> PARTIAL:foo HASH{bar=PATH:bat} }}\n"); + equals(astFor('{{> foo bar=bat}}'), '{{> PARTIAL:foo HASH{bar=PATH:bat} }}\n'); }); it('parses a partial with context and hash', function() { - equals(ast_for("{{> foo bar bat=baz}}"), "{{> PARTIAL:foo PATH:bar HASH{bat=PATH:baz} }}\n"); + equals(astFor('{{> foo bar bat=baz}}'), '{{> PARTIAL:foo PATH:bar HASH{bat=PATH:baz} }}\n'); }); it('parses a partial with a complex name', function() { - equals(ast_for("{{> shared/partial?.bar}}"), "{{> PARTIAL:shared/partial?.bar }}\n"); + equals(astFor('{{> shared/partial?.bar}}'), '{{> PARTIAL:shared/partial?.bar }}\n'); }); it('parses a comment', function() { - equals(ast_for("{{! this is a comment }}"), "{{! ' this is a comment ' }}\n"); + equals(astFor('{{! this is a comment }}'), "{{! ' this is a comment ' }}\n"); }); it('parses a multi-line comment', function() { - equals(ast_for("{{!\nthis is a multi-line comment\n}}"), "{{! \'\nthis is a multi-line comment\n\' }}\n"); + equals(astFor('{{!\nthis is a multi-line comment\n}}'), "{{! \'\nthis is a multi-line comment\n\' }}\n"); }); it('parses an inverse section', function() { - equals(ast_for("{{#foo}} bar {{^}} baz {{/foo}}"), "BLOCK:\n PATH:foo []\n PROGRAM:\n CONTENT[ ' bar ' ]\n {{^}}\n CONTENT[ ' baz ' ]\n"); + equals(astFor('{{#foo}} bar {{^}} baz {{/foo}}'), "BLOCK:\n PATH:foo []\n PROGRAM:\n CONTENT[ ' bar ' ]\n {{^}}\n CONTENT[ ' baz ' ]\n"); }); it('parses an inverse (else-style) section', function() { - equals(ast_for("{{#foo}} bar {{else}} baz {{/foo}}"), "BLOCK:\n PATH:foo []\n PROGRAM:\n CONTENT[ ' bar ' ]\n {{^}}\n CONTENT[ ' baz ' ]\n"); + equals(astFor('{{#foo}} bar {{else}} baz {{/foo}}'), "BLOCK:\n PATH:foo []\n PROGRAM:\n CONTENT[ ' bar ' ]\n {{^}}\n CONTENT[ ' baz ' ]\n"); }); it('parses multiple inverse sections', function() { - equals(ast_for("{{#foo}} bar {{else if bar}}{{else}} baz {{/foo}}"), "BLOCK:\n PATH:foo []\n PROGRAM:\n CONTENT[ ' bar ' ]\n {{^}}\n BLOCK:\n PATH:if [PATH:bar]\n PROGRAM:\n {{^}}\n CONTENT[ ' baz ' ]\n"); + equals(astFor('{{#foo}} bar {{else if bar}}{{else}} baz {{/foo}}'), "BLOCK:\n PATH:foo []\n PROGRAM:\n CONTENT[ ' bar ' ]\n {{^}}\n BLOCK:\n PATH:if [PATH:bar]\n PROGRAM:\n {{^}}\n CONTENT[ ' baz ' ]\n"); }); it('parses empty blocks', function() { - equals(ast_for("{{#foo}}{{/foo}}"), "BLOCK:\n PATH:foo []\n PROGRAM:\n"); + equals(astFor('{{#foo}}{{/foo}}'), 'BLOCK:\n PATH:foo []\n PROGRAM:\n'); }); it('parses empty blocks with empty inverse section', function() { - equals(ast_for("{{#foo}}{{^}}{{/foo}}"), "BLOCK:\n PATH:foo []\n PROGRAM:\n {{^}}\n"); + equals(astFor('{{#foo}}{{^}}{{/foo}}'), 'BLOCK:\n PATH:foo []\n PROGRAM:\n {{^}}\n'); }); it('parses empty blocks with empty inverse (else-style) section', function() { - equals(ast_for("{{#foo}}{{else}}{{/foo}}"), "BLOCK:\n PATH:foo []\n PROGRAM:\n {{^}}\n"); + equals(astFor('{{#foo}}{{else}}{{/foo}}'), 'BLOCK:\n PATH:foo []\n PROGRAM:\n {{^}}\n'); }); it('parses non-empty blocks with empty inverse section', function() { - equals(ast_for("{{#foo}} bar {{^}}{{/foo}}"), "BLOCK:\n PATH:foo []\n PROGRAM:\n CONTENT[ ' bar ' ]\n {{^}}\n"); + equals(astFor('{{#foo}} bar {{^}}{{/foo}}'), "BLOCK:\n PATH:foo []\n PROGRAM:\n CONTENT[ ' bar ' ]\n {{^}}\n"); }); it('parses non-empty blocks with empty inverse (else-style) section', function() { - equals(ast_for("{{#foo}} bar {{else}}{{/foo}}"), "BLOCK:\n PATH:foo []\n PROGRAM:\n CONTENT[ ' bar ' ]\n {{^}}\n"); + equals(astFor('{{#foo}} bar {{else}}{{/foo}}'), "BLOCK:\n PATH:foo []\n PROGRAM:\n CONTENT[ ' bar ' ]\n {{^}}\n"); }); it('parses empty blocks with non-empty inverse section', function() { - equals(ast_for("{{#foo}}{{^}} bar {{/foo}}"), "BLOCK:\n PATH:foo []\n PROGRAM:\n {{^}}\n CONTENT[ ' bar ' ]\n"); + equals(astFor('{{#foo}}{{^}} bar {{/foo}}'), "BLOCK:\n PATH:foo []\n PROGRAM:\n {{^}}\n CONTENT[ ' bar ' ]\n"); }); it('parses empty blocks with non-empty inverse (else-style) section', function() { - equals(ast_for("{{#foo}}{{else}} bar {{/foo}}"), "BLOCK:\n PATH:foo []\n PROGRAM:\n {{^}}\n CONTENT[ ' bar ' ]\n"); + equals(astFor('{{#foo}}{{else}} bar {{/foo}}'), "BLOCK:\n PATH:foo []\n PROGRAM:\n {{^}}\n CONTENT[ ' bar ' ]\n"); }); it('parses a standalone inverse section', function() { - equals(ast_for("{{^foo}}bar{{/foo}}"), "BLOCK:\n PATH:foo []\n {{^}}\n CONTENT[ 'bar' ]\n"); + equals(astFor('{{^foo}}bar{{/foo}}'), "BLOCK:\n PATH:foo []\n {{^}}\n CONTENT[ 'bar' ]\n"); }); it('throws on old inverse section', function() { shouldThrow(function() { - ast_for("{{else foo}}bar{{/foo}}"); + astFor('{{else foo}}bar{{/foo}}'); }, Error); }); it('parses block with block params', function() { - equals(ast_for("{{#foo as |bar baz|}}content{{/foo}}"), "BLOCK:\n PATH:foo []\n PROGRAM:\n BLOCK PARAMS: [ bar baz ]\n CONTENT[ 'content' ]\n"); + equals(astFor('{{#foo as |bar baz|}}content{{/foo}}'), "BLOCK:\n PATH:foo []\n PROGRAM:\n BLOCK PARAMS: [ bar baz ]\n CONTENT[ 'content' ]\n"); }); it('parses inverse block with block params', function() { - equals(ast_for("{{^foo as |bar baz|}}content{{/foo}}"), "BLOCK:\n PATH:foo []\n {{^}}\n BLOCK PARAMS: [ bar baz ]\n CONTENT[ 'content' ]\n"); + equals(astFor('{{^foo as |bar baz|}}content{{/foo}}'), "BLOCK:\n PATH:foo []\n {{^}}\n BLOCK PARAMS: [ bar baz ]\n CONTENT[ 'content' ]\n"); }); it('parses chained inverse block with block params', function() { - equals(ast_for("{{#foo}}{{else foo as |bar baz|}}content{{/foo}}"), "BLOCK:\n PATH:foo []\n PROGRAM:\n {{^}}\n BLOCK:\n PATH:foo []\n PROGRAM:\n BLOCK PARAMS: [ bar baz ]\n CONTENT[ 'content' ]\n"); + equals(astFor('{{#foo}}{{else foo as |bar baz|}}content{{/foo}}'), "BLOCK:\n PATH:foo []\n PROGRAM:\n {{^}}\n BLOCK:\n PATH:foo []\n PROGRAM:\n BLOCK PARAMS: [ bar baz ]\n CONTENT[ 'content' ]\n"); }); - it("raises if there's a Parse error", function() { + it('raises if there\'s a Parse error', function() { shouldThrow(function() { - ast_for("foo{{^}}bar"); + astFor('foo{{^}}bar'); }, Error, /Parse error on line 1/); shouldThrow(function() { - ast_for("{{foo}"); + astFor('{{foo}'); }, Error, /Parse error on line 1/); shouldThrow(function() { - ast_for("{{foo &}}"); + astFor('{{foo &}}'); }, Error, /Parse error on line 1/); shouldThrow(function() { - ast_for("{{#goodbyes}}{{/hellos}}"); + astFor('{{#goodbyes}}{{/hellos}}'); }, Error, /goodbyes doesn't match hellos/); shouldThrow(function() { - ast_for("{{{{goodbyes}}}} {{{{/hellos}}}}"); + astFor('{{{{goodbyes}}}} {{{{/hellos}}}}'); }, Error, /goodbyes doesn't match hellos/); }); it('should handle invalid paths', function() { shouldThrow(function() { - ast_for("{{foo/../bar}}"); + astFor('{{foo/../bar}}'); }, Error, /Invalid path: foo\/\.\. - 1:2/); shouldThrow(function() { - ast_for("{{foo/./bar}}"); + astFor('{{foo/./bar}}'); }, Error, /Invalid path: foo\/\. - 1:2/); shouldThrow(function() { - ast_for("{{foo/this/bar}}"); + astFor('{{foo/this/bar}}'); }, Error, /Invalid path: foo\/this - 1:2/); }); it('knows how to report the correct line number in errors', function() { shouldThrow(function() { - ast_for("hello\nmy\n{{foo}"); + astFor('hello\nmy\n{{foo}'); }, Error, /Parse error on line 3/); shouldThrow(function() { - ast_for("hello\n\nmy\n\n{{foo}"); + astFor('hello\n\nmy\n\n{{foo}'); }, Error, /Parse error on line 5/); }); it('knows how to report the correct line number in errors when the first character is a newline', function() { shouldThrow(function() { - ast_for("\n\nhello\n\nmy\n\n{{foo}"); + astFor('\n\nhello\n\nmy\n\n{{foo}'); }, Error, /Parse error on line 7/); }); describe('externally compiled AST', function() { it('can pass through an already-compiled AST', function() { - equals(ast_for(new Handlebars.AST.Program([new Handlebars.AST.ContentStatement("Hello")], null)), "CONTENT[ \'Hello\' ]\n"); + equals(astFor(new Handlebars.AST.Program([new Handlebars.AST.ContentStatement('Hello')], null)), 'CONTENT[ \'Hello\' ]\n'); }); }); }); |