private void assertErrorContains(boolean squareTags, String ftl, String... expectedSubstrings) {
   try {
     if (squareTags) {
       ftl = ftl.replace('<', '[').replace('>', ']');
     }
     new Template("adhoc", ftl, cfg);
     fail("The tempalte had to fail");
   } catch (ParseException e) {
     String msg = e.getMessage();
     for (String needle : expectedSubstrings) {
       if (needle.startsWith("\\!")) {
         String netNeedle = needle.substring(2);
         if (msg.contains(netNeedle)) {
           fail(
               "The message shouldn't contain substring "
                   + StringUtil.jQuote(netNeedle)
                   + ":\n"
                   + msg);
         }
       } else if (!msg.contains(needle)) {
         fail("The message didn't contain substring " + StringUtil.jQuote(needle) + ":\n" + msg);
       }
     }
     showError(e);
   } catch (IOException e) {
     // Won't happen
     throw new RuntimeException(e);
   }
 }
 private static void assertParseException(int offset, String message, final String json) {
   ParseException exception =
       assertException(
           ParseException.class,
           new Runnable() {
             public void run() {
               parse(json);
             }
           });
   assertEquals(offset, exception.getOffset());
   assertThat(exception.getMessage(), StringStartsWith.startsWith(message + " at"));
 }
 private static void assertParseException(int offset, int line, int column, final String json) {
   ParseException exception =
       assertException(
           ParseException.class,
           new Runnable() {
             public void run() {
               parse(json);
             }
           });
   assertEquals("offset", offset, exception.getOffset());
   assertEquals("line", line, exception.getLine());
   assertEquals("column", column, exception.getColumn());
 }
  @Test
  public void parse_rejectsEmptyReader() {
    ParseException exception =
        assertException(
            ParseException.class,
            new Runnable() {
              public void run() {
                try {
                  new JsonParser(new StringReader("")).parse();
                } catch (IOException exception) {
                  throw new RuntimeException(exception);
                }
              }
            });

    assertEquals(0, exception.getOffset());
    assertThat(exception.getMessage(), StringStartsWith.startsWith("Unexpected end of input at"));
  }
  @Test
  public void parse_handlesPositionsCorrectlyWhenInputExceedsBufferSize() {
    final String input = "{\n  \"a\": 23,\n  \"b\": 42,\n}";

    ParseException exception =
        assertException(
            ParseException.class,
            new Runnable() {
              public void run() {
                try {
                  new JsonParser(new StringReader(input), 3).parse();
                } catch (IOException e) {
                }
              }
            });

    assertEquals(4, exception.getLine());
    assertEquals(0, exception.getColumn());
    assertEquals(24, exception.getOffset());
  }