diff options
author | kpdecker <kpdecker@gmail.com> | 2014-12-26 11:32:30 -0600 |
---|---|---|
committer | kpdecker <kpdecker@gmail.com> | 2014-12-26 11:32:30 -0600 |
commit | 9ff3daf78556a62829b8982c467243dc810a8a6b (patch) | |
tree | 10418fff6c5b4f2039487048c8eb932de95834c9 /spec/visitor.js | |
parent | 8babe059534acda388672491108c2d6f1ac2a431 (diff) | |
download | handlebars.js-9ff3daf78556a62829b8982c467243dc810a8a6b.zip handlebars.js-9ff3daf78556a62829b8982c467243dc810a8a6b.tar.gz handlebars.js-9ff3daf78556a62829b8982c467243dc810a8a6b.tar.bz2 |
Add parent tracking and mutation to AST visitors
Fixes #916
Diffstat (limited to 'spec/visitor.js')
-rw-r--r-- | spec/visitor.js | 111 |
1 files changed, 108 insertions, 3 deletions
diff --git a/spec/visitor.js b/spec/visitor.js index 17a948e..0c23c0d 100644 --- a/spec/visitor.js +++ b/spec/visitor.js @@ -1,7 +1,7 @@ -/*global Handlebars */ +/*global Handlebars, shouldThrow */ describe('Visitor', function() { - if (!Handlebars.Visitor) { + if (!Handlebars.Visitor || !Handlebars.print) { return; } @@ -23,9 +23,15 @@ describe('Visitor', function() { }; visitor.BooleanLiteral = function(bool) { equal(bool.value, true); + + equal(this.parents.length, 4); + equal(this.parents[0].type, 'SubExpression'); + equal(this.parents[1].type, 'SubExpression'); + equal(this.parents[2].type, 'BlockStatement'); + equal(this.parents[3].type, 'Program'); }; visitor.PathExpression = function(id) { - equal(/foo\.bar$/.test(id.original), true); + equal(/(foo\.)?bar$/.test(id.original), true); }; visitor.ContentStatement = function(content) { equal(content.value, ' '); @@ -36,4 +42,103 @@ describe('Visitor', function() { visitor.accept(Handlebars.parse('{{#foo.bar (foo.bar 1 "2" true) foo=@foo.bar}}{{!comment}}{{> bar }} {{/foo.bar}}')); }); + + it('should return undefined'); + + describe('mutating', function() { + describe('fields', function() { + it('should replace value', function() { + var visitor = new Handlebars.Visitor(); + + visitor.mutating = true; + visitor.StringLiteral = function(string) { + return new Handlebars.AST.NumberLiteral(42, string.locInfo); + }; + + var ast = Handlebars.parse('{{foo foo="foo"}}'); + visitor.accept(ast); + equals(Handlebars.print(ast), '{{ PATH:foo [] HASH{foo=NUMBER{42}} }}\n'); + }); + it('should treat undefined resonse as identity', function() { + var visitor = new Handlebars.Visitor(); + visitor.mutating = true; + + var ast = Handlebars.parse('{{foo foo=42}}'); + visitor.accept(ast); + equals(Handlebars.print(ast), '{{ PATH:foo [] HASH{foo=NUMBER{42}} }}\n'); + }); + it('should remove false responses', function() { + var visitor = new Handlebars.Visitor(); + + visitor.mutating = true; + visitor.Hash = function() { + return false; + }; + + var ast = Handlebars.parse('{{foo foo=42}}'); + visitor.accept(ast); + equals(Handlebars.print(ast), '{{ PATH:foo [] }}\n'); + }); + it('should throw when removing required values', function() { + shouldThrow(function() { + var visitor = new Handlebars.Visitor(); + + visitor.mutating = true; + visitor.SubExpression = function() { + return false; + }; + + var ast = Handlebars.parse('{{foo 42}}'); + visitor.accept(ast); + }, Handlebars.Exception, 'MustacheStatement requires sexpr'); + }); + it('should throw when returning non-node responses', function() { + shouldThrow(function() { + var visitor = new Handlebars.Visitor(); + + visitor.mutating = true; + visitor.SubExpression = function() { + return {}; + }; + + var ast = Handlebars.parse('{{foo 42}}'); + visitor.accept(ast); + }, Handlebars.Exception, 'Unexpected node type "undefined" found when accepting sexpr on MustacheStatement'); + }); + }); + describe('arrays', function() { + it('should replace value', function() { + var visitor = new Handlebars.Visitor(); + + visitor.mutating = true; + visitor.StringLiteral = function(string) { + return new Handlebars.AST.NumberLiteral(42, string.locInfo); + }; + + var ast = Handlebars.parse('{{foo "foo"}}'); + visitor.accept(ast); + equals(Handlebars.print(ast), '{{ PATH:foo [NUMBER{42}] }}\n'); + }); + it('should treat undefined resonse as identity', function() { + var visitor = new Handlebars.Visitor(); + visitor.mutating = true; + + var ast = Handlebars.parse('{{foo 42}}'); + visitor.accept(ast); + equals(Handlebars.print(ast), '{{ PATH:foo [NUMBER{42}] }}\n'); + }); + it('should remove false responses', function() { + var visitor = new Handlebars.Visitor(); + + visitor.mutating = true; + visitor.NumberLiteral = function() { + return false; + }; + + var ast = Handlebars.parse('{{foo 42}}'); + visitor.accept(ast); + equals(Handlebars.print(ast), '{{ PATH:foo [] }}\n'); + }); + }); + }); }); |