summaryrefslogtreecommitdiffstats
path: root/spec/visitor.js
diff options
context:
space:
mode:
authorkpdecker <kpdecker@gmail.com>2014-12-26 11:32:30 -0600
committerkpdecker <kpdecker@gmail.com>2014-12-26 11:32:30 -0600
commit9ff3daf78556a62829b8982c467243dc810a8a6b (patch)
tree10418fff6c5b4f2039487048c8eb932de95834c9 /spec/visitor.js
parent8babe059534acda388672491108c2d6f1ac2a431 (diff)
downloadhandlebars.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.js111
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');
+ });
+ });
+ });
});