Permalink
Browse files

Adding basic parse error reporting.

  • Loading branch information...
1 parent ad837c8 commit 467fefabf785b49d2575396802862235a524b7fd @pvande pvande committed Jan 9, 2011
Showing with 77 additions and 1 deletion.
  1. +23 −1 lib/Template/Mustache.pm
  2. +54 −0 t/parse_errors.t
View
@@ -80,6 +80,13 @@ sub parse {
my $cache = $TemplateCache{join ' ', @$delims} ||= {};
return $cache->{$tmpl} if exists $cache->{$tmpl};
+ my $error = sub {
+ my ($message, $errorPos) = @_;
+ my @lineCount = split("\n", substr($tmpl, 0, $errorPos));
+
+ die $message . "\nLine " . length(@lineCount);
+ };
+
# Build the pattern, and instruct the regex engine to begin at `$start`.
my $pattern = build_pattern(@$delims);
my $pos = pos($tmpl) = $start ||= 0;
@@ -125,7 +132,12 @@ sub parse {
} elsif ($type eq '=') {
# Set Delimiter Tag - Changes the delimiter pair and updates the
# tag pattern.
- $pattern = build_pattern(@{$delims = [ split(/\s+/, $tag) ]});
+ $delims = [ split(/\s+/, $tag) ];
+
+ $error->("Set Delimiters tags must have exactly two values!", $pos)
+ if @$delims != 2;
+
+ $pattern = build_pattern(@$delims);
} elsif ($type eq '#' || $type eq '^') {
# Section Tag - Recursively calls #parse (starting from the current
# index), and receives the raw section string and a new index.
@@ -136,9 +148,19 @@ sub parse {
# End Section Tag - Short circuits a recursive call to #parse,
# caches the buffer for the raw section template, and returns the
# raw section template and the index immediately following the tag.
+ my $msg;
+ if (!$section) {
+ $msg = "End Section tag '$tag' found, but not in a section!";
+ } elsif ($tag ne $section) {
+ $msg = "End Section tag closes '$tag'; expected '$section'!";
+ }
+ $error->($msg, $pos) if $msg;
+
my $raw_section = substr($tmpl, $start, $eoc + 1 - $start);
$cache->{$raw_section} = [@buffer];
return ($raw_section, $pos);
+ } else {
+ $error->("Unknown tag type -- $type", $pos);
}
# Update our match pointer to coincide with any changes we've made.
View
@@ -0,0 +1,54 @@
+use Test::Mini::Unit;
+use Template::Mustache;
+
+case t::ParseErrors {
+ test closing_the_wrong_section_tag {
+ assert_dies(sub {
+ Template::Mustache->render("
+ Before...
+ {{#section}}
+ Inner...
+ {{/other}}
+ After...
+ ")
+ }, "End Section tag closes 'other'; expected 'section'!");
+ }
+
+ test not_closing_a_nested_section_tag {
+ assert_dies(sub {
+ Template::Mustache->render("
+ {{#a}}
+ {{#b}}
+ {{/a}}
+ ")
+ }, "End Section tag closes 'a'; expected 'b'!");
+ }
+
+ test closing_a_section_at_the_top_level {
+ assert_dies(sub {
+ Template::Mustache->render("
+ Before...
+ {{/section}}
+ After...
+ ")
+ }, "End Section tag 'section' found, but not in a section!");
+ }
+
+ test specifying_too_few_delimiters {
+ assert_dies(sub {
+ Template::Mustache->render('{{= $$$ =}}')
+ }, 'Set Delimiters tags must have exactly two values!');
+ }
+
+ test specifying_too_many_delimiters {
+ assert_dies(sub {
+ Template::Mustache->render('{{= $ $ $ =}}')
+ }, 'Set Delimiters tags must have exactly two values!');
+ }
+
+ test specifying_an_unknown_tag_type {
+ assert_dies(sub {
+ Template::Mustache->render('{{% something }}')
+ }, 'Unknown tag type -- %');
+ }
+}

0 comments on commit 467fefa

Please sign in to comment.