Repository: prettier/prettier-eslint (ts)

Issue:
It doesn't work with eslint v8
<!--
Thanks for your interest in the project. I appreciate bugs filed and PRs submitted!
Please make sure that you are familiar with and follow the Code of Conduct for
this project (found in the CODE_OF_CONDUCT.md file).

Please fill out this template with all the relevant information so we can
understand what's going on and fix the issue.

I'll probably ask you to submit the fix (after giving some direction). If you've
never done that before, that's great! Check this free short video tutorial to
learn how: http://kcd.im/pull-request
-->

**Versions**:

- `prettier-eslint` version: 9.0.2
- `node` version: 14
- `npm` (or `yarn`) version: 1.22.5

**Have you followed [the debugging tips](https://github.com/prettier/prettier-eslint/blob/master/README.md#debugging-issues)?**

Yes

**Relevant code or config**

```shell
prettier-eslint '**/*.{ts,tsx}' --list-different
```

**What I did:**



**What happened:**
![image](https://user-images.githubusercontent.com/19839331/139210561-d2f8b4d1-06c0-4dca-8637-1f480de0899f.png)

<!-- Please provide the full error message/screenshots/anything -->

**Reproduction repository:**

<!--
If possible, please create a repository that reproduces the issue with the
minimal amount of code possible.
-->

**Problem description:**
It doesn't work with eslint v8

**Suggested solution:**
update with [this document](https://eslint.org/docs/8.0.0/user-guide/migrating-to-8.0.0#remove-cliengine) to adapting eslint v8.





Pull request:
feat: :sparkles: Support ESLint 8
Closes #656

These are breaking changes as the ESLint API has changed with version 8.

Major change is that `format` is now asynchronous. This is because the `executeOnText` function (now `lintText`) https://github.com/eslint/eslint/blob/851f1f18bd1a5da32c1b645bfcb28fadc627ad9e/lib/eslint/eslint.js#L572 is asynchronous. I would have made my changes backward compatible, but there is no backward compatible method for the asynchronous change.

Patch:
diff --git a/.all-contributorsrc b/.all-contributorsrc
index d44891f..ee2f3c8 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -301,6 +301,15 @@
       "contributions": [
         "maintenance"
       ]
+    },
+    {
+      "login": "idahogurl",
+      "name": "Rebecca Vest",
+      "avatar_url": "https://avatars.githubusercontent.com/u/10620169?v=4",
+      "profile": "https://campcode.dev/",
+      "contributions": [
+        "code"
+      ]
     }
   ],
   "repoType": "github",
diff --git a/.eslintrc.js b/.eslintrc.js
index 6f6c05b..9c6d945 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,16 +1,17 @@
 const config = {
-  extends: ["kentcdodds", "kentcdodds/jest"],
+  extends: ['kentcdodds', 'kentcdodds/jest'],
   rules: {
-    "valid-jsdoc": "off",
-    "max-len": "off",
-    "space-before-function-paren": [
-      "error",
+    'valid-jsdoc': 'off',
+    'max-len': 'off',
+    'space-before-function-paren': [
+      'error',
       {
-        anonymous: "never",
-        named: "never",
-        asyncArrow: "always"
+        anonymous: 'never',
+        named: 'never',
+        asyncArrow: 'always'
       }
-    ]
+    ],
+    'import/no-import-module-exports': 'off'
   }
 };
 
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 8cc8a93..929c521 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,6 +1,6 @@
 name: CI
 
-on: [push]
+on: [push, pull_request]
 
 jobs:
   ci:
diff --git a/.prettierrc.js b/.prettierrc.js
new file mode 100644
index 0000000..e4d181d
--- /dev/null
+++ b/.prettierrc.js
@@ -0,0 +1,4 @@
+module.exports = {
+  arrowParens: 'avoid',
+  singleQuote: true
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index 87e0135..f653315 100644
--- a/README.md
+++ b/README.md
@@ -72,7 +72,7 @@ const options = {
   },
 };
 
-const formatted = format(options);
+const formatted = await format(options);
 
 // notice no semicolon in the formatted text
 formatted; // const { foo } = bar
@@ -304,6 +304,7 @@ Thanks goes to these people ([emoji key][emojis]):
   </tr>
   <tr>
     <td align="center"><a href="https://github.com/cy6erskunk"><img src="https://avatars3.githubusercontent.com/u/754849?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Igor</b></sub></a><br /><a href="#maintenance-cy6erskunk" title="Maintenance">🚧</a></td>
+    <td align="center"><a href="https://campcode.dev/"><img src="https://avatars.githubusercontent.com/u/10620169?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Rebecca Vest</b></sub></a><br /><a href="https://github.com/prettier/prettier-eslint/commits?author=idahogurl" title="Code">💻</a></td>
   </tr>
 </table>
 
diff --git a/package.json b/package.json
index 86f3d82..acbb082 100644
--- a/package.json
+++ b/package.json
@@ -18,18 +18,18 @@
   ],
   "license": "MIT",
   "dependencies": {
-    "@typescript-eslint/parser": "^3.0.0",
+    "@typescript-eslint/parser": "^5.10.0",
     "common-tags": "^1.4.0",
     "dlv": "^1.1.0",
-    "eslint": "^7.9.0",
+    "eslint": "^8.7.0",
     "indent-string": "^4.0.0",
     "lodash.merge": "^4.6.0",
     "loglevel-colored-level-prefix": "^1.0.0",
-    "prettier": "^2.0.0",
+    "prettier": "^2.5.1",
     "pretty-format": "^23.0.1",
     "require-relative": "^0.8.7",
-    "typescript": "^3.9.3",
-    "vue-eslint-parser": "~7.1.0"
+    "typescript": "^4.5.4",
+    "vue-eslint-parser": "^8.0.1"
   },
   "devDependencies": {
     "@babel/cli": "^7.4.4",
@@ -40,7 +40,7 @@
     "all-contributors-cli": "^6.7.0",
     "babel-jest": "^25.0.0",
     "chalk": "^2.1.0",
-    "eslint-config-kentcdodds": "~16.0.1",
+    "eslint-config-kentcdodds": "^20.0.1",
     "husky": "^2.4.1",
     "jest": "^25.0.0",
     "jest-cli": "^25.0.0",
diff --git a/src/__mocks__/eslint.js b/src/__mocks__/eslint.js
index 10369ec..dced55a 100644
--- a/src/__mocks__/eslint.js
+++ b/src/__mocks__/eslint.js
@@ -2,35 +2,35 @@
 // search around the file system for stuff
 
 const eslint = jest.requireActual('eslint');
-const { CLIEngine } = eslint;
+const { ESLint } = eslint;
 
-const mockGetConfigForFileSpy = jest.fn(mockGetConfigForFile);
-mockGetConfigForFileSpy.overrides = {};
-const mockExecuteOnTextSpy = jest.fn(mockExecuteOnText);
+const mockCalculateConfigForFileSpy = jest.fn(mockCalculateConfigForFile);
+mockCalculateConfigForFileSpy.overrides = {};
+const mockLintTextSpy = jest.fn(mockLintText);
 
 module.exports = Object.assign(eslint, {
-  CLIEngine: jest.fn(MockCLIEngine),
+  ESLint: jest.fn(MockESLint),
   mock: {
-    getConfigForFile: mockGetConfigForFileSpy,
-    executeOnText: mockExecuteOnTextSpy
+    calculateConfigForFile: mockCalculateConfigForFileSpy,
+    lintText: mockLintTextSpy
   }
 });
 
-function MockCLIEngine(...args) {
+function MockESLint(...args) {
   global.__PRETTIER_ESLINT_TEST_STATE__.eslintPath = __filename;
-  const cliEngine = new CLIEngine(...args);
-  cliEngine.getConfigForFile = mockGetConfigForFileSpy;
-  cliEngine._originalExecuteOnText = cliEngine.executeOnText;
-  cliEngine.executeOnText = mockExecuteOnTextSpy;
-  return cliEngine;
+  const eslintInstance = new ESLint(...args);
+  eslintInstance.calculateConfigForFile = mockCalculateConfigForFileSpy;
+  eslintInstance._originalLintText = eslintInstance.lintText;
+  eslintInstance.lintText = mockLintTextSpy;
+  return eslintInstance;
 }
 
-MockCLIEngine.prototype = Object.create(CLIEngine.prototype);
+MockESLint.prototype = Object.create(ESLint.prototype);
 
 // eslint-disable-next-line complexity
-function mockGetConfigForFile(filePath) {
-  if (mockGetConfigForFileSpy.throwError) {
-    throw mockGetConfigForFileSpy.throwError;
+function mockCalculateConfigForFile(filePath) {
+  if (mockCalculateConfigForFileSpy.throwError) {
+    throw mockCalculateConfigForFileSpy.throwError;
   }
   if (!filePath) {
     return {
@@ -71,10 +71,10 @@ function mockGetConfigForFile(filePath) {
   }
 }
 
-function mockExecuteOnText(...args) {
-  /* eslint babel/no-invalid-this:0 */
-  if (mockExecuteOnTextSpy.throwError) {
-    throw mockExecuteOnTextSpy.throwError;
+function mockLintText(...args) {
+  /* eslint no-invalid-this:0 */
+  if (mockLintTextSpy.throwError) {
+    throw mockLintTextSpy.throwError;
   }
-  return this._originalExecuteOnText(...args);
+  return this._originalLintText(...args);
 }
diff --git a/src/index.js b/src/index.js
index 60d53eb..e730b0e 100644
--- a/src/index.js
+++ b/src/index.js
@@ -9,11 +9,7 @@ import { oneLine, stripIndent } from 'common-tags';
 import indentString from 'indent-string';
 import getLogger from 'loglevel-colored-level-prefix';
 import merge from 'lodash.merge';
-import {
-  getESLintCLIEngine,
-  getOptionsForFormatting,
-  requireModule
-} from './utils';
+import { getESLint, getOptionsForFormatting, requireModule } from './utils';
 
 const logger = getLogger({ prefix: 'prettier-eslint' });
 
@@ -44,7 +40,7 @@ module.exports = format;
  * @param {Boolean} options.prettierLast - Run Prettier Last
  * @return {String} - the formatted string
  */
-function format(options) {
+async function format(options) {
   const { logLevel = getDefaultLogLevel() } = options;
   logger.setLevel(logLevel);
   logger.trace('called format with options:', prettyFormat(options));
@@ -64,12 +60,6 @@ function format(options) {
     getESLintConfig(filePath, eslintPath)
   );
 
-  if (typeof eslintConfig.globals === 'object') {
-    eslintConfig.globals = Object.entries(eslintConfig.globals).map(
-      ([key, value]) => `${key}:${value}`
-    );
-  }
-
   const prettierOptions = merge(
     {},
     filePath && { filepath: filePath },
@@ -131,10 +121,11 @@ function format(options) {
       formattingOptions.eslint.parser || require.resolve('vue-eslint-parser');
   }
 
-  const eslintFix = createEslintFix(formattingOptions.eslint, eslintPath);
+  const eslintFix = await createEslintFix(formattingOptions.eslint, eslintPath);
 
   if (prettierLast) {
-    return prettify(eslintFix(text, filePath));
+    const eslintFixed = await eslintFix(text, filePath);
+    return prettify(eslintFixed);
   }
   return eslintFix(prettify(text), filePath);
 }
@@ -151,7 +142,7 @@ function createPrettify(formatOptions, prettierPath) {
     );
     const prettier = requireModule(prettierPath, 'prettier');
     try {
-      logger.trace(`calling prettier.format with the text and prettierOptions`);
+      logger.trace('calling prettier.format with the text and prettierOptions');
       const output = prettier.format(text, formatOptions);
       logger.trace('prettier: output === input', output === text);
       logger.trace(
@@ -170,18 +161,45 @@ function createPrettify(formatOptions, prettierPath) {
 }
 
 function createEslintFix(eslintConfig, eslintPath) {
-  return function eslintFix(text, filePath) {
-    const cliEngine = getESLintCLIEngine(eslintPath, eslintConfig);
+  return async function eslintFix(text, filePath) {
+    if (Array.isArray(eslintConfig.globals)) {
+      const tempGlobals = {};
+      eslintConfig.globals.forEach(g => {
+        const [key, value] = g.split(':');
+        tempGlobals[key] = value;
+      });
+      eslintConfig.globals = tempGlobals;
+    }
+
+    eslintConfig.overrideConfig = {
+      rules: eslintConfig.rules,
+      parser: eslintConfig.parser,
+      globals: eslintConfig.globals,
+      parserOptions: eslintConfig.parserOptions,
+      ignorePatterns: eslintConfig.ignorePattern,
+      ...eslintConfig.overrideConfig
+    };
+
+    delete eslintConfig.rules;
+    delete eslintConfig.parser;
+    delete eslintConfig.parserOptions;
+    delete eslintConfig.globals;
+    delete eslintConfig.ignorePattern;
+
+    const eslint = getESLint(eslintPath, eslintConfig);
     try {
-      logger.trace(`calling cliEngine.executeOnText with the text`);
-      const report = cliEngine.executeOnText(text, filePath, true);
+      logger.trace('calling cliEngine.executeOnText with the text');
+      const report = await eslint.lintText(text, {
+        filePath,
+        warnIgnored: true
+      });
       logger.trace(
-        `executeOnText returned the following report:`,
+        'executeOnText returned the following report:',
         prettyFormat(report)
       );
       // default the output to text because if there's nothing
       // to fix, eslint doesn't provide `output`
-      const [{ output = text }] = report.results;
+      const [{ output = text }] = await report;
       logger.trace('eslint --fix: output === input', output === text);
       // NOTE: We're ignoring linting errors/warnings here and
       // defaulting to the given text if there are any
@@ -233,10 +251,10 @@ function getESLintConfig(filePath, eslintPath) {
       "${filePath || process.cwd()}"
     `
   );
-  const cliEngine = getESLintCLIEngine(eslintPath, eslintOptions);
+  const eslint = getESLint(eslintPath, eslintOptions);
   try {
     logger.debug(`getting eslint config for file at "${filePath}"`);
-    const config = cliEngine.getConfigForFile(filePath);
+    const config = eslint.calculateConfigForFile(filePath);
     logger.trace(
       `eslint config for "${filePath}" received`,
       prettyFormat(config)
diff --git a/src/utils.js b/src/utils.js
index acfa3d5..3ebd1ce 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -2,6 +2,7 @@
 import { oneLine } from 'common-tags';
 import delve from 'dlv';
 import getLogger from 'loglevel-colored-level-prefix';
+import { Linter } from 'eslint';
 
 const logger = getLogger({ prefix: 'prettier-eslint' });
 const RULE_DISABLED = {};
@@ -57,15 +58,14 @@ const OPTION_GETTERS = {
 };
 
 /* eslint import/prefer-default-export:0 */
-export { getESLintCLIEngine, getOptionsForFormatting, requireModule };
+export { getESLint, getOptionsForFormatting, requireModule };
 
 function getOptionsForFormatting(
   eslintConfig,
   prettierOptions = {},
-  fallbackPrettierOptions = {},
-  eslintPath
+  fallbackPrettierOptions = {}
 ) {
-  const eslint = getRelevantESLintConfig(eslintConfig, eslintPath);
+  const eslint = getRelevantESLintConfig(eslintConfig);
   const prettier = getPrettierOptionsFromESLintRules(
     eslintConfig,
     prettierOptions,
@@ -74,37 +74,24 @@ function getOptionsForFormatting(
   return { eslint, prettier };
 }
 
-function getRelevantESLintConfig(eslintConfig, eslintPath) {
-  const cliEngine = getESLintCLIEngine(eslintPath);
-  // TODO: Actually test this branch
-  // istanbul ignore next
-  const loadedRules =
-    (cliEngine.getRules && cliEngine.getRules()) ||
-    // XXX: Fallback list of unfixable rules, when using and old version of eslint
-    new Map([['global-require', { meta: {} }], ['no-with', { meta: {} }]]);
-
-  const { rules } = eslintConfig;
-
+function getRelevantESLintConfig(eslintConfig) {
+  const linter = new Linter();
+  const rules = linter.getRules();
   logger.debug('turning off unfixable rules');
 
-  const relevantRules = Object.entries(rules).reduce(
-    (rulesAccumulator, [name, rule]) => {
-      if (loadedRules.has(name)) {
-        const {
-          meta: { fixable }
-        } = loadedRules.get(name);
-
-        if (!fixable) {
-          logger.trace('turing off rule:', JSON.stringify({ [name]: rule }));
-          rule = ['off'];
-        }
-      }
+  const relevantRules = {};
 
-      rulesAccumulator[name] = rule;
-      return rulesAccumulator;
-    },
-    {}
-  );
+  rules.forEach((rule, name) => {
+    const {
+      meta: { fixable }
+    } = rule;
+
+    if (!fixable) {
+      logger.trace('turning off rule:', JSON.stringify({ [name]: rule }));
+      rule = ['off'];
+      relevantRules[name] = rule;
+    }
+  }, {});
 
   return {
     // defaults
@@ -114,9 +101,9 @@ function getRelevantESLintConfig(eslintConfig, eslintPath) {
     },
     ...eslintConfig,
     // overrides
-    rules: relevantRules,
+    rules: { ...eslintConfig.rules, ...relevantRules },
     fix: true,
-    globals: []
+    globals: eslintConfig.globals || {}
   };
 }
 
@@ -417,12 +404,12 @@ function requireModule(modulePath, name) {
   }
 }
 
-function getESLintCLIEngine(eslintPath, eslintOptions) {
-  const { CLIEngine } = requireModule(eslintPath, 'eslint');
+function getESLint(eslintPath, eslintOptions) {
+  const { ESLint } = requireModule(eslintPath, 'eslint');
   try {
-    return new CLIEngine(eslintOptions);
+    return new ESLint(eslintOptions);
   } catch (error) {
-    logger.error(`There was trouble creating the ESLint CLIEngine.`);
+    logger.error('There was trouble creating the ESLint CLIEngine.');
     throw error;
   }
 }


Test patch:
diff --git a/src/__tests__/index.js b/src/__tests__/index.js
index 1098bb2..3ef58b0 100644
--- a/src/__tests__/index.js
+++ b/src/__tests__/index.js
@@ -63,7 +63,6 @@ const tests = [
     input: {
       text: 'const { foo } = bar;',
       eslintConfig: {
-        foo: true,
         // Won't be overridden
         parserOptions: {
           ecmaVersion: 7
@@ -140,6 +139,14 @@ const tests = [
     },
     output: 'var [foo, { bar }] = window.APP;'
   },
+  {
+    title: 'accepts config globals as array',
+    input: {
+      text: defaultInputText(),
+      eslintConfig: { globals: ['window:writable'] }
+    },
+    output: noopOutput()
+  },
   {
     title: 'CSS example',
     input: {
@@ -180,8 +187,7 @@ const tests = [
           'space-before-function-paren': [2, 'always']
         }
       },
-      text:
-        '<template>\n  <div></div>\n</template>\n<script>\nfunction foo() { return "foo" }\n</script>\n<style>\n</style>',
+      text: '<template>\n  <div></div>\n</template>\n<script>\nfunction foo() { return "foo" }\n</script>\n<style>\n</style>',
       filePath: path.resolve('./test.vue')
     },
     output:
@@ -226,8 +232,8 @@ const tests = [
 ];
 
 beforeEach(() => {
-  eslintMock.mock.executeOnText.mockClear();
-  eslintMock.mock.getConfigForFile.mockClear();
+  eslintMock.mock.lintText.mockClear();
+  eslintMock.mock.calculateConfigForFile.mockClear();
   prettierMock.format.mockClear();
   prettierMock.resolveConfig.sync.mockClear();
   fsMock.readFileSync.mockClear();
@@ -240,55 +246,55 @@ tests.forEach(({ title, modifier, input, output }) => {
   if (modifier) {
     fn = test[modifier];
   }
-  fn(title, () => {
+  fn(title, async () => {
     input.text = stripIndent(input.text).trim();
     const expected = stripIndent(output).trim();
-    const actual = format(input);
+    const actual = await format(input);
     // adding the newline in the expected because
     // prettier adds a newline to the end of the input
     expect(actual).toBe(`${expected}\n`);
   });
 });
 
-test('failure to fix with eslint throws and logs an error', () => {
-  const { executeOnText } = eslintMock.mock;
+test('failure to fix with eslint throws and logs an error', async () => {
+  const { lintText } = eslintMock.mock;
   const error = new Error('Something happened');
-  executeOnText.throwError = error;
+  lintText.throwError = error;
 
-  expect(() => format({ text: '' })).toThrowError(error);
+  await expect(() => format({ text: '' })).rejects.toThrowError(error);
   expect(logger.error).toHaveBeenCalledTimes(1);
-  executeOnText.throwError = null;
+  lintText.throwError = null;
 });
 
-test('logLevel is used to configure the logger', () => {
+test('logLevel is used to configure the logger', async () => {
   logger.setLevel = jest.fn();
-  format({ text: '', logLevel: 'silent' });
+  await format({ text: '', logLevel: 'silent' });
   expect(logger.setLevel).toHaveBeenCalledTimes(1);
   expect(logger.setLevel).toHaveBeenCalledWith('silent');
 });
 
-test(`when prettier throws, log to logger.error and throw the error`, () => {
+test('when prettier throws, log to logger.error and throw the error', async () => {
   const error = new Error('something bad happened');
   prettierMock.format.throwError = error;
 
-  expect(() => format({ text: '' })).toThrowError(error);
+  await expect(() => format({ text: '' })).rejects.toThrowError(error);
   expect(logger.error).toHaveBeenCalledTimes(1);
   prettierMock.format.throwError = null;
 });
 
-test('can accept a path to an eslint module and uses that instead.', () => {
+test('can accept a path to an eslint module and uses that instead.', async () => {
   const eslintPath = path.join(__dirname, '../__mocks__/eslint');
-  format({ text: '', eslintPath });
-  expect(eslintMock.mock.executeOnText).toHaveBeenCalledTimes(1);
+  await format({ text: '', eslintPath });
+  expect(eslintMock.mock.lintText).toHaveBeenCalledTimes(1);
 });
 
-test('fails with an error if the eslint module cannot be resolved.', () => {
+test('fails with an error if the eslint module cannot be resolved.', async () => {
   const eslintPath = path.join(
     __dirname,
     '../__mocks__/non-existent-eslint-module'
   );
 
-  expect(() => format({ text: '', eslintPath })).toThrowError(
+  await expect(() => format({ text: '', eslintPath })).rejects.toThrowError(
     /non-existent-eslint-module/
   );
   expect(logger.error).toHaveBeenCalledTimes(1);
@@ -300,19 +306,20 @@ test('fails with an error if the eslint module cannot be resolved.', () => {
   expect(logger.error).toHaveBeenCalledWith(errorString);
 });
 
-test('can accept a path to a prettier module and uses that instead.', () => {
+test('can accept a path to a prettier module and uses that instead.', async () => {
   const prettierPath = path.join(__dirname, '../__mocks__/prettier');
-  format({ text: '', prettierPath });
+  await format({ text: '', prettierPath });
+
   expect(prettierMock.format).toHaveBeenCalledTimes(1);
 });
 
-test('fails with an error if the prettier module cannot be resolved.', () => {
+test('fails with an error if the prettier module cannot be resolved.', async () => {
   const prettierPath = path.join(
     __dirname,
     '../__mocks__/non-existent-prettier-module'
   );
 
-  expect(() => format({ text: '', prettierPath })).toThrowError(
+  await expect(() => format({ text: '', prettierPath })).rejects.toThrowError(
     /non-existent-prettier-module/
   );
   expect(logger.error).toHaveBeenCalledTimes(1);
@@ -322,9 +329,9 @@ test('fails with an error if the prettier module cannot be resolved.', () => {
   expect(logger.error).toHaveBeenCalledWith(errorString);
 });
 
-test('resolves to the eslint module relative to the given filePath', () => {
+test('resolves to the eslint module relative to the given filePath', async () => {
   const filePath = require.resolve('../../tests/fixtures/paths/foo.js');
-  format({ text: '', filePath });
+  await format({ text: '', filePath });
   const stateObj = {
     eslintPath: require.resolve(
       '../../tests/fixtures/paths/node_modules/eslint/index.js'
@@ -336,9 +343,9 @@ test('resolves to the eslint module relative to the given filePath', () => {
   expect(global.__PRETTIER_ESLINT_TEST_STATE__).toMatchObject(stateObj);
 });
 
-test('resolves to the local eslint module', () => {
+test('resolves to the local eslint module', async () => {
   const filePath = '/blah-blah/default-config.js';
-  format({ text: '', filePath });
+  await format({ text: '', filePath });
   expect(global.__PRETTIER_ESLINT_TEST_STATE__).toMatchObject({
     // without Jest's mocking, these would actually resolve to the
     // project modules :) The fact that jest's mocking is being
@@ -348,31 +355,30 @@ test('resolves to the local eslint module', () => {
   });
 });
 
-test('reads text from fs if filePath is provided but not text', () => {
+test('reads text from fs if filePath is provided but not text', async () => {
   const readFileSyncMockSpy = jest.spyOn(fsMock, 'readFileSync');
 
   const filePath = '/blah-blah/some-file.js';
-  format({ filePath });
-  
-  expect(readFileSyncMockSpy).toHaveBeenCalledWith(filePath, 'utf8');
+  await format({ filePath });
 
+  expect(readFileSyncMockSpy).toHaveBeenCalledWith(filePath, 'utf8');
 });
 
-test('logs error if it cannot read the file from the filePath', () => {
+test('logs error if it cannot read the file from the filePath', async () => {
   const originalMock = fsMock.readFileSync;
   fsMock.readFileSync = jest.fn(() => {
     throw new Error('some error');
   });
-  expect(() => format({ filePath: '/some-path.js' })).toThrowError(
-    /some error/
-  );
+  await expect(() =>
+    format({ filePath: '/some-path.js' })
+  ).rejects.toThrowError(/some error/);
   expect(logger.error).toHaveBeenCalledTimes(1);
   fsMock.readFileSync = originalMock;
 });
 
-test('calls prettier.resolveConfig.sync with the file path', () => {
+test('calls prettier.resolveConfig.sync with the file path', async () => {
   const filePath = require.resolve('../../tests/fixtures/paths/foo.js');
-  format({
+  await format({
     filePath,
     text: defaultInputText(),
     eslintConfig: getESLintConfigWithDefaultRules()
@@ -399,12 +405,12 @@ test('does not raise an error if prettier.resolveConfig.sync is not defined', ()
   prettierMock.resolveConfig.sync = originalPrettierMockResolveConfigSync;
 });
 
-test('does not raise an error if prettier.resolveConfig is not defined', () => {
+test('does not raise an error if prettier.resolveConfig is not defined', async () => {
   const filePath = require.resolve('../../tests/fixtures/paths/foo.js');
   const originalPrettierMockResolveConfig = prettierMock.resolveConfig;
   prettierMock.resolveConfig = undefined;
 
-  function callingFormat() {
+  async function callingFormat() {
     return format({
       filePath,
       text: defaultInputText(),
@@ -412,18 +418,18 @@ test('does not raise an error if prettier.resolveConfig is not defined', () => {
     });
   }
 
-  expect(callingFormat).not.toThrowError();
+  await expect(callingFormat).not.toThrowError();
 
   prettierMock.resolveConfig = originalPrettierMockResolveConfig;
 });
 
-test('logs if there is a problem making the CLIEngine', () => {
+test('logs if there is a problem making the CLIEngine', async () => {
   const error = new Error('fake error');
-  eslintMock.CLIEngine.mockImplementation(() => {
+  eslintMock.ESLint.mockImplementation(() => {
     throw error;
   });
-  expect(() => format({ text: '' })).toThrowError(error);
-  eslintMock.CLIEngine.mockReset();
+  await expect(() => format({ text: '' })).rejects.toThrowError(error);
+  eslintMock.ESLint.mockReset();
   expect(logger.error).toHaveBeenCalledTimes(1);
 });
 
diff --git a/src/__tests__/utils.js b/src/__tests__/utils.js
index 0a84398..458bc0e 100644
--- a/src/__tests__/utils.js
+++ b/src/__tests__/utils.js
@@ -211,7 +211,7 @@ test('if prettierOptions are provided, those are preferred', () => {
 });
 
 // eslint-disable-next-line max-len
-test(`if fallbacks are provided, those are preferred over disabled eslint rules`, () => {
+test('if fallbacks are provided, those are preferred over disabled eslint rules', () => {
   const { prettier } = getOptionsForFormatting(
     {
       rules: {
@@ -309,7 +309,7 @@ test('Turn off unfixable rules', () => {
       quotes: ['error', 'double']
     },
     fix: true,
-    globals: [],
+    globals: {},
     useEslintrc: false
   });
 });
diff --git a/tests/fixtures/paths/node_modules/eslint/index.js b/tests/fixtures/paths/node_modules/eslint/index.js
index 1544d74..592f4f4 100644
--- a/tests/fixtures/paths/node_modules/eslint/index.js
+++ b/tests/fixtures/paths/node_modules/eslint/index.js
@@ -1,11 +1,11 @@
 const eslintMock = require('../../../../../src/__mocks__/eslint')
 module.exports = Object.assign({}, eslintMock, {
-  CLIEngine: MockMockCLIEngine
+  ESLint: MockMockESLint
 })
 
-function MockMockCLIEngine(...args) {
+function MockMockESLint(...args) {
   try {
-    return eslintMock.CLIEngine.apply(this, args)
+    return eslintMock.ESLint.apply(this, args)
   } finally {
     global.__PRETTIER_ESLINT_TEST_STATE__.eslintPath = __filename
   }