gt:         person1.put("addresses", Arrays.asList(address1, address2));
context: /*
   * Grakn - A Distributed Semantic Database
   * Copyright (C) 2016  Grakn Labs Limited
   *
   * Grakn is free software: you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation, either version 3 of the License, or
   * (at your option) any later version.
   *
   * Grakn is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with Grakn. If not, see <http://www.gnu.org/licenses/gpl.txt>.
   */
  
  package ai.grakn.graql.template;
  
  import ai.grakn.exception.GraqlTemplateParsingException;
  import ai.grakn.graql.Graql;
  import ai.grakn.graql.Query;
  import org.junit.Rule;
  import org.junit.Test;
  import org.junit.rules.ExpectedException;
  
  import java.util.Arrays;
  import java.util.Collections;
  import java.util.HashMap;
  import java.util.Map;
  
  import static ai.grakn.graql.Graql.parse;
  import static java.util.Collections.singletonMap;
  import static junit.framework.TestCase.assertEquals;
  
  public class TemplateParserTest {
  
      @Rule
      public final ExpectedException exception = ExpectedException.none();
  
      @Test
      public void oneValueOneLineTest(){
          String template = "insert $x isa person has name <name>;    ";
          String expected = "insert $x0 has name \"Phil Collins\" isa person;";
  
          Map<String, Object> data = new HashMap<>();
          data.put("name", "Phil Collins");
  
          assertParseEquals(template, data, expected);
      }
  
      @Test
      public void concatenateValuesTest(){
          String template = "insert $x isa @noescp(<first>)-@noescp(<last>);";
          String expected = "insert $x0 isa one-two;";
  
          Map<String, Object> data = new HashMap<>();
          data.put("first", "one");
          data.put("last", "two");
  
          assertParseEquals(template, data, expected);
      }
  
      @Test
      public void multiValueOneLineTest(){
          String template = "insert $x isa person has name <name> , has feet <numFeet>;";
          String expected = "insert $x0 has name \"Phil Collins\" isa person has feet 3;";
  
          Map<String, Object> data = new HashMap<>();
          data.put("name", "Phil Collins");
          data.put("numFeet", 3);
  
          assertParseEquals(template, data, expected);
      }
  
      @Test(expected = GraqlTemplateParsingException.class)
      public void dataMissingTest() {
          String template = "insert $x isa person has name <name> , has feet <numFeet> ";
          String expected = "insert $x0 has name \"Phil Collins\" isa person has feet 3;";
  
          Map<String, Object> data = new HashMap<>();
          data.put("name", "Phil Collins");
          data.put("feet", 3);
  
          assertParseEquals(template, data, expected);
      }
  
      @Test
      public void quotingWhenReplacementInVariableTest(){
          String template =
                  "insert \n" +
                          "for (address in <addresses>) do { \n" +
                          "   $<address> has address <address>;\n" +
                          "}";
  
          String expected = "insert $22-Hornsey has address \"22 Hornsey\";\n" +
                  "$Something has address \"Something\";";
  
  
          Map<String, Object> data = new HashMap<>();
          data.put("addresses", Arrays.asList("22 Hornsey", "Something"));
  
          assertParseEquals(template, data, expected);
      }
  
      @Test
      public void noSpacesBetweenTokensTest(){
          String template =
                  "insert " +
                          "for (whale in <whales>) do {" +
                          "\t\t\t$x isa whale has name <whale>;\n}";
  
          String expected =
                  "insert $x0 isa whale has name \"shamu\";\n" +
                          "$x1 isa whale has name \"dory\";";
  
          Map<String, Object> data = new HashMap<>();
          data.put("whales", Arrays.asList("shamu", "dory"));
  
          assertParseEquals(template, data, expected);
      }
  
      @Test
      public void multipleDataTypesTest(){
          String template = "insert $x isa y; $x value <string>; $x value <long>; $x value <double>; $x value <bool>;";
          String expected =
                  "insert $x0 isa y;\n" +
                          "$x0 value \"string\";\n" +
                          "$x0 value 40;\n" +
                          "$x0 value 0.001;\n" +
                          "$x0 value false;";
  
          Map<String, Object> data = new HashMap<>();
          data.put("string", "string");
          data.put("long", 40);
          data.put("double", 0.001);
          data.put("bool", false);
  
          assertParseEquals(template, data, expected);
      }
  
      @Test
      public void forLoopOverArrayTest(){
          String template = "insert " +
                  "for (whale in <whales> ) do {" +
                  "$x isa whale has name <whale>;\n}";
  
          String expected =
                  "insert $x0 isa whale has name \"shamu\";\n" +
                          "$x1 isa whale has name \"dory\";";
  
          Map<String, Object> data = new HashMap<>();
          data.put("whales", Arrays.asList("shamu", "dory"));
  
          assertParseEquals(template, data, expected);
      }
  
      @Test
      public void forLoopOverObjectsWithEnhancedForSyntaxTest(){
          String template = "insert\n" +
                  "    $x isa person;\n" +
                  "    for ( <addresses> ) do {\n" +
                  "        $y isa address;\n" +
                  "        $y has street <street> ;\n" +
                  "        $y has number <houseNumber> ;\n" +
                  "        ($x, $y) isa resides;\n" +
                  "    }";
  
          String expected =
                  "insert $x0 isa person;\n" +
                          "$y0 isa address;\n" +
                          "$y0 has street \"Collins Ave\";\n" +
                          "$y0 has number 8855;\n" +
                          "($x0, $y0) isa resides;\n" +
                          "$y1 isa address;\n" +
                          "$y1 has street \"Hornsey St\";\n" +
                          "$y1 has number 8;\n" +
                          "($x0, $y1) isa resides;";
  
          Map<String, Object> address1 = new HashMap<>();
          address1.put("street", "Collins Ave");
          address1.put("houseNumber", 8855);
  
          Map<String, Object> address2 = new HashMap<>();
          address2.put("street", "Hornsey St");
          address2.put("houseNumber", 8);
  
          Map<String, Object> data = new HashMap<>();
          data.put("addresses", Arrays.asList(address1, address2));
  
          assertParseEquals(template, data, expected);
      }
  
      @Test
      public void forLoopOverObjectsWithNormalForSyntaxTest(){
          String template = "insert\n" +
                  "    $x isa person;\n" +
                  "    for ( address in <addresses> ) do {\n" +
                  "        $y isa address;\n" +
                  "        $y has street <address.street> ;\n" +
                  "        $y has number <address.number> ;\n" +
                  "        ($x, $y) isa resides;\n" +
                  "    }";
  
          String expected = "insert $x0 isa person;\n" +
                  "$y0 isa address;\n" +
                  "$y0 has street \"Collins Ave\";\n" +
                  "$y0 has number 8855;\n" +
                  "($x0, $y0) isa resides;\n" +
                  "$y1 isa address;\n" +
                  "$y1 has street \"Hornsey St\";\n" +
                  "$y1 has number 8;\n" +
                  "($x0, $y1) isa resides;";
  
          Map<String, Object> address1 = new HashMap<>();
          address1.put("street", "Collins Ave");
          address1.put("number", 8855);
  
          Map<String, Object> address2 = new HashMap<>();
          address2.put("street", "Hornsey St");
          address2.put("number", 8);
  
          Map<String, Object> data = new HashMap<>();
          data.put("addresses", Arrays.asList(address1, address2));
  
          assertParseEquals(template, data, expected);
      }
  
      @Test
      public void doubleNestedForTest(){
  
          String template =
                  "insert " +
                          "for ( <people> ) \n" +
                          "do { \n" +
                          "$x isa person has name <name>;\n" +
                          "    for ( <addresses> ) do {\n" +
                          "    $y isa address ;\n" +
                          "        $y has street <street> ;\n" +
                          "        $y has number <number> ;\n" +
                          "        ($x, $y) isa resides;\n" +
                          "    }\n" +
                          "}";
  
          String expected =
                  "insert $x0 isa person has name \"Elmo\";\n" +
                          "$y0 isa address;\n" +
                          "$y0 has street \"North Pole\";\n" +
                          "$y0 has number 100;\n" +
                          "($x0, $y0) isa resides;\n" +
                          "$y1 isa address;\n" +
                          "$y1 has street \"South Pole\";\n" +
                          "$y1 has number -100;\n" +
                          "($x0, $y1) isa resides;\n" +
                          "$x1 isa person has name \"Flounder\";\n" +
                          "$y2 isa address;\n" +
                          "$y2 has street \"Under the sea\";\n" +
                          "$y2 has number 22;\n" +
                          "($x1, $y2) isa resides;";
  
          Map<String, Object> address1 = new HashMap<>();
          address1.put("street", "North Pole");
          address1.put("number", 100);
  
          Map<String, Object> address2 = new HashMap<>();
          address2.put("street", "South Pole");
          address2.put("number", -100);
  
          Map<String, Object> address3 = new HashMap<>();
          address3.put("street", "Under the sea");
          address3.put("number", 22);
  
          Map<String, Object> person1 = new HashMap<>();
          person1.put("name", "Elmo");
  