<?php
/**
 * @copyright (c) Kufer Software GmbH, Oderstraße 7, D-84453 Mühldorf
 */

use Kufer\Web\Classes\Scripting3\Parser;

/**
 * Generated by PHPUnit_SkeletonGenerator on 2020-07-17 at 16:05:30.
 */
class easyhtmlscript3Test extends \PHPUnit\Framework\TestCase
{
  protected $object;

  /**
   * Sets up the fixture, for example, opens a network connection.
   * This method is called before a test is executed.
   */
  public function setUp(): void
  {
    if (!\defined('EASYHTMLSCRIPT3_DONT_ERROR_LOG')) {
      \define('EASYHTMLSCRIPT3_DONT_ERROR_LOG', true);
    }
  }

  /**
   * Tears down the fixture, for example, closes a network connection.
   * This method is called after a test is executed.
   */
  public function tearDown(): void
  {
  }

  /**
   * @covers Parser::parseAll
   * @test
   */
  public function parse_TestText()
  {
    $parser = new Parser('Hello, World');
    $this->assertEquals('Hello, World', $parser->execute(array(), array()));

    $parser = new Parser('Hello,\' World');
    $this->assertEquals('Hello,\' World', $parser->execute(array(), array()));

    $parser = new Parser('Hello,\\\' World');
    $this->assertEquals('Hello,\\\' World', $parser->execute(array(), array()));

    $parser = new Parser('Hello," World');
    $this->assertEquals('Hello," World', $parser->execute(array(), array()));
  }

  /**
   * @covers ExprVar::toPHP
   * @test
   */
  public function parse_TestVariable()
  {
    $parser = new Parser('{%var%}');

    $this->assertEquals('Hello, World', $parser->execute(array('var' => 'Hello, World'), array()));

    $parser = new Parser('{%Ärray%}');

    $this->assertEquals('Hello, World', $parser->execute(array('Ärray' => 'Hello, World'), array()));
  }

