| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 | <?php
/*
 * This file is part of Twig.
 *
 * (c) Fabien Potencier
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
class Twig_Tests_LexerTest extends PHPUnit_Framework_TestCase
{
    public function testNameLabelForTag()
    {
        $template = '{% ☃ %}';
        $lexer = new Twig_Lexer(new Twig_Environment());
        $stream = $lexer->tokenize($template);
        $stream->expect(Twig_Token::BLOCK_START_TYPE);
        $this->assertSame('☃', $stream->expect(Twig_Token::NAME_TYPE)->getValue());
    }
    public function testNameLabelForFunction()
    {
        $template = '{{ ☃() }}';
        $lexer = new Twig_Lexer(new Twig_Environment());
        $stream = $lexer->tokenize($template);
        $stream->expect(Twig_Token::VAR_START_TYPE);
        $this->assertSame('☃', $stream->expect(Twig_Token::NAME_TYPE)->getValue());
    }
    public function testBracketsNesting()
    {
        $template = '{{ {"a":{"b":"c"}} }}';
        $this->assertEquals(2, $this->countToken($template, Twig_Token::PUNCTUATION_TYPE, '{'));
        $this->assertEquals(2, $this->countToken($template, Twig_Token::PUNCTUATION_TYPE, '}'));
    }
    protected function countToken($template, $type, $value = null)
    {
        $lexer = new Twig_Lexer(new Twig_Environment());
        $stream = $lexer->tokenize($template);
        $count = 0;
        $tokens = array();
        while (!$stream->isEOF()) {
            $token = $stream->next();
            if ($type === $token->getType()) {
                if (null === $value || $value === $token->getValue()) {
                    ++$count;
                }
            }
        }
        return $count;
    }
    public function testLineDirective()
    {
        $template = "foo\n"
            . "bar\n"
            . "{% line 10 %}\n"
            . "{{\n"
            . "baz\n"
            . "}}\n";
        $lexer = new Twig_Lexer(new Twig_Environment());
        $stream = $lexer->tokenize($template);
        // foo\nbar\n
        $this->assertSame(1, $stream->expect(Twig_Token::TEXT_TYPE)->getLine());
        // \n (after {% line %})
        $this->assertSame(10, $stream->expect(Twig_Token::TEXT_TYPE)->getLine());
        // {{
        $this->assertSame(11, $stream->expect(Twig_Token::VAR_START_TYPE)->getLine());
        // baz
        $this->assertSame(12, $stream->expect(Twig_Token::NAME_TYPE)->getLine());
    }
    public function testLineDirectiveInline()
    {
        $template = "foo\n"
            . "bar{% line 10 %}{{\n"
            . "baz\n"
            . "}}\n";
        $lexer = new Twig_Lexer(new Twig_Environment());
        $stream = $lexer->tokenize($template);
        // foo\nbar
        $this->assertSame(1, $stream->expect(Twig_Token::TEXT_TYPE)->getLine());
        // {{
        $this->assertSame(10, $stream->expect(Twig_Token::VAR_START_TYPE)->getLine());
        // baz
        $this->assertSame(11, $stream->expect(Twig_Token::NAME_TYPE)->getLine());
    }
    public function testLongComments()
    {
        $template = '{# '.str_repeat('*', 100000).' #}';
        $lexer = new Twig_Lexer(new Twig_Environment());
        $lexer->tokenize($template);
        // should not throw an exception
    }
    public function testLongRaw()
    {
        $template = '{% raw %}'.str_repeat('*', 100000).'{% endraw %}';
        $lexer = new Twig_Lexer(new Twig_Environment());
        $stream = $lexer->tokenize($template);
        // should not throw an exception
    }
    public function testLongVar()
    {
        $template = '{{ '.str_repeat('x', 100000).' }}';
        $lexer = new Twig_Lexer(new Twig_Environment());
        $stream = $lexer->tokenize($template);
        // should not throw an exception
    }
    public function testLongBlock()
    {
        $template = '{% '.str_repeat('x', 100000).' %}';
        $lexer = new Twig_Lexer(new Twig_Environment());
        $stream = $lexer->tokenize($template);
        // should not throw an exception
    }
    public function testBigNumbers()
    {
        $template = '{{ 922337203685477580700 }}';
        $lexer = new Twig_Lexer(new Twig_Environment());
        $stream = $lexer->tokenize($template);
        $node = $stream->next();
        $node = $stream->next();
        $this->assertEquals(922337203685477580700, $node->getValue());
    }
    public function testString()
    {
        $template = 'foo {{ "bar #{ baz + 1 }" }}';
        $lexer = new Twig_Lexer(new Twig_Environment());
        $stream = $lexer->tokenize($template);
        $stream->expect(Twig_Token::TEXT_TYPE, 'foo ');
        $stream->expect(Twig_Token::VAR_START_TYPE);
        $stream->expect(Twig_Token::STRING_TYPE, 'bar ');
        $stream->expect(Twig_Token::INTERPOLATION_START_TYPE);
        $stream->expect(Twig_Token::NAME_TYPE, 'baz');
        $stream->expect(Twig_Token::OPERATOR_TYPE, '+');
        $stream->expect(Twig_Token::NUMBER_TYPE, '1');
        $stream->expect(Twig_Token::INTERPOLATION_END_TYPE);
        $stream->expect(Twig_Token::VAR_END_TYPE);
    }
    public function testStringWithEscapedInterpolation()
    {
        $template = '{{ "bar \#{baz+1}" }}';
        $lexer = new Twig_Lexer(new Twig_Environment());
        $stream = $lexer->tokenize($template);
        $stream->expect(Twig_Token::VAR_START_TYPE);
        $stream->expect(Twig_Token::STRING_TYPE, 'bar #{baz+1}');
        $stream->expect(Twig_Token::VAR_END_TYPE);
    }
    public function testStringWithHash()
    {
        $template = '{{ "bar # baz" }}';
        $lexer = new Twig_Lexer(new Twig_Environment());
        $stream = $lexer->tokenize($template);
        $stream->expect(Twig_Token::VAR_START_TYPE);
        $stream->expect(Twig_Token::STRING_TYPE, 'bar # baz');
        $stream->expect(Twig_Token::VAR_END_TYPE);
    }
    /**
     * @expectedException Twig_Error_Syntax
     * @expectedExceptionMessage Unclosed """
     */
    public function testStringWithUnterminatedInterpolation()
    {
        $template = '{{ "bar #{x" }}';
        $lexer = new Twig_Lexer(new Twig_Environment());
        $stream = $lexer->tokenize($template);
    }
    public function testStringWithNestedInterpolations()
    {
        $template = '{{ "bar #{ "foo#{bar}" }" }}';
        $lexer = new Twig_Lexer(new Twig_Environment());
        $stream = $lexer->tokenize($template);
        $stream->expect(Twig_Token::VAR_START_TYPE);
        $stream->expect(Twig_Token::STRING_TYPE, 'bar ');
        $stream->expect(Twig_Token::INTERPOLATION_START_TYPE);
        $stream->expect(Twig_Token::STRING_TYPE, 'foo');
        $stream->expect(Twig_Token::INTERPOLATION_START_TYPE);
        $stream->expect(Twig_Token::NAME_TYPE, 'bar');
        $stream->expect(Twig_Token::INTERPOLATION_END_TYPE);
        $stream->expect(Twig_Token::INTERPOLATION_END_TYPE);
        $stream->expect(Twig_Token::VAR_END_TYPE);
    }
    public function testStringWithNestedInterpolationsInBlock()
    {
        $template = '{% foo "bar #{ "foo#{bar}" }" %}';
        $lexer = new Twig_Lexer(new Twig_Environment());
        $stream = $lexer->tokenize($template);
        $stream->expect(Twig_Token::BLOCK_START_TYPE);
        $stream->expect(Twig_Token::NAME_TYPE, 'foo');
        $stream->expect(Twig_Token::STRING_TYPE, 'bar ');
        $stream->expect(Twig_Token::INTERPOLATION_START_TYPE);
        $stream->expect(Twig_Token::STRING_TYPE, 'foo');
        $stream->expect(Twig_Token::INTERPOLATION_START_TYPE);
        $stream->expect(Twig_Token::NAME_TYPE, 'bar');
        $stream->expect(Twig_Token::INTERPOLATION_END_TYPE);
        $stream->expect(Twig_Token::INTERPOLATION_END_TYPE);
        $stream->expect(Twig_Token::BLOCK_END_TYPE);
    }
    public function testOperatorEndingWithALetterAtTheEndOfALine()
    {
        $template = "{{ 1 and\n0}}";
        $lexer = new Twig_Lexer(new Twig_Environment());
        $stream = $lexer->tokenize($template);
        $stream->expect(Twig_Token::VAR_START_TYPE);
        $stream->expect(Twig_Token::NUMBER_TYPE, 1);
        $stream->expect(Twig_Token::OPERATOR_TYPE, 'and');
    }
}
 |