@Test
  public void testZeroSizeFile() throws Exception {
    ByteArrayOutputStream log = new ByteArrayOutputStream();
    helper.redirectLog(log, LogLevel.BASIC);
    try (FileObject fileObj = KettleVFS.getFileObject(BASE_RAM_DIR + "test.json");
        LocaleChange enUs = new LocaleChange(Locale.US); ) {
      fileObj.createFile();
      JsonInputField price = new JsonInputField();
      price.setName("price");
      price.setType(ValueMetaInterface.TYPE_NUMBER);
      price.setPath("$..book[*].price");

      JsonInputMeta meta = createSimpleMeta("in file", price);
      meta.setIsAFile(true);
      meta.setRemoveSourceField(true);
      meta.setIgnoreEmptyFile(false);
      JsonInput jsonInput =
          createJsonInput(
              "in file", meta, new Object[][] {new Object[] {BASE_RAM_DIR + "test.json"}});
      processRows(jsonInput, 1);
      String logMsgs = log.toString();
      assertTrue(logMsgs, logMsgs.contains("is empty!"));
    } finally {
      deleteFiles();
    }
  }
  @Test
  public void testZipFileInput() throws Exception {
    ByteArrayOutputStream err = new ByteArrayOutputStream();
    helper.redirectLog(err, LogLevel.ERROR);

    final String input = getBasicTestJson();
    try (FileObject fileObj = KettleVFS.getFileObject(BASE_RAM_DIR + "test.zip")) {
      fileObj.createFile();
      try (OutputStream out = fileObj.getContent().getOutputStream()) {
        try (ZipOutputStream zipOut = new ZipOutputStream(out)) {
          ZipEntry jsonFile = new ZipEntry("test.json");
          zipOut.putNextEntry(jsonFile);
          zipOut.write(input.getBytes());
          zipOut.closeEntry();
          zipOut.flush();
        }
      }
      JsonInputField price = new JsonInputField();
      price.setName("price");
      price.setType(ValueMetaInterface.TYPE_NUMBER);
      price.setPath("$..book[*].price");

      JsonInputMeta meta = createSimpleMeta("in file", price);
      meta.setIsAFile(true);
      meta.setRemoveSourceField(true);
      JsonInput jsonInput =
          createJsonInput(
              "in file",
              meta,
              new Object[][] {new Object[] {"zip:" + BASE_RAM_DIR + "test.zip!/test.json"}});
      RowComparatorListener rowComparator =
          new RowComparatorListener(
              new Object[] {8.95d},
              new Object[] {12.99d},
              new Object[] {8.99d},
              new Object[] {22.99d});
      jsonInput.addRowListener(rowComparator);
      processRows(jsonInput, 5);
      Assert.assertEquals(err.toString(), 0, jsonInput.getErrors());
    } finally {
      deleteFiles();
    }
  }
  @Test
  public void testExtraFileFields() throws Exception {
    ByteArrayOutputStream err = new ByteArrayOutputStream();
    helper.redirectLog(err, LogLevel.ERROR);

    final String input1 = getBasicTestJson();
    final String input2 = "{ \"store\": { \"bicycle\": { \"color\": \"blue\" } } }";
    final String path1 = BASE_RAM_DIR + "test1.json";
    final String path2 = BASE_RAM_DIR + "test2.js";
    try (FileObject fileObj1 = KettleVFS.getFileObject(path1);
        FileObject fileObj2 = KettleVFS.getFileObject(path2)) {
      try (OutputStream out = fileObj1.getContent().getOutputStream()) {
        out.write(input1.getBytes());
      }
      try (OutputStream out = fileObj2.getContent().getOutputStream()) {
        out.write(input2.getBytes());
      }

      JsonInputField color = new JsonInputField();
      color.setName("color");
      color.setType(ValueMetaInterface.TYPE_STRING);
      color.setPath("$.store.bicycle.color");

      JsonInputMeta meta = createSimpleMeta("in file", color);
      meta.setInFields(true);
      meta.setIsAFile(true);
      meta.setRemoveSourceField(true);

      meta.setExtensionField("extension");
      meta.setPathField("dir path");
      meta.setSizeField("size");
      meta.setIsHiddenField("hidden?");
      meta.setLastModificationDateField("last modified");
      meta.setUriField("URI");
      meta.setRootUriField("root URI");

      // custom checkers for size and last modified
      RowComparatorListener rowComparator =
          new RowComparatorListener(
              new Object[] {
                "red",
                "json",
                "ram:///jsonInputTest",
                -1L,
                false,
                new Date(0),
                "ram:///jsonInputTest/test1.json",
                "ram:///"
              },
              new Object[] {
                "blue",
                "js",
                "ram:///jsonInputTest",
                -1L,
                false,
                new Date(0),
                "ram:///jsonInputTest/test2.js",
                "ram:///"
              });
      rowComparator.setComparator(
          3,
          new RowComparatorListener.Comparison<Object>() {
            @Override
            public boolean equals(Object expected, Object actual) throws Exception {
              // just want a valid size
              return ((long) actual) > 0L;
            }
          });
      rowComparator.setComparator(
          5,
          new RowComparatorListener.Comparison<Object>() {
            @Override
            public boolean equals(Object expected, Object actual) throws Exception {
              return ((Date) actual).after(new Date(0));
            }
          });
      JsonInput jsonInput =
          createJsonInput(
              "in file", meta, new Object[][] {new Object[] {path1}, new Object[] {path2}});
      jsonInput.addRowListener(rowComparator);
      processRows(jsonInput, 3);
      Assert.assertEquals(err.toString(), 0, jsonInput.getErrors());
    } finally {
      deleteFiles();
    }
  }