@Test(
      dataProvider = "unit-test",
      groups = {"functional"})
  public void semanticErrorTest(final String rootDir, final String adlName) throws Exception {
    initSourcePath(rootDir);
    final ExpectedError expectedError = parserFirstLine(adlName);
    try {
      loader.load(adlName, context);
      if (expectedError != null) fail("Successful loading of erroneous " + adlName + " ADL.");
    } catch (final ADLException e) {
      final Error error = e.getError();
      if (error == null) {
        throw new AssertionFailedError("Loader returned an exception without error.");
      }
      ErrorLocator locator = error.getLocator();
      while (locator instanceof ChainedErrorLocator) {
        locator = ((ChainedErrorLocator) locator).getRootLocator();
      }

      assertNotNull(locator, "Caught ADLException have no locator");
      assertEquals(
          ((Enum<?>) error.getTemplate()).name(),
          expectedError.errorId,
          "Unexpected errorId of caught ADLException");
      assertEquals(
          error.getTemplate().getGroupId(),
          expectedError.groupId,
          "Unexpected groupId of caught ADLException");
      assertEquals(
          locator.getBeginLine(), expectedError.line, "Unexpected line of caught ADLException");
    }
  }
  public static String formatError(final Error error) {
    ErrorLocator locator = error.getLocator();
    if (locator instanceof ChainedErrorLocator) {
      locator = ((ChainedErrorLocator) locator).getRootLocator();
      if (locator == null) {
        final Iterator<ErrorLocator> iter =
            ((ChainedErrorLocator) error.getLocator()).getChainedLocations().iterator();
        while (iter.hasNext() && locator == null) {
          locator = iter.next();
        }
      }
    }
    final String cwd = System.getProperty("user.dir") + File.separator;

    String fileLocation = null;

    if (locator != null && locator.getInputFilePath() != null) {
      fileLocation = locator.getInputFilePath();
      if (fileLocation.startsWith(cwd)) {
        fileLocation = fileLocation.substring(cwd.length());
      }
    }

    final StringBuilder sb = new StringBuilder();
    if (locator != null && fileLocation != null) {
      sb.append("At ").append(fileLocation);

      if (locator.getBeginLine() >= 0) {
        sb.append(":").append(locator.getBeginLine());
        if (locator.getBeginColumn() >= 0) {
          sb.append(",").append(locator.getBeginColumn());
        }
      }
      sb.append(":\n |--> ");
      if (locator.getBeginLine() >= 0) {
        final File inputFile = new File(locator.getInputFilePath());
        if (inputFile.exists()) {
          try {
            final LineNumberReader reader = new LineNumberReader(new FileReader(inputFile));
            for (int i = 0; i < locator.getBeginLine() - 1; i++) {
              reader.readLine();
            }
            final String line = reader.readLine().replace("\t", "    ");
            sb.append("  ").append(line).append("\n |-->   ");
            if (locator.getBeginColumn() >= 0) {
              for (int i = 0; i < locator.getBeginColumn() - 1; i++) {
                sb.append(" ");
              }
              int end = line.length();
              if (locator.getEndColumn() >= 0 && locator.getBeginLine() == locator.getEndLine()) {
                end = locator.getEndColumn();
              }
              for (int i = locator.getBeginColumn(); i < end + 1; i++) {
                sb.append("-");
              }
              sb.append("\n |--> ");
            }
          } catch (final IOException e1) {
            // ignore
          }
        }
      }
    }
    sb.append(error.getMessage()).append("\n");
    Throwable cause = error.getCause();
    while (cause != null) {
      sb.append("caused by : ");
      sb.append(cause.getMessage()).append('\n');
      cause = cause.getCause();
    }
    return sb.toString();
  }