Repository: babel/babel
File: packages/babel-parser/test/helpers/run-fixture-tests.js (JavaScript)

Code before:
function runParseTest(parse, test, onlyCompareErrors, ignoreLocations) {
  const { adjust, expected, source, filename, options } = test;

  if (!OVERWRITE && expected.threw && expected.ast) {
    throw Error(
      "File expected.json exists although options specify throws. Remove expected.json.",
    );
  }

  const actual = parseWithRecovery(parse, source, filename, options);

  if (ignoreLocations) {
    if (
      actual.ast &&
      expected.ast &&
      !actual.ast.errors &&
      !options.plugins?.includes("estree") &&
      !options.ranges
    ) {
      removeLocations(actual.ast);
      removeLocations(expected.ast);
    } else {
      return;
    }
  }

  const difference = new Difference(
    adjust,
    onlyCompareErrors ? toJustErrors(expected) : expected,
    onlyCompareErrors ? toJustErrors(actual) : actual,
  );

  // No differences means we passed and there's nothing left to do.
  if (difference === Difference.None) return;

  // We only write the output of the original test, not all it's auto-generated
  // variations.
  if (!test.original) return;

  const testLocation = test.taskDir;

  // FIXME: We're just maintaining the legacy behavior of storing *just* the
  // error `message` here, which differs from the error's `toString()` that we
  // store for each error in the `errors` array. In both cases, we should
  // serialize the full error to be able to property test locations,
  // reasonCodes, etc.
  const throws = actual.threw ? actual.threw.message : undefined;
  const optionsLocation = join(testLocation, "options.json");

  // We want to throw away the contents of `throws` here.
  const { throws: expectedThrows, ...oldOptions } = readJSON(optionsLocation);

Review comment (bug):
Thanks @liuxingbaoyu for working on this test!

Below in the file, when we are fuzzing and using random line/col/index, `test.original` will be false and thus the `if (!test.original) return` will suppress any error. Should we replace it with
```js
  if (!test.original) {
    const err = new Error();
    err.message = `Test Failed: ${testLocation}\nFixtureError.fromDifference: ${
      FixtureError.fromDifference(difference, actual).message
    }`;
    throw err;
  }
```

Code after:
  const { adjust, expected, source, filename, options } = test;

  if (!OVERWRITE && expected.threw && expected.ast) {
    throw Error(
      "File expected.json exists although options specify throws. Remove expected.json.",
    );
  }

  const actual = parseWithRecovery(parse, source, filename, options);

  if (ignoreLocations) {
    if (
      actual.ast &&
      expected.ast &&
      !actual.ast.errors &&
      !(options.plugins && options.plugins.includes("estree")) &&
      !options.ranges
    ) {
      removeLocations(actual.ast);
      removeLocations(expected.ast);
    } else {
      return;
    }
  }

  const difference = new Difference(
    adjust,
    onlyCompareErrors ? toJustErrors(expected) : expected,
    onlyCompareErrors ? toJustErrors(actual) : actual,
  );

  // No differences means we passed and there's nothing left to do.
  if (difference === Difference.None) return;

  // We only write the output of the original test, not all it's auto-generated
  // variations.
  if (!test.original) {
    const err = new Error();
    err.message = `Test Failed: ${testLocation}\nFixtureError.fromDifference: ${
      FixtureError.fromDifference(difference, actual).message
    }`;
    throw err;
  }

  const testLocation = test.taskDir;

  // FIXME: We're just maintaining the legacy behavior of storing *just* the
  // error `message` here, which differs from the error's `toString()` that we
  // store for each error in the `errors` array. In both cases, we should
  // serialize the full error to be able to property test locations,
  // reasonCodes, etc.