package com.dmarcotte.handlebars.parsing;
import static com.dmarcotte.handlebars.parsing.HbTokenTypes.*;
/**
* Java representation of the validations in the spec/tokenizer.js revision which corresponds
* to the revision of handlesbars.l that our lexer is based on
* (https://github.com/wycats/handlebars.js/blob/408192ba9f262bb82be88091ab3ec3c16dc02c6d/spec/tokenizer.js)
* <p/>
* All the tests should be nearly identical except that we generate whitespace tokens to give IDEA a better picture
* of the text, vs. the actual Handlebars lexer which can just toss whitespace out
*/
public class HbTokenizerSpecTest extends HbLexerTest {
/**
* tokenizes a simple mustache as 'OPEN ID CLOSE'
*/
public void testSimpleMustache() {
TokenizerResult result = tokenize("{{foo}}");
result.shouldMatchTokenTypes(OPEN, ID, CLOSE);
result.shouldBeToken(1, ID, "foo");
}
/**
* supports unescaping with &
*/
public void testUnescapingWithAmp() {
TokenizerResult result = tokenize("{{&bar}}");
result.shouldMatchTokenTypes(OPEN, ID, CLOSE);
result.shouldBeToken(0, OPEN, "{{&");
result.shouldBeToken(1, ID, "bar");
}
/**
* supports unescaping with {{{
*/
public void testUnescapingWithTripleStache() {
TokenizerResult result = tokenize("{{{bar}}}");
result.shouldMatchTokenTypes(OPEN_UNESCAPED, ID, CLOSE_UNESCAPED);
result.shouldBeToken(1, ID, "bar");
}
/**
* supports escaping delimiters
*/
public void testEscapingDelimiters() {
TokenizerResult result = tokenize("{{foo}} \\{{bar}} {{baz}}");
result.shouldMatchTokenTypes(OPEN, ID, CLOSE, WHITE_SPACE, ESCAPE_CHAR, CONTENT, OPEN, ID, CLOSE);
result.shouldBeToken(5, CONTENT, "{{bar}} ");
}
/**
* supports escaping multiple delimiters
*/
public void testEscapingMultipleDelimiters() {
TokenizerResult result = tokenize("{{foo}} \\{{bar}} \\{{baz}}");
result.shouldMatchTokenTypes(OPEN, ID, CLOSE, WHITE_SPACE, ESCAPE_CHAR, CONTENT, ESCAPE_CHAR, CONTENT);
result.shouldBeToken(4, ESCAPE_CHAR, "\\");
result.shouldBeToken(5, CONTENT, "{{bar}} ");
result.shouldBeToken(6, ESCAPE_CHAR, "\\");
result.shouldBeToken(7, CONTENT, "{{baz}}");
}
/**
* supports escaping a triple stash
*/
public void testEscapingTripleStash() {
TokenizerResult result = tokenize("{{foo}} \\{{{bar}}} {{baz}}");
result.shouldMatchTokenTypes(OPEN, ID, CLOSE, WHITE_SPACE, ESCAPE_CHAR, CONTENT, OPEN, ID, CLOSE);
result.shouldBeToken(5, CONTENT, "{{{bar}}} ");
}
/**
* supports escaping escape character
*/
public void testEscapingEscapeCharacter() {
TokenizerResult result = tokenize("{{foo}} \\\\{{bar}} {{baz}}");
result.shouldMatchTokenTypes(OPEN, ID, CLOSE, CONTENT, OPEN, ID, CLOSE, WHITE_SPACE, OPEN, ID, CLOSE);
result.shouldBeToken(3, CONTENT, " \\\\");
result.shouldBeToken(5, ID, "bar");
}
/**
* supports escaping multiple escape characters
*/
public void testEscapingMultipleEscapeCharacter() {
TokenizerResult result = tokenize("{{foo}} \\\\{{bar}} \\\\{{baz}}");
result.shouldMatchTokenTypes(OPEN, ID, CLOSE, CONTENT, OPEN, ID, CLOSE, CONTENT, OPEN, ID, CLOSE);
result.shouldBeToken(3, CONTENT, " \\\\");
result.shouldBeToken(5, ID, "bar");
result.shouldBeToken(7, CONTENT, " \\\\");
result.shouldBeToken(9, ID, "baz");
}
/**
* supports escaped mustaches after escaped escape characters
*/
public void testMixedEscapedDelimitersAndEscapedEscapes() {
TokenizerResult result = tokenize("{{foo}} \\\\{{bar}} \\{{baz}}");
result.shouldMatchTokenTypes(OPEN, ID, CLOSE, CONTENT, OPEN, ID, CLOSE, WHITE_SPACE, ESCAPE_CHAR, CONTENT);
result.shouldBeToken(3, CONTENT, " \\\\");
result.shouldBeToken(4, OPEN, "{{");
result.shouldBeToken(5, ID, "bar");
result.shouldBeToken(9, CONTENT, "{{baz}}");
}
/**
* supports escaped escape characters after escaped mustaches
*/
public void testEscapedEscapeCharactersAfterEscapedStaches() {
TokenizerResult result = tokenize("{{foo}} \\{{bar}} \\\\{{baz}}");
result.shouldMatchTokenTypes(OPEN, ID, CLOSE, WHITE_SPACE, ESCAPE_CHAR, CONTENT, CONTENT, OPEN, ID, CLOSE);
result.shouldBeToken(4, ESCAPE_CHAR, "\\");
result.shouldBeToken(5, CONTENT, "{{bar}} ");
result.shouldBeToken(6, CONTENT, "\\\\");
result.shouldBeToken(7, OPEN, "{{");
result.shouldBeToken(8, ID, "baz");
}
/**
* supports escaped escape character on a triple stash
*/
public void testEscapedEscapeCharOnTripleStash() {
TokenizerResult result = tokenize("{{foo}} \\\\{{{bar}}} {{baz}}");
result.shouldMatchTokenTypes(OPEN, ID, CLOSE, CONTENT, OPEN_UNESCAPED, ID, CLOSE_UNESCAPED, WHITE_SPACE, OPEN, ID, CLOSE);
result.shouldBeToken(3, CONTENT, " \\\\");
result.shouldBeToken(5, ID, "bar");
}
/**
* tokenizes a simple path
*/
public void testSimplePath() {
TokenizerResult result = tokenize("{{foo/bar}}");
result.shouldMatchTokenTypes(OPEN, ID, SEP, ID, CLOSE);
}
/**
* allows dot notation
*/
public void testAllowDotNotation() {
TokenizerResult result = tokenize("{{foo.bar}}");
result.shouldMatchTokenTypes(OPEN, ID, SEP, ID, CLOSE);
}
/**
* allows path literals with []
*/
public void testAllowPathLiteralsWithSquareBrackets() {
TokenizerResult result = tokenize("{{foo.[bar]}}");
result.shouldMatchTokenTypes(OPEN, ID, SEP, ID, CLOSE);
}
/**
* allows multiple path literals on a line with []
*/
public void testAllowsPathLiteralsOnLineWithSquareBrackets() {
TokenizerResult result = tokenize("{{foo.[bar]}}{{foo.[baz]}}");
result.shouldMatchTokenTypes(OPEN, ID, SEP, ID, CLOSE, OPEN, ID, SEP, ID, CLOSE);
}
/**
* tokenizes {{.}} as OPEN ID CLOSE
*/
public void testTokenizesOpenDotClose() {
TokenizerResult result = tokenize("{{.}}");
result.shouldMatchTokenTypes(OPEN, ID, CLOSE);
}
/**
* tokenizes a path as 'OPEN (ID SEP)* ID CLOSE'
*/
public void testTokenizeDoubleDotPath() {
TokenizerResult result = tokenize("{{../foo/bar}}");
result.shouldMatchTokenTypes(OPEN, ID, SEP, ID, SEP, ID, CLOSE);
result.shouldBeToken(1, ID, "..");
}
/**
* tokenizes a path with .. as a parent path
*/
public void testTokenizeDoubleDotPathAsParent() {
TokenizerResult result = tokenize("{{../foo.bar}}");
result.shouldMatchTokenTypes(OPEN, ID, SEP, ID, SEP, ID, CLOSE);
result.shouldBeToken(1, ID, "..");
}
/**
* tokenizes a path with this/foo as OPEN ID SEP ID CLOSE
*/
public void testTokenizesSlashAsSep() {
TokenizerResult result = tokenize("{{this/foo}}");
result.shouldMatchTokenTypes(OPEN, ID, SEP, ID, CLOSE);
result.shouldBeToken(1, ID, "this");
result.shouldBeToken(3, ID, "foo");
}
/**
* tokenizes a simple mustache with spaces as 'OPEN ID CLOSE'
*/
public void testTokenizeSimpleMustacheWithSpaces() {
TokenizerResult result = tokenize("{{ foo }}");
result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, CLOSE);
result.shouldBeToken(2, ID, "foo");
}
/**
* tokenizes a simple mustache with line breaks as 'OPEN ID ID CLOSE'
*/
public void testTokenizeSimpleMustacheWithLineBreaks() {
TokenizerResult result = tokenize("{{ foo \n bar }}");
result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, ID, WHITE_SPACE, CLOSE);
result.shouldBeToken(2, ID, "foo");
}
/**
* tokenizes raw content as 'CONTENT'
*/
public void testTokenizeRawContent() {
TokenizerResult result = tokenize("foo {{ bar }} baz");
result.shouldMatchTokenTypes(CONTENT, OPEN, WHITE_SPACE, ID, WHITE_SPACE, CLOSE, CONTENT);
result.shouldBeToken(0, CONTENT, "foo ");
result.shouldBeToken(6, CONTENT, " baz");
}
/**
* tokenizes a partial as 'OPEN_PARTIAL ID CLOSE'
*/
public void testTokenizePartial() {
TokenizerResult result = tokenize("{{> foo}}");
result.shouldMatchTokenTypes(OPEN_PARTIAL, WHITE_SPACE, ID, CLOSE);
}
/**
* tokenizes a partial with context as 'OPEN_PARTIAL ID ID CLOSE'
*/
public void testTokenizePartialWithMultipleIds() {
TokenizerResult result = tokenize("{{> foo bar }}");
result.shouldMatchTokenTypes(OPEN_PARTIAL, WHITE_SPACE, ID, WHITE_SPACE, ID, WHITE_SPACE, CLOSE);
}
/**
* tokenizes a partial without spaces as 'OPEN_PARTIAL ID CLOSE'
*/
public void testTokenizePartialWithoutSpaces() {
TokenizerResult result = tokenize("{{>foo}}");
result.shouldMatchTokenTypes(OPEN_PARTIAL, ID, CLOSE);
}
/**
* tokenizes a partial space at the end as 'OPEN_PARTIAL ID CLOSE'
*/
public void testTokenizePartialWithTrailingSpaces() {
TokenizerResult result = tokenize("{{>foo }}");
result.shouldMatchTokenTypes(OPEN_PARTIAL, ID, WHITE_SPACE, CLOSE);
}
/**
* tokenizes partial block declarations
*/
public void testTokenizePartialBlockDeclarations() {
TokenizerResult result = tokenize("{{#> foo}}");
result.shouldMatchTokenTypes(OPEN_PARTIAL_BLOCK, WHITE_SPACE, ID, CLOSE);
}
/**
* tokenizes a comment as 'COMMENT'
*/
public void testTokenizeComment() {
TokenizerResult result = tokenize("foo {{! this is a comment }} bar {{ baz }}");
result.shouldMatchTokenTypes(CONTENT, COMMENT, CONTENT, OPEN, WHITE_SPACE, ID, WHITE_SPACE, CLOSE);
// Note that we differ from tokenizer_spec.rb since it is convenient to include the comment mustaches into the comment token for the IDE
result.shouldBeToken(1, COMMENT, "{{! this is a comment }}");
}
/**
* tokenizes a block comment as 'COMMENT'
*/
public void testTokenizeBlockComment() {
TokenizerResult result = tokenize("foo {{!-- this is a {{comment}} --}} bar {{ baz }}");
result.shouldMatchTokenTypes(CONTENT, COMMENT, CONTENT, OPEN, WHITE_SPACE, ID, WHITE_SPACE, CLOSE);
result.shouldBeToken(1, COMMENT, "{{!-- this is a {{comment}} --}}");
}
/**
* tokenizes a block comment with whitespace as 'COMMENT'
*/
public void testTokenizeBlockCommentWithWhitespace() {
TokenizerResult result = tokenize("foo {{!-- this is a\n{{comment}}\n--}} bar {{ baz }}");
result.shouldMatchTokenTypes(CONTENT, COMMENT, CONTENT, OPEN, WHITE_SPACE, ID, WHITE_SPACE, CLOSE);
result.shouldBeToken(1, COMMENT, "{{!-- this is a\n{{comment}}\n--}}");
}
/**
* tokenizes open and closing blocks as 'OPEN_BLOCK ID CLOSE ... OPEN_ENDBLOCK ID CLOSE'
*/
public void testTokenizeOpenAndCloseBlock() {
TokenizerResult result = tokenize("{{#foo}}content{{/foo}}");
result.shouldMatchTokenTypes(OPEN_BLOCK, ID, CLOSE, CONTENT, OPEN_ENDBLOCK, ID, CLOSE);
}
/**
* tokenizes inverse sections as 'OPEN_INVERSE CLOSE'
*/
public void testTokenizeInverseSection() {
tokenize("{{^}}").shouldMatchTokenTypes(OPEN_INVERSE, CLOSE);
// NOTE: we lex "else"-type inverses in a non-standard was to allow us to highlight it properly
tokenize("{{else}}").shouldMatchTokenTypes(OPEN, ELSE, CLOSE);
tokenize("{{ else }}").shouldMatchTokenTypes(OPEN, WHITE_SPACE, ELSE, WHITE_SPACE, CLOSE);
}
/**
* tokenizes inverse sections with ID as 'OPEN_INVERSE ID CLOSE'
*/
public void testTokenizeInverseSectionWithId() {
TokenizerResult result = tokenize("{{^foo}}");
result.shouldMatchTokenTypes(OPEN_INVERSE, ID, CLOSE);
result.shouldBeToken(1, ID, "foo");
}
/**
* tokenizes inverse sections with ID and spaces as 'OPEN_INVERSE ID CLOSE'
*/
public void testTokenizeInverseSectionWithWhitespace() {
TokenizerResult result = tokenize("{{^ foo }}");
result.shouldMatchTokenTypes(OPEN_INVERSE, WHITE_SPACE, ID, WHITE_SPACE, CLOSE);
result.shouldBeToken(2, ID, "foo");
}
/**
* tokenizes mustaches with params as 'OPEN ID ID ID CLOSE'
*/
public void testTokenizeMustacheWithParams() {
TokenizerResult result = tokenize("{{ foo bar baz }}");
result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, ID, WHITE_SPACE, ID, WHITE_SPACE, CLOSE);
result.shouldBeToken(2, ID, "foo");
result.shouldBeToken(4, ID, "bar");
result.shouldBeToken(6, ID, "baz");
}
/**
* tokenizes mustaches with String params as 'OPEN ID ID STRING CLOSE'
*/
public void testTokenizeMustacheWithStringParams() {
TokenizerResult result = tokenize("{{ foo bar \"baz\" }}");
result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, ID, WHITE_SPACE, STRING, WHITE_SPACE, CLOSE);
result.shouldBeToken(6, STRING, "\"baz\"");
}
/**
* tokenizes mustaches with String params using single quotes as 'OPEN ID ID STRING CLOSE'
*/
public void testTokenizeMustachesWithStringParamsUsingSingleQuotes() {
TokenizerResult result = tokenize("{{ foo bar 'baz' }}");
result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, ID, WHITE_SPACE, STRING, WHITE_SPACE, CLOSE);
result.shouldBeToken(6, STRING, "'baz'");
}
/**
* tokenizes String params with spaces inside as 'STRING'
*/
public void testTokenizeMustacheWithStringParamsWithSpaces() {
TokenizerResult result = tokenize("{{ foo bar \"baz bat\" }}");
result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, ID, WHITE_SPACE, STRING, WHITE_SPACE, CLOSE);
result.shouldBeToken(6, STRING, "\"baz bat\"");
}
/**
* tokenizes String params using single quotes with escapes quotes as 'STRING'
*/
public void testTokenizeStringParamsUsingSingleQuotesWithEscapedQuotes() {
TokenizerResult result = tokenize("{{ foo 'bar\\'baz' }}");
result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, STRING, WHITE_SPACE, CLOSE);
result.shouldBeToken(4, STRING, "'bar\\'baz'");
}
/**
* tokenizes String params with escapes quotes as 'STRING'
* {{ foo "bar\"baz" }}
*/
public void testTokenizeMustacheWithStringParamWithEscapeQuotes() {
TokenizerResult result = tokenize("{{ foo \"bar\\\"baz\" }}");
result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, STRING, WHITE_SPACE, CLOSE);
result.shouldBeToken(4, STRING, "\"bar\\\"baz\"");
}
/**
* tokenizes numbers
*/
public void testTokenizesNumbers() {
TokenizerResult result = tokenize("{{ foo 1 }}");
result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, NUMBER, WHITE_SPACE, CLOSE);
result.shouldBeToken(4, NUMBER, "1");
result = tokenize("{{ foo -1 }}");
result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, NUMBER, WHITE_SPACE, CLOSE);
result.shouldBeToken(4, NUMBER, "-1");
}
/**
* tokenizes booleans
*/
public void testTokenizeBooleans() {
TokenizerResult result = tokenize("{{ foo true }}");
result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, BOOLEAN, WHITE_SPACE, CLOSE);
result.shouldBeToken(4, BOOLEAN, "true");
result = tokenize("{{ foo false }}");
result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, BOOLEAN, WHITE_SPACE, CLOSE);
result.shouldBeToken(4, BOOLEAN, "false");
}
/**
* tokenizes hash arguments
*/
public void testTokenizeHashArguments() {
TokenizerResult result = tokenize("{{ foo bar=baz }}");
result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, ID, EQUALS, ID, WHITE_SPACE, CLOSE);
result = tokenize("{{ foo bar baz=bat }}");
result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, ID, WHITE_SPACE, ID, EQUALS, ID, WHITE_SPACE, CLOSE);
result = tokenize("{{ foo bar baz=1 }}");
result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, ID, WHITE_SPACE, ID, EQUALS, NUMBER, WHITE_SPACE, CLOSE);
result = tokenize("{{ foo bar baz=true }}");
result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, ID, WHITE_SPACE, ID, EQUALS, BOOLEAN, WHITE_SPACE, CLOSE);
result = tokenize("{{ foo bar baz=false }}");
result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, ID, WHITE_SPACE, ID, EQUALS, BOOLEAN, WHITE_SPACE, CLOSE);
result = tokenize("{{ foo bar\n baz=bat }}");
result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, ID, WHITE_SPACE, ID, EQUALS, ID, WHITE_SPACE, CLOSE);
result = tokenize("{{ foo bar baz=\"bat\" }}");
result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, ID, WHITE_SPACE, ID, EQUALS, STRING, WHITE_SPACE, CLOSE);
result = tokenize("{{ foo bar baz=\"bat\" bam=wot }}");
result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, ID, WHITE_SPACE, ID, EQUALS, STRING, WHITE_SPACE, ID, EQUALS, ID,
WHITE_SPACE, CLOSE);
result = tokenize("{{ foo omg bar=\"baz\" bat=\"bam\" }}");
result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, ID, WHITE_SPACE, ID, EQUALS, STRING, WHITE_SPACE, ID, EQUALS, STRING,
WHITE_SPACE, CLOSE);
result.shouldBeToken(4, ID, "omg");
}
/**
* tokenizes special @ identifiers
*/
public void testSpecialDataIdentifiers() {
TokenizerResult result = tokenize("{{ @foo }}");
result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, DATA_PREFIX, ID, WHITE_SPACE, CLOSE);
result.shouldBeToken(3, ID, "foo");
result = tokenize("{{ foo @bar }}");
result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, DATA_PREFIX, ID, WHITE_SPACE, CLOSE);
result.shouldBeToken(5, ID, "bar");
result = tokenize("{{ foo bar=@baz }}");
result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, ID, EQUALS, DATA_PREFIX, ID, WHITE_SPACE, CLOSE);
result.shouldBeToken(7, ID, "baz");
}
/**
* tokenizes subexpressions
*/
public void testTokenizesSubexpressions() {
TokenizerResult result = tokenize("{{foo (bar)}}");
result.shouldMatchTokenTypes(OPEN, ID, WHITE_SPACE, OPEN_SEXPR, ID, CLOSE_SEXPR, CLOSE);
result.shouldBeToken(1, ID, "foo");
result.shouldBeToken(4, ID, "bar");
result = tokenize("{{foo (a-x b-y)}}");
result.shouldMatchTokenTypes(OPEN, ID, WHITE_SPACE, OPEN_SEXPR, ID, WHITE_SPACE, ID, CLOSE_SEXPR, CLOSE);
result.shouldBeToken(1, ID, "foo");
result.shouldBeToken(4, ID, "a-x");
result.shouldBeToken(6, ID, "b-y");
}
/**
* tokenizes nested subexpressions
*/
public void testTokenizesNestedSubexpressions() {
TokenizerResult result = tokenize("{{foo (bar (lol rofl)) (baz)}}");
result.shouldMatchTokenTypes(OPEN, ID, WHITE_SPACE, OPEN_SEXPR, ID, WHITE_SPACE, OPEN_SEXPR, ID, WHITE_SPACE, ID, CLOSE_SEXPR, CLOSE_SEXPR, WHITE_SPACE, OPEN_SEXPR, ID, CLOSE_SEXPR, CLOSE);
result.shouldBeToken(4, ID, "bar");
result.shouldBeToken(7, ID, "lol");
result.shouldBeToken(9, ID, "rofl");
result.shouldBeToken(14, ID, "baz");
}
/**
* tokenizes nested subexpressions: literals
*/
public void testTokenizesNestedSubexpressionLiterals() {
TokenizerResult result = tokenize("{{foo (bar (lol true) false) (baz 1) (blah 'b') (blorg \"c\")}}");
result.shouldMatchTokenTypes(OPEN, ID, WHITE_SPACE, OPEN_SEXPR, ID, WHITE_SPACE, OPEN_SEXPR, ID, WHITE_SPACE, BOOLEAN, CLOSE_SEXPR, WHITE_SPACE, BOOLEAN, CLOSE_SEXPR, WHITE_SPACE, OPEN_SEXPR, ID, WHITE_SPACE, NUMBER, CLOSE_SEXPR, WHITE_SPACE, OPEN_SEXPR, ID, WHITE_SPACE, STRING, CLOSE_SEXPR, WHITE_SPACE, OPEN_SEXPR, ID, WHITE_SPACE, STRING, CLOSE_SEXPR, CLOSE);
}
/**
* tokenizes block params
*/
public void testTokenizesBlockParams() {
TokenizerResult result = tokenize("{{#foo as |bar|}}");
result.shouldMatchTokenTypes(OPEN_BLOCK, ID, WHITE_SPACE, OPEN_BLOCK_PARAMS, ID, CLOSE_BLOCK_PARAMS, CLOSE);
result = tokenize("{{#foo as |bar baz|}}");
result.shouldMatchTokenTypes(OPEN_BLOCK, ID, WHITE_SPACE, OPEN_BLOCK_PARAMS, ID, WHITE_SPACE, ID, CLOSE_BLOCK_PARAMS, CLOSE);
result = tokenize("{{#foo as | bar baz |}}");
result.shouldMatchTokenTypes(OPEN_BLOCK, ID, WHITE_SPACE, OPEN_BLOCK_PARAMS, WHITE_SPACE, ID, WHITE_SPACE, ID, WHITE_SPACE, CLOSE_BLOCK_PARAMS, CLOSE);
result = tokenize("{{#foo as as | bar baz |}}");
result.shouldMatchTokenTypes(OPEN_BLOCK, ID, WHITE_SPACE, ID, WHITE_SPACE, OPEN_BLOCK_PARAMS, WHITE_SPACE, ID, WHITE_SPACE, ID, WHITE_SPACE, CLOSE_BLOCK_PARAMS, CLOSE);
result = tokenize("{{else foo as |bar baz|}}");
result.shouldMatchTokenTypes(OPEN, ELSE, WHITE_SPACE, ID, WHITE_SPACE, OPEN_BLOCK_PARAMS, ID, WHITE_SPACE, ID, CLOSE_BLOCK_PARAMS, CLOSE);
}
/**
* tokenizes directives
*/
public void testTokenizeDirectives() {
TokenizerResult result = tokenize("{{#*foo}}content{{/foo}}");
result.shouldMatchTokenTypes(OPEN_BLOCK, ID, CLOSE, CONTENT, OPEN_ENDBLOCK, ID, CLOSE);
result = tokenize("{{*foo}}");
result.shouldMatchTokenTypes(OPEN, ID, CLOSE);
}
}