Files
handlebars.js/spec/parser_spec.rb
T
wycats f205cec745 Finish compatibility with the old handlebars:
* foo"bar" is an invalid param
* {{foo}}bar{{/baz}} is invalid
* fix a number of issues with inverse sections
* add partials
2010-12-03 16:49:04 -05:00

182 lines
3.9 KiB
Ruby

require "spec_helper"
describe "Parser" do
let(:handlebars) { @context["Handlebars"] }
def program(&block)
ASTBuilder.build do
program do
instance_eval(&block)
end
end
end
def ast_for(string)
ast = handlebars.parse(string)
handlebars.print(ast)
end
class ASTBuilder
def self.build(&block)
ret = new
ret.evaluate(&block)
ret.out
end
attr_reader :out
def initialize
@padding = 0
@out = ""
end
def evaluate(&block)
instance_eval(&block)
end
def pad(string)
@out << (" " * @padding) + string + "\n"
end
def with_padding
@padding += 1
ret = yield
@padding -= 1
ret
end
def program
pad("PROGRAM:")
with_padding { yield }
end
def inverse
pad("{{^}}")
with_padding { yield }
end
def block
pad("BLOCK:")
with_padding { yield }
end
def inverted_block
pad("INVERSE:")
with_padding { yield }
end
def mustache(id, *params)
pad("{{ #{id} [#{params.join(", ")}] }}")
end
def partial(id, context = nil)
content = id.dup
content << " #{context}" if context
pad("{{> #{content} }}")
end
def comment(comment)
pad("{{! '#{comment}' }}")
end
def content(string)
pad("CONTENT[ '#{string}' ]")
end
def string(string)
string.inspect
end
def id(id)
"ID:#{id}"
end
def path(*parts)
"PATH:#{parts.join("/")}"
end
end
it "parses simple mustaches" do
ast_for("{{foo}}").should == program { mustache id("foo") }
end
it "parses mustaches with paths" do
ast_for("{{foo/bar}}").should == program { mustache path("foo", "bar") }
end
it "parses mustaches with this/foo" do
ast_for("{{this/foo}}").should == program { mustache id("foo") }
end
it "parses mustaches with parameters" do
ast_for("{{foo bar}}").should == program { mustache id("foo"), id("bar") }
end
it "parses mustaches with string parameters" do
ast_for("{{foo bar \"baz\" }}").should == program { mustache id("foo"), id("bar"), string("baz")}
end
it "parses contents followed by a mustache" do
ast_for("foo bar {{baz}}").should == program do
content "foo bar "
mustache id("baz")
end
end
it "parses a partial" do
ast_for("{{> foo }}").should == program { partial id("foo") }
end
it "parses a partial with context" do
ast_for("{{> foo bar}}").should == program { partial id("foo"), id("bar") }
end
it "parses a comment" do
ast_for("{{! this is a comment }}").should == program do
comment " this is a comment "
end
end
it "parses an inverse section" do
ast_for("{{#foo}} bar {{^}} baz {{/foo}}").should == program do
block do
mustache id("foo")
program do
content " bar "
end
inverse do
content " baz "
end
end
end
end
it "parses a standalone inverse section" do
ast_for("{{^foo}}bar{{/foo}}").should == program do
inverted_block do
mustache id("foo")
program do
content "bar"
end
end
end
end
it "raises if there's a Parse error" do
lambda { ast_for("{{foo}") }.should raise_error(V8::JSError, /Parse error on line 1/)
lambda { ast_for("{{foo &}}")}.should raise_error(V8::JSError, /Parse error on line 1/)
end
it "knows how to report the correct line number in errors" do
lambda { ast_for("hello\nmy\n{{foo}") }.should raise_error(V8::JSError, /Parse error on line 3/m)
lambda { ast_for("hello\n\nmy\n\n{{foo}") }.should raise_error(V8::JSError, /Parse error on line 5/m)
end
it "knows how to report the correct line number in errors when the first character is a newline" do
lambda { ast_for("\n\nhello\n\nmy\n\n{{foo}") }.should raise_error(V8::JSError, /Parse error on line 7/m)
end
end