  /**
   * @covers ExprIf::toPHP
   * @test
   */
  public function parse_TestIfEquals()
  {
    $parser = new Parser('(§IF§) ("text" == "text") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) ("text" == "notext") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array(), array()));
  }

  /**
   * @covers ExprIf::toPHP
   * @test
   */
  public function parse_TestIfEqualsAlternativeValueBraces()
  {
    $parser = new Parser('(§IF§) ("text" == \'text\') {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) (\'text\' == "notext") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array(), array()));
  }

  /**
   * @covers ExprIf::toPHP
   * @test
   */
  public function parse_TestIfEqualsSpace()
  {
    $parser = new Parser('(§IF§) ("text" == "text") {TRUE}                                  else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser("(§IF§) (\"text\" == \"text\") {TRUE}   \r\n    else {FALSE}");

    $this->assertEquals('TRUE', $parser->execute(array(), array()));
  }

  /**
   * @covers ExprIf::toPHP
   * @test
   */
  public function parse_TestIfEqualsNumbers()
  {
    $parser = new Parser('(§IF§) ("0,00" == "0.0") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) ("0" == "1") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) ("1,25" == "1.25") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) ("1000" == "1.000") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array(), array()));
  }

  /**
   * @covers ExprIf::toPHP
   * @test
   */
  public function parse_TestIfNumbersNotEqualsText()
  {
    $parser = new Parser('(§IF§) ("0" == "text") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) ("0" == "") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array(), array()));
  }

  /**
   * @covers ExprIf::toPHP
   * @test
   */
  public function parse_TestIfNotEqualsTrue()
  {
    $parser = new Parser('(§IF§) ("0,00" != "1.0") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) ("0,00" != "text") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) ("notext" != "text") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) ("notext" != "") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));
  }

  /**
   * @covers ExprIf::toPHP
   * @test
   */
  public function parse_TestIfNotEqualsFalse()
  {
    $parser = new Parser('(§IF§) ("0" != "0") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) ("text" != "text") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) ("" != "") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array(), array()));
  }

  /**
   * @covers ExprIf::toPHP
   * @test
   */
  public function parse_TestIfEqualsHTML()
  {
    $parser = new Parser('(§IF§) ("&uuml;" == "ü") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) ("&ouml;" == "ö") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));
  }

  /**
   * @covers ExprIf::toPHP
   * @test
   */
  public function parse_TestElseIfDifferentTokens()
  {
    $parser = new Parser('(§IF§) ("{%var%}" != "1") {TRUE} else if ("{%var%}" == "1") {FALSE} else {UNKNOWN}');

    $this->assertEquals('FALSE', $parser->execute(array('var' => '1'), array()));

    $parser = new Parser('(§IF§) ("{%var%}" != "1") {TRUE} else (§IF§) ("{%var%}" == "1") {FALSE} else {UNKNOWN}');

    $this->assertEquals('FALSE', $parser->execute(array('var' => '1'), array()));

    $parser = new Parser('(§IF§) ("{%var%}" != "1") {TRUE} ELSE (§IF§) ("{%var%}" == "1") {FALSE} ELSE {UNKNOWN}');

    $this->assertEquals('FALSE', $parser->execute(array('var' => '1'), array()));

    $parser = new Parser('(§IF§) ("{%var%}" != "1") {TRUE} else If ("{%var%}" == "1") {FALSE} else {UNKNOWN}');

    $this->assertEquals('FALSE', $parser->execute(array('var' => '1'), array()));

    $parser = new Parser('(§IF§) ("{%var%}" != "1") {TRUE} elseif ("{%var%}" == "1") {FALSE} else {UNKNOWN}');

    $this->assertEquals('FALSE', $parser->execute(array('var' => '1'), array()));
  }

  /**
   * @covers ExprForeach::toPHP
   * @test
   */
  public function parse_TestOldForeachWithVariable()
  {
    $parser = new Parser('(§FOREACH:ary§){%hello%}(§/ENDFOREACH:ary§)');

    $this->assertEquals('world', $parser->execute(array(
          'hello' => 'world',
        ), array(array(
          'ary' => array(array('name' => 0)),
        ))));
  }

  /**
   * @covers ExprForeach::toPHP
   * @test
   */
  public function parse_TestOldForeach()
  {
    // Danger {.*} is an edge case conflicting

    $parser = new Parser('(§FOREACH:ary§){name}(§/ENDFOREACH:ary§)');

    $this->assertEquals('0123456789', $parser->execute(array(), array(array(
      'ary' => array(array('name' => 0),
        array('name' => 1),
        array('name' => 2),
        array('name' => 3),
        array('name' => 4),
        array('name' => 5),
        array('name' => 6),
        array('name' => 7),
        array('name' => 8),
        array('name' => 9), ),
    ))));

    $this->assertEquals('0912345678', $parser->execute(array(), array(array(
      'ary' => array(array('name' => 0),
        array('name' => 9),
        array('name' => 1),
        array('name' => 2),
        array('name' => 3),
        array('name' => 4),
        array('name' => 5),
        array('name' => 6),
        array('name' => 7),
        array('name' => 8), ),
    ))));
  }

  /**
   * @covers ExprForeach::toPHP
   * @test
   */
  public function parse_TestForeach()
  {
    $parser = new Parser('(§FOREACH:ary§) {{name}}');

    $this->assertEquals('0123456789', $parser->execute(array(), array(array(
      'ary' => array(array('name' => 0),
        array('name' => 1),
        array('name' => 2),
        array('name' => 3),
        array('name' => 4),
        array('name' => 5),
        array('name' => 6),
        array('name' => 7),
        array('name' => 8),
        array('name' => 9), ),
    ))));

    $this->assertEquals('0912345678', $parser->execute(array(), array(array(
      'ary' => array(array('name' => 0),
        array('name' => 9),
        array('name' => 1),
        array('name' => 2),
        array('name' => 3),
        array('name' => 4),
        array('name' => 5),
        array('name' => 6),
        array('name' => 7),
        array('name' => 8), ),
    ))));
  }

  /**
   * @covers ExprForeach::toPHP
   * @test
   */
  public function parse_TestForeachEqualName()
  {
    $parser = new Parser('(§FOREACH:ary§) {{ary}}');

    $this->assertEquals('0912345678', $parser->execute(array(), array(array(
      'ary' => array(array('ary' => 0),
        array('ary' => 9),
        array('ary' => 1),
        array('ary' => 2),
        array('ary' => 3),
        array('ary' => 4),
        array('ary' => 5),
        array('ary' => 6),
        array('ary' => 7),
        array('ary' => 8), ),
    ))));
  }

  /**
   * @covers ExprForeach::toPHP
   * @test
   */
  public function parse_TestTwoForeachPriorityEqualName()
  {
    $parser = new Parser('(§FOREACH:ary0§) {(§FOREACH:ary1§) {{ary}}}');

    $this->assertEquals(\str_repeat('9876543210', 10), $parser->execute(array(), array(array(
      'ary0' => array(array('ary' => 0),
        array('ary' => 9),
        array('ary' => 1),
        array('ary' => 2),
        array('ary' => 3),
        array('ary' => 4),
        array('ary' => 5),
        array('ary' => 6),
        array('ary' => 7),
        array('ary' => 8), ),
    'ary1' => array(array('ary' => 9),
        array('ary' => 8),
        array('ary' => 7),
        array('ary' => 6),
        array('ary' => 5),
        array('ary' => 4),
        array('ary' => 3),
        array('ary' => 2),
        array('ary' => 1),
        array('ary' => 0), ),
    ))));
  }

  /**
   * @covers ExprForeach::toPHP
   * @test
   */
  public function parse_TestTwoForeach()
  {
    $parser = new Parser('(§FOREACH:ary0§) {(§FOREACH:ary1§) {{name}{ary}}}');

    $this->assertEquals('x0x1x2x3y0y1y2y3z0z1z2z3', $parser->execute(array(), array(array(
      'ary0' => array(array('name' => 'x'),
        array('name' => 'y'),
        array('name' => 'z'), ),
      'ary1' => array(array('ary' => 0),
        array('ary' => 1),
        array('ary' => 2),
        array('ary' => 3), ),
    ))));
  }

  /**
   * @covers ExprForeach::toPHP
   * @test
   */
  public function parse_TestForeachRecursive()
  {
    $parser = new Parser('(§FOREACH:idx§) {{name_{i}}}');

    $this->assertEquals('hello world!', $parser->execute(array(), array(array(
      'idx' => array(array('i' => 1),
        array('i' => 2),
        array('i' => 3), ),
      'name_1' => 'hello ',
      'name_2' => 'world',
      'name_3' => '!',
      ))));
  }

  /**
   * @covers ExprIf::toPHP
   * @test
   */
  public function parse_ExprIfAnd()
  {
    $parser = new Parser('(§IF§) ("0,00" == "0.0" && "1" == "1") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) ("0" == "1" && "1" == "1") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) ("1" == "1" && "0" == "1") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array(), array()));
  }

  /**
   * @covers ExprIf::toPHP
   * @test
   */
  public function parse_ExprIfOr()
  {
    $parser = new Parser('(§IF§) ("0,00" == "0.0" || "1" == "1") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) (("0,00" == "0.0") || ("1" == "1")) {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) ("0,00" == "0.0" || "0" == "1") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) ("1,00" == "0.0" || "1" == "1") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) ("0" == "1" || "1" == "0") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array(), array()));
  }

  /**
   * @covers ExprIf::toPHP
   * @test
   */
  public function parse_ExprIfOneString()
  {
    $parser = new Parser('(§IF§) ("") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) ("text") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) ("t") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));
  }

  /**
   * @covers ExprIf::toPHP
   * @test
   */
  public function parse_ExprIfAndOr()
  {
    $parser = new Parser('(§IF§) (("0,00" == "0.0" || "1" == "1") && "") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) (("0,00" == "0.0" || "1" == "1") && ("")) {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) (("0,00" == "0.0" || "1" == "1") && ("text")) {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) (("0,00" == "0.0" || "1" == "1") && ("text" || "")) {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) (("0,00" == "0.0" || "1" == "1") && ("text" && "")) {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) (("0,00" == "0.0" || "1" == "1") && ("" || "")) {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) (((("TRUE")))) {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) (((("")))) {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array(), array()));
  }

  /**
   * @covers ExprIf::toPHP
   * @test
   */
  public function parse_ExprIfAltOperatoren()
  {
    $parser = new Parser('(§IF§) (("0,00" == "0.0" OR "1" == "1") AND "") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) (("0,00" == "0.0" OR "1" == "1") AND ("")) {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) (("0,00" == "0.0" OR "1" == "1") AND ("text")) {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) (("0,00" == "0.0" OR "1" == "1") AND ("text" OR "")) {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));


    $parser = new Parser('(§IF§) (("0,00" == "0.0" or "1" == "1") and "") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) (("0,00" == "0.0" or "1" == "1") and ("")) {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) (("0,00" == "0.0" or "1" == "1") and ("text")) {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) (("0,00" == "0.0" or "1" == "1") and ("text" or "")) {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));
  }

  /**
   * @covers ExprIf::toPHP
   * @test
   */
  public function parse_TestIfWithALotOfConditions()
  {
    $parser = new Parser('(§IF§) (("" == "") AND ("1" == "1") AND ("2" == "2") AND ("3" == "3")) {TRUE} else {FALSE}');
    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) (("" == "") AND ("1" == "1") AND ("2" == "2") AND ("3" == "3") AND ("4" == "4")) {TRUE} else {FALSE}');
    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) (("" == "") AND ("1" == "1") AND ("2" == "2") AND ("3" == "3") AND ("1" == "2")) {TRUE} else {FALSE}');
    $this->assertEquals('FALSE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) ("" == "" AND "1" == "1" AND "2" == "2" AND "3" == "3") {TRUE} else {FALSE}');
    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) ("" == "" AND "1" == "1" AND "2" == "2" AND "3" == "3" AND "4" == "4") {TRUE} else {FALSE}');
    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) ("" == "" AND "1" == "1" AND "2" == "2" AND "3" == "3" AND "1" == "2") {TRUE} else {FALSE}');
    $this->assertEquals('FALSE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) (((("" == "") AND ("1" == "1")) AND ("2" == "2")) AND ("3" == "3")) {TRUE} else {FALSE}');
    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) ((((("" == "") AND ("1" == "1")) AND ("2" == "2")) AND ("3" == "3")) AND ("4" == "4")) {TRUE} else {FALSE}');
    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) ((((("" == "") AND ("1" == "1")) AND ("2" == "2")) AND ("3" == "3")) AND ("1" == "2")) {TRUE} else {FALSE}');
    $this->assertEquals('FALSE', $parser->execute(array(), array()));
  }

  /**
   * @covers ExprFunction::toPHP
   * @test
   */
  public function parse_ExprFunction()
  {
    $parser = new Parser('(§FUNCTION:hello§) {Hello, World}');

    $this->assertEquals('', $parser->execute(array(), array()));

    $parser = new Parser('(§FUNCTION:hello§) {Hello, World}{%:hello%}');

    $this->assertEquals('Hello, World', $parser->execute(array(), array()));
  }

  /**
   * @covers ExprFunction::toPHP
   * @test
   */
  public function parse_ExprFunctionArg0()
  {
    $parser = new Parser('(§FUNCTION:text:str§) {{str}}');

    $this->assertEquals('', $parser->execute(array(), array()));

    $parser = new Parser('(§FUNCTION:text:str§) {{str}}{%:text:Hello, World%}');

    $this->assertEquals('Hello, World', $parser->execute(array(), array()));
  }

  /**
   * @covers ExprFunction::toPHP
   * @test
   */
  public function parse_ExprFunctionDifferentArgCount()
  {
    $inistr = '(§FUNCTION:text:str§) {{str}}(§FUNCTION:text:str0:str1§) {{str0}+{str1}}';

    $parser = new Parser($inistr);

    $this->assertEquals('', $parser->execute(array(), array()));

    $parser = new Parser($inistr . '{%:text:1:2%}');

    $this->assertEquals('1+2', $parser->execute(array(), array()));

    $parser = new Parser($inistr . '{%:text:Hello, World%}');

    $this->assertEquals('Hello, World', $parser->execute(array(), array()));
  }

  /**
   * @covers ExprFunction::toPHP
   * @test
   */
  public function parse_ExprFunctionDifferentArgCountException()
  {
    $this->expectException(\Exception::class);

    $inistr = '(§FUNCTION:text:str§) {{str}}{%:text:1:2%}';

    $parser = new Parser($inistr);

    $parser->execute(array(), array());
  }

  /**
   * @covers ExprFunction::toPHP
   * @test
   */
  public function parse_ExprFunctionSameNameException()
  {
    $this->expectException(\Exception::class);

    $parser = new Parser('(§FUNCTION:text§){}(§FUNCTION:text§){}');

    $parser->execute(array(), array());
  }

  /**
   * @covers ExprFunction::toPHP
   * @test
   */
  public function parse_ExprCallFNFunction()
  {
    $parser = new Parser('(§FUNCTION:hello§) {Hello, World}{%:callfn:hello%}');

    $this->assertEquals('Hello, World', $parser->execute(array(), array()));

    $parser = new Parser('(§FUNCTION:text:str§) {{str}}{%:callfn:text:Hello, World%}');

    $this->assertEquals('Hello, World', $parser->execute(array(), array()));
  }

  /**
   * @covers ExprFunction::toPHP
   * @test
   */
  public function parse_ExprFunctionTrimResult()
  {
    $parser = new Parser('(§FUNCTION:hello§) {          ' . "\n"
        . 'Hello, World          }{%:hello%}');

    $this->assertEquals('Hello, World', $parser->execute(array(), array()));
  }

  /**
   * @covers ExprIf::toPHP
   * @test
   */
  public function parse_ExprDisplay()
  {
    $parser = new Parser('{§DISPLAY§}{%var%}{/§DISPLAY§}');

    $this->assertEquals(' style="display: none;"', $parser->execute(array(), array()));

    $this->assertEquals('', $parser->execute(array('var' => 'Variable'), array()));

    $parser = new Parser('{§DISPLAY§}   {%var%}   {/§DISPLAY§}');

    $this->assertEquals(' style="display: none;"', $parser->execute(array(), array()));

    $this->assertEquals('', $parser->execute(array('var' => 'Variable'), array()));
  }

  /**
   * @covers ExprIf::toPHP
   * @test
   */
  public function parse_ExprElseIf()
  {
    $parser = new Parser('(§IF§) ("{%str%}" == "0") {1} else if ("{%str%}" == "1") {2}');

    $this->assertEquals('', $parser->execute(array(), array()));

    $this->assertEquals('1', $parser->execute(array('str' => '0'), array()));

    $this->assertEquals('2', $parser->execute(array('str' => '1'), array()));

    $this->assertEquals('', $parser->execute(array('str' => '2'), array()));

    $parser = new Parser('(§IF§) ("{%str%}" == "0") {1} else if ("{%str%}" == "1") {2} else if ("{%str%}" == "2") {3}');

    $this->assertEquals('', $parser->execute(array(), array()));

    $this->assertEquals('1', $parser->execute(array('str' => '0'), array()));

    $this->assertEquals('2', $parser->execute(array('str' => '1'), array()));

    $this->assertEquals('3', $parser->execute(array('str' => '2'), array()));

    $parser = new Parser('(§IF§) ("{%str%}" == "0") {1} else if ("{%str%}" == "1") {2} else if ("{%str%}" == "2") {3} else {4}');

    $this->assertEquals('4', $parser->execute(array(), array()));

    $this->assertEquals('1', $parser->execute(array('str' => '0'), array()));

    $this->assertEquals('2', $parser->execute(array('str' => '1'), array()));

    $this->assertEquals('3', $parser->execute(array('str' => '2'), array()));

    $this->assertEquals('4', $parser->execute(array('str' => 'hallo'), array()));
  }

  /**
   * @covers ExprIf::toPHP
   * @test
   */
  public function parse_ExprOldIf()
  {
    $parser = new Parser('{§IF§} {§VALUE1§}{%str%}{/§VALUE1§} {§EQUAL§}=={/§EQUAL§}{§VALUE2§}0{/§VALUE2§}'
        . '{§THEN§}Then-Fall{/§THEN§}'
        . '{§ELSE§}Else-Fall{/§ELSE§}'
        . '{§END§}');

    $this->assertEquals('Else-Fall', $parser->execute(array(), array()));

    $this->assertEquals('Else-Fall', $parser->execute(array('str' => ''), array()));

    $this->assertEquals('Else-Fall', $parser->execute(array('str' => 'hello'), array()));

    $this->assertEquals('Then-Fall', $parser->execute(array('str' => '0'), array()));
  }

  /**
   * @covers Parser::parseAll()
   * @test
   */
  public function parse_ExprOldIfException()
  {
    $parser = new Parser('{§IF§}');

    $this->expectException(\Exception::class);

    $parser->execute(array(), array());
  }

  /**
   * @covers ExprIf::toPHP
   * @test
   */
  public function parse_TestExprInIfExpr()
  {
    $parser = new Parser('(§IF§) ("(§FOREACH:ary§) {{number}}" == "0123456789") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array(array(
      'ary' => array(
        array('number' => '0'),
        array('number' => '1'),
        array('number' => '2'),
        array('number' => '3'),
        array('number' => '4'),
        array('number' => '5'),
        array('number' => '6'),
        array('number' => '7'),
        array('number' => '8'),
        array('number' => '9'),
      ),
    ))));
  }

  /**
   * @covers ExprFunctionCall::toPHP
   * @test
   */
  public function parse_TestFunctionTrim()
  {
    $parser = new Parser('{%:trim:  Hello, World! ' . "\n\t" . ' %}');

    $this->assertEquals('Hello, World!', $parser->execute(array(), array()));

    $parser = new Parser('{%:trim:Hello, World!%}');

    $this->assertEquals('Hello, World!', $parser->execute(array(), array()));
  }

  /**
   * @covers ExprSingleCondition::toPHP
   * @test
   */
  public function parse_TestOperatorContains()
  {
    $parser = new Parser('(§IF§) ("{%var%}" contains "M") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array('var' => 'Match'), array()));

    $this->assertEquals('FALSE', $parser->execute(array('var' => 'No'), array()));

    $parser = new Parser('(§IF§) ("{%var%}" contains "m") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array('var' => 'Match'), array()));

    $parser = new Parser('(§IF§) ("{%var%}" contains "M") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array('var' => 'match'), array()));
  }

  /**
   * @covers ExprSingleCondition::toPHP
   * @test
   */
  public function parse_TestOperatorMatch()
  {
    $parser = new Parser('(§IF§) ("/match/i" matches "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array('var' => 'Match'), array()));

    $parser = new Parser('(§IF§) ("/match/" matches "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array('var' => 'Match'), array()));

    $parser = new Parser('(§IF§) ("/.*/" matches "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array('var' => 'Match'), array()));

    $parser = new Parser('(§IF§) ("/.+/" matches "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array('var' => 'Match'), array()));

    $parser = new Parser('(§IF§) ("/...../" matches "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array('var' => 'Match'), array()));

    $parser = new Parser('(§IF§) ("/^.$/" matches "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array('var' => 'Match'), array()));

    $parser = new Parser('(§IF§) ("/^.$/" matches "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array('var' => ''), array()));

    $parser = new Parser('(§IF§) ("/match/i" matches "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array('var' => 'MatchMatch'), array()));
  }

  /**
   * @covers ExprSingleCondition::toPHP
   * @test
   */
  public function parse_TestOperatorPartMatch()
  {
    $parser = new Parser('(§IF§) ("/match/i" partmatches "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array('var' => 'MatchMatch'), array()));

    $parser = new Parser('(§IF§) ("/match/" partmatches "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array('var' => 'MatchMatch'), array()));

    $parser = new Parser('(§IF§) ("/match/" partmatches "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array('var' => 'Matchmatch'), array()));

    $parser = new Parser('(§IF§) ("/.*/" partmatches "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array('var' => 'Match'), array()));

    $parser = new Parser('(§IF§) ("/.+/" partmatches "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array('var' => 'Match'), array()));

    $parser = new Parser('(§IF§) ("/...../" partmatches "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array('var' => 'Match'), array()));

    $parser = new Parser('(§IF§) ("/^.$/" partmatches "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array('var' => 'Match'), array()));

    $parser = new Parser('(§IF§) ("/^.$/" partmatches "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array('var' => ''), array()));
  }

  /**
   * @covers ExprSingleCondition::toPHP
   * @test
   */
  public function parse_TestOperatorLessThan()
  {
    $parser = new Parser('(§IF§) ("10" < "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array('var' => '100'), array()));

    $parser = new Parser('(§IF§) ("10" < "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array('var' => '10'), array()));

    $parser = new Parser('(§IF§) ("10" < "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array('var' => ''), array()));
  }

  /**
   * @covers ExprSingleCondition::toPHP
   * @test
   */
  public function parse_TestOperatorGreaterThan()
  {
    $parser = new Parser('(§IF§) ("10" > "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array('var' => '100'), array()));

    $parser = new Parser('(§IF§) ("10" > "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array('var' => '10'), array()));

    $parser = new Parser('(§IF§) ("10" > "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array('var' => ''), array()));
  }

  /**
   * @covers ExprSingleCondition::toPHP
   * @test
   */
  public function parse_TestOperatorLessEquals()
  {
    $parser = new Parser('(§IF§) ("10" <= "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array('var' => '100'), array()));

    $parser = new Parser('(§IF§) ("10" <= "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array('var' => '10'), array()));

    $parser = new Parser('(§IF§) ("10" <= "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array('var' => ''), array()));
  }

  /**
   * @covers ExprSingleCondition::toPHP
   * @test
   */
  public function parse_TestOperatorGreaterEquals()
  {
    $parser = new Parser('(§IF§) ("10" >= "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array('var' => '100'), array()));

    $parser = new Parser('(§IF§) ("10" >= "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array('var' => '10'), array()));

    $parser = new Parser('(§IF§) ("10" >= "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array('var' => ''), array()));
  }

  /**
   * @covers ExprSingleCondition::toPHP
   * @test
   */
  public function parse_TestOperatorEquals()
  {
    $parser = new Parser('(§IF§) ("10" == "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array('var' => '100'), array()));

    $parser = new Parser('(§IF§) ("10" == "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array('var' => 'text'), array()));

    $parser = new Parser('(§IF§) ("  text" == "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array('var' => 'text'), array()));

    $parser = new Parser('(§IF§) ("text   " == "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array('var' => 'text'), array()));

    $parser = new Parser('(§IF§) ("10" == "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array('var' => '10'), array()));

    $parser = new Parser('(§IF§) ("10" == "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array('var' => '   10  '), array()));

    $parser = new Parser('(§IF§) (" 10   " == "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array('var' => '   10  '), array()));
  }

  /**
   * @covers ExprSingleCondition::toPHP
   * @test
   */
  public function parse_TestOperatorNotEquals()
  {
    $parser = new Parser('(§IF§) ("10" != "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array('var' => '100'), array()));

    $parser = new Parser('(§IF§) ("10" != "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array('var' => 'text'), array()));

    $parser = new Parser('(§IF§) ("  text" != "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array('var' => 'text'), array()));

    $parser = new Parser('(§IF§) ("text   " != "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array('var' => 'text'), array()));

    $parser = new Parser('(§IF§) ("10" != "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array('var' => '10'), array()));

    $parser = new Parser('(§IF§) ("10" != "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array('var' => '   10  '), array()));

    $parser = new Parser('(§IF§) (" 10   " != "{%var%}") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array('var' => '   10  '), array()));
  }

  /**
   * @covers ExprFunction::toPHP
   * @test
   */
  public function parse_TestFunctionTrue()
  {
    $parser = new Parser('{%:true%}');

    $this->assertEquals('1', $parser->execute(array(), array()));
  }

  /**
   * @covers ExprFunction::toPHP
   * @test
   */
  public function parse_TestFunctionTrueExceptionArgLength()
  {
    $this->expectException(\Exception::class);

    $parser = new Parser('{%:true:arg0%}');

    $this->assertEquals('1', $parser->execute(array(), array()));
  }

  /**
   * @covers ExprFunction::toPHP
   * @test
   */
  public function parse_TestFunctionFalse()
  {
    $parser = new Parser('{%:false%}');

    $this->assertEquals('', $parser->execute(array(), array()));
  }

  /**
   * @covers Parser::parseAll()
   * @test
   */
  public function parse_TestEscapedCurlyBracket()
  {
    $parser = new Parser('(§FUNCTION:text§) {\\{}{%:text%}');

    $this->assertEquals('{', $parser->execute(array(), array()));

    $parser = new Parser('(§FUNCTION:text§) {text\\{text}{%:text%}');

    $this->assertEquals('text{text', $parser->execute(array(), array()));
  }

  /**
   * @covers Parser::parseAll()
   * @test
   */
  public function parse_TestForeachInGlobalContext()
  {
    $parser = new Parser('{thisisnotavar}');

    $this->assertEquals('{thisisnotavar}', $parser->execute(array(), array()));
  }

  /**
   * @covers Parser::parseAll()
   * @test
   */
  public function parse_TestNoBracketsIfConditionValue()
  {
    $parser = new Parser('(§IF§) ("x" == x) {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) ("x" == 0) {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) ("0123459" == 0123459) {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) (0123459 == 0123459) {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) (0123459 == "0123459") {TRUE} else {FALSE}');

    $this->assertEquals('TRUE', $parser->execute(array(), array()));

    $parser = new Parser('(§IF§) (0123459 == "012345") {TRUE} else {FALSE}');

    $this->assertEquals('FALSE', $parser->execute(array(), array()));
  }

  /**
   * @covers Parser::parseAll()
   * @test
   */
  public function parse_TestFunctionAdd()
  {
    $parser = new Parser('{%:add:1:2%}');

    $this->assertEquals('3', $parser->execute(array(), array()));

    $parser = new Parser('{%:add:0:2%}');

    $this->assertEquals('2', $parser->execute(array(), array()));

    $parser = new Parser('{%:add:0:0%}');

    $this->assertEquals('0', $parser->execute(array(), array()));

    $parser = new Parser('{%:add:1.0:1.25%}');

    $this->assertEquals('2.25', $parser->execute(array(), array()));
  }

  /**
   * @covers Parser::parseAll()
   * @test
   */
  public function parse_TestFunctionSubtract()
  {
    $parser = new Parser('{%:sub:1:2%}');

    $this->assertEquals('-1', $parser->execute(array(), array()));

    $parser = new Parser('{%:sub:0:2%}');

    $this->assertEquals('-2', $parser->execute(array(), array()));

    $parser = new Parser('{%:sub:0:0%}');

    $this->assertEquals('0', $parser->execute(array(), array()));

    $parser = new Parser('{%:sub:1.0:1.25%}');

    $this->assertEquals('-0.25', $parser->execute(array(), array()));

    $parser = new Parser('{%:sub:1:-2%}');

    $this->assertEquals('3', $parser->execute(array(), array()));
  }

  /**
   * @covers Parser::parseAll()
   * @test
   */
  public function parse_TestFunctionMultiply()
  {
    $parser = new Parser('{%:mult:1:2%}');

    $this->assertEquals('2', $parser->execute(array(), array()));

    $parser = new Parser('{%:mult:0:2%}');

    $this->assertEquals('0', $parser->execute(array(), array()));

    $parser = new Parser('{%:mult:0:0%}');

    $this->assertEquals('0', $parser->execute(array(), array()));

    $parser = new Parser('{%:mult:1.0:1.25%}');

    $this->assertEquals('1.25', $parser->execute(array(), array()));

    $parser = new Parser('{%:mult:1:-2%}');

    $this->assertEquals('-2', $parser->execute(array(), array()));
  }

  /**
   * @covers Parser::parseAll()
   * @test
   */
  public function parse_TestFunctionDivision()
  {
    $parser = new Parser('{%:div:1:2%}');

    $this->assertEquals('0.5', $parser->execute(array(), array()));

    $parser = new Parser('{%:div:3:2%}');

    $this->assertEquals('1.5', $parser->execute(array(), array()));

    $parser = new Parser('{%:div:4:2%}');

    $this->assertEquals('2', $parser->execute(array(), array()));
  }

  /**
   * @covers Parser::parseAll()
   * @test
   */
  public function parse_TestFunctionCallfn()
  {
    $parser = new Parser('(§FUNCTION:myfunction0:arg§) {TRUE{arg}}'
     . '(§FUNCTION:myfunction1:arg§) {FALSE{arg}}'
     . '{%:callfn:{%fnname%}:{%arg%}%}');


    $this->assertEquals('TRUE0', $parser->execute(array(
      'fnname' => 'myfunction0',
      'arg' => '0',
    ), array()));

    $this->assertEquals('FALSE0', $parser->execute(array(
      'fnname' => 'myfunction1',
      'arg' => '0',
    ), array()));
  }

  /**
   * @covers Parser::parseAll()
   * @test
   */
  public function parse_TestFunctionValue()
  {
    $parser = new Parser('{%:value:{%variable%}%}');

    $this->assertEquals('TRUE', $parser->execute(array(
      'variable' => 'var0',
      'var0' => 'TRUE',
    ), array()));

    $this->assertEquals('hello, world', $parser->execute(array(
      'variable' => 'asdfasdfasdfasdf',
      'asdfasdfasdfasdf' => 'hello, world',
    ), array()));

    $this->assertEquals('', $parser->execute(array(
      'variable' => 'asdfasdfasdfasdf',
    ), array()));
  }

  /**
   * @covers Parser::parseAll()
   * @test
   */
  public function parse_TestFunctionFloor()
  {
    $parser = new Parser('{%:floor:{%variable%}%}');

    $this->assertEquals('1', $parser->execute(array(
      'variable' => 1.5,
    ), array()));

    $this->assertEquals('1', $parser->execute(array(
      'variable' => 1.1,
    ), array()));

    $this->assertEquals('2', $parser->execute(array(
      'variable' => 2.0,
    ), array()));
  }

  /**
   * @covers Parser::parseAll()
   * @test
   */
  public function parse_TestFunctionCeil()
  {
    $parser = new Parser('{%:ceil:{%variable%}%}');

    $this->assertEquals('2', $parser->execute(array(
      'variable' => 1.5,
    ), array()));

    $this->assertEquals('2', $parser->execute(array(
      'variable' => 1.2,
    ), array()));

    $this->assertEquals('2', $parser->execute(array(
      'variable' => 2,
    ), array()));
  }

  /**
   * @covers Parser::parseAll()
   * @test
   */
  public function parse_TestFunctionRound()
  {
    $parser = new Parser('{%:round:{%variable%}%}');

    $this->assertEquals('2', $parser->execute(array(
      'variable' => 1.5,
    ), array()));

    $this->assertEquals('1', $parser->execute(array(
      'variable' => 1.2,
    ), array()));

    $this->assertEquals('2', $parser->execute(array(
      'variable' => 2,
    ), array()));
  }

  /**
   * @covers Parser::parseAll()
   * @test
   */
  public function parse_TestFunctionRoundWrongArgCount()
  {
    $this->expectException(\Exception::class);

    $parser = new Parser('{%:round%}');

    $parser->execute(array(
      'variable' => 1.5,
    ), array());
  }

  /**
   * Test um auf Exploits zu testen
   * @covers Parser::parseAll()
   * @test
   */
  public function parse_TestVariableNoRecurse()
  {
    $parser = new Parser('{%variable%}');

    $this->assertEquals('{%variable%}', $parser->execute(array(
      'variable' => '{%variable%}',
    ), array()));
    $this->assertEquals('{%var0%}', $parser->execute(array(
      'variable' => '{%var0%}',
      'var0' => 'test',
    ), array()));
  }

  /**
   * @covers Parser::parseAll
   * @covers Parser::execute
   * @covers \Kufer\Web\Classes\Scripting3\ParserHelper::applyFilter
   * @test
   */
  public function parse_variableFilter()
  {
    $parser = new Parser('{%variable@raw%}');
    $this->assertEquals('&<', $parser->execute(array(
      'variable' => '&<',
    ), array()));

    $parser = new Parser('{%variable@escape%}');
    $this->assertEquals('&amp;&lt;', $parser->execute(array(
      'variable' => '&<',
    ), array()));

    $parser = new Parser('{%variable@escape@raw%}');
    $this->assertEquals('&amp;&lt;', $parser->execute(array(
      'variable' => '&<',
    ), array()));

    $parser = new Parser('{%variable@raw@escape%}');
    $this->assertEquals('&amp;&lt;', $parser->execute(array(
      'variable' => '&<',
    ), array()));

    $parser = new Parser('{%variable@escapehtml%}');
    $this->assertEquals('&amp;&lt;', $parser->execute(array(
      'variable' => '&<',
    ), array()));

    $parser = new Parser('{%variable@safehtml%}');
    $this->assertEquals('<p>hello</p>', $parser->execute(array(
      'variable' => '<p>hello</p><script></script>',
    ), array()));

    $parser = new Parser('{%variable@striptags%}');
    $this->assertEquals('hello', $parser->execute(array(
      'variable' => '<p>hello</p><script></script>',
    ), array()));

    $parser = new Parser('{%variable@escapejs%}');
    $this->assertEquals('hello\\u0022\\u0027', $parser->execute(array(
      'variable' => 'hello"\'',
    ), array()));

    $parser = new Parser('{%variable@escapejs@raw%}');
    $this->assertEquals('hello\\u0022\\u0027', $parser->execute(array(
      'variable' => 'hello"\'',
    ), array()));

    $parser = new Parser('{%variable:%var%@escapejs@raw%}');
    $this->assertEquals('hello\\u0022\\u0027', $parser->execute(array(
      'variable' => 'hello"\'',
    ), array()));
  }

  /**
   * @covers Parser::parseAll
   * @covers Parser::execute
   * @covers \Kufer\Web\Classes\Scripting3\ParserHelper::applyFilter
   * @test
   */
  public function parse_variableForeachFilter()
  {
    $parser = new Parser('(§FOREACH:variable§) {{val}}');
    $this->assertEquals('&<', $parser->execute(array(
    ), array(array('variable' => array(array('val' => '&<'))))));

    $parser = new Parser('(§FOREACH:variable§) {{val@raw}}');
    $this->assertEquals('&<', $parser->execute(array(
    ), array(array('variable' => array(array('val' => '&<'))))));

    $parser = new Parser('(§FOREACH:variable§) {{val@escape}}');
    $this->assertEquals('&amp;&lt;', $parser->execute(array(
    ), array(array('variable' => array(array('val' => '&<'))))));

    $parser = new Parser('(§FOREACH:variable§){val@escape}(§/ENDFOREACH:variable§)');
    $this->assertEquals('&amp;&lt;', $parser->execute(array(
    ), array(array('variable' => array(array('val' => '&<'))))));
  }

  /**
   * @covers Parser::parseAll
   * @covers Parser::execute
   * @covers \Kufer\Web\Classes\Scripting3\Parser::nextTextExpr()
   * @test
   */
  public function parse_foreachvars_not_in_foreach()
  {
    $parser = new Parser('{var}');
    $this->assertEquals('{var}', $parser->execute(array(
      'var' => 'val'
    ), array()));
    $parser = new Parser('{var}');
    $this->assertEquals('{var}', $parser->execute(array(
      'var' => 'val'
    ), array()));
    $parser = new Parser('(§IF§) ("{%test%}" == "") {{var}}');
    $this->assertEquals('{var}', $parser->execute(array(
      'var' => 'val'
    ), array()));
    $parser = new Parser('(§IF§) ("{%test%}" == "") {test{var}test}');
    $this->assertEquals('test{var}test', $parser->execute(array(
      'var' => 'val'
    ), array()));
  }
}
