"use strict";

require("core-js/modules/es.promise.js");

require("core-js/modules/es.string.trim.js");

require("core-js/modules/es.array.iterator.js");

var _fs = _interopRequireDefault(require("fs"));

var _findUp = _interopRequireDefault(require("find-up"));

var _prettierEslint = _interopRequireDefault(require("prettier-eslint"));

var _glob = _interopRequireDefault(require("glob"));

var _getStdin = _interopRequireDefault(require("get-stdin"));

var _loglevelColoredLevelPrefix = _interopRequireDefault(require("loglevel-colored-level-prefix"));

var _formatFiles = _interopRequireDefault(require("./format-files"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/* eslint no-console:0 */
jest.mock('fs');
beforeEach(() => {
  process.stdout.write = jest.fn();
  console.error = jest.fn();
  console.log = jest.fn();

  _prettierEslint.default.mockClear();

  _fs.default.writeFile.mockClear();

  _fs.default.readFile.mockClear();
});
afterEach(() => {
  process.exitCode = 0;
});
test('sanity test', async () => {
  const globs = ['src/**/1*.js', 'src/**/2*.js'];
  await (0, _formatFiles.default)({
    _: globs
  });
  expect(_glob.default).toHaveBeenCalledTimes(globs.length);
  expect(_fs.default.readFile).toHaveBeenCalledTimes(6);
  expect(_prettierEslint.default).toHaveBeenCalledTimes(6);
  expect(_fs.default.writeFile).toHaveBeenCalledTimes(0);
  expect(process.stdout.write).toHaveBeenCalledTimes(6);
  expect(console.error).toHaveBeenCalledTimes(1);
  const mockOutput = expect.stringMatching(/MOCK_OUTPUT.*index.js/);
  const successOutput = expect.stringMatching(/success.*6.*files/);
  expect(process.stdout.write).toHaveBeenCalledWith(mockOutput);
  expect(console.error).toHaveBeenCalledWith(successOutput);
});
test('glob call inclues an ignore of node_modules', async () => {
  const fileGlob = 'src/**/1*.js';
  await (0, _formatFiles.default)({
    _: [fileGlob]
  });
  const globOptions = expect.objectContaining({
    ignore: expect.arrayContaining(['**/node_modules/**'])
  });
  const callback = expect.any(Function);
  expect(_glob.default).toHaveBeenCalledWith(fileGlob, globOptions, callback);
});
test('glob call excludes an ignore of node_modules', async () => {
  const fileGlob = 'foo/node_modules/stuff*.js';
  await (0, _formatFiles.default)({
    _: [fileGlob]
  });
  expect(_glob.default).not.toHaveBeenCalledWith(expect.any, expect.objectContaining({
    // should not have an ignore with **/node_modules/**
    ignore: expect.arrayContaining(['**/node_modules/**'])
  }), expect.any);
});
test('should accept stdin', async () => {
  _getStdin.default.stdin = '  var [ foo, {  bar } ] = window.APP ;';
  await (0, _formatFiles.default)({
    stdin: true
  });
  expect(_prettierEslint.default).toHaveBeenCalledTimes(1); // the trim is part of the test

  const text = _getStdin.default.stdin.trim();

  expect(_prettierEslint.default).toHaveBeenCalledWith(expect.objectContaining({
    text
  }));
  expect(process.stdout.write).toHaveBeenCalledTimes(1);
  expect(process.stdout.write).toHaveBeenCalledWith('MOCK_OUTPUT for stdin');
});
test('will write to files if that is specified', async () => {
  const fileGlob = 'src/**/1*.js';
  await (0, _formatFiles.default)({
    _: [fileGlob],
    write: true
  });
  expect(_fs.default.writeFile).toHaveBeenCalledTimes(4);
});
test('handles stdin errors gracefully', async () => {
  _getStdin.default.stdin = 'MOCK_SYNTAX_ERROR';
  await (0, _formatFiles.default)({
    stdin: true
  });
  expect(console.error).toHaveBeenCalledTimes(1);
});
test('handles file errors gracefully', async () => {
  const globs = ['files-with-syntax-errors/*.js', 'src/**/1*.js'];
  await (0, _formatFiles.default)({
    _: globs,
    write: true
  });
  expect(_fs.default.writeFile).toHaveBeenCalledTimes(4);
  expect(console.error).toHaveBeenCalledTimes(4);
  const successOutput = expect.stringMatching(/success.*4.*files/);
  const failureOutput = expect.stringMatching(/failure.*2.*files/);
  expect(console.error).toHaveBeenCalledWith(successOutput);
  expect(console.error).toHaveBeenCalledWith(failureOutput);
});
test('does not print success if there were no successful files', async () => {
  await (0, _formatFiles.default)({
    _: ['no-match/*.js']
  });
  const successOutput = expect.stringMatching(/unhandled error/);
  expect(process.stdout.write).not.toHaveBeenCalledWith(successOutput);
});
test('fails gracefully if something odd happens', async () => {
  await (0, _formatFiles.default)({
    _: ['throw-error/*.js']
  });
  expect(console.error).toHaveBeenCalledTimes(1);
  const label = expect.stringMatching(/prettier-eslint-cli/);
  const notice = expect.stringMatching(/unhandled error/);
  const errorStack = expect.stringMatching(/something weird happened/);
  expect(console.error).toHaveBeenCalledWith(label, notice, errorStack);
});
test('logs errors to the console if something goes wrong', async () => {
  const globs = ['eslint-config-error/*.js', 'src/**/2*.js'];
  await (0, _formatFiles.default)({
    _: globs,
    write: true
  });
  expect(_fs.default.writeFile).toHaveBeenCalledTimes(4);
  expect(console.error).toHaveBeenCalledTimes(4);
  const successOutput = expect.stringMatching(/success.*4.*files/);
  const failureOutput = expect.stringMatching(/failure.*2.*files/);
  expect(console.error).toHaveBeenCalledWith(successOutput);
  expect(console.error).toHaveBeenCalledWith(failureOutput);
  const errorPrefix = expect.stringMatching(/prettier-eslint-cli.*ERROR/);
  const cliError = expect.stringContaining('eslint-config-error');
  const errorOutput = expect.stringContaining('Some weird eslint config error');
  expect(console.error).toHaveBeenCalledWith(errorPrefix, cliError, errorOutput);
});
test('does not log anything to the console if logLevel is silent', async () => {
  const log = (0, _loglevelColoredLevelPrefix.default)();
  const globs = ['eslint-config-error/*.js', 'src/**/2*.js'];
  await (0, _formatFiles.default)({
    _: globs,
    write: true,
    logLevel: log.levels.SILENT
  });
  expect(_fs.default.writeFile).toHaveBeenCalledTimes(4);
  expect(console.error).not.toHaveBeenCalled();
});
test('forwards logLevel onto prettier-eslint', async () => {
  await (0, _formatFiles.default)({
    _: ['src/**/1*.js'],
    logLevel: 'debug'
  });
  const options = expect.objectContaining({
    logLevel: 'debug'
  });
  expect(_prettierEslint.default).toHaveBeenCalledWith(options);
});
test('forwards prettierLast onto prettier-eslint', async () => {
  await (0, _formatFiles.default)({
    _: ['src/**/1*.js'],
    prettierLast: true
  });
  expect(_prettierEslint.default).toHaveBeenCalledWith(expect.objectContaining({
    prettierLast: true
  }));
});
test('forwards prettierOptions onto prettier-eslint', async () => {
  await (0, _formatFiles.default)({
    _: ['src/**/1*.js'],
    trailingComma: 'es5'
  });
  expect(_prettierEslint.default).toHaveBeenCalledWith(expect.objectContaining({
    prettierOptions: {
      trailingComma: 'es5'
    }
  }));
});
test('wont save file if contents did not change', async () => {
  const fileGlob = 'no-change/*.js';
  await (0, _formatFiles.default)({
    _: [fileGlob],
    write: true
  });
  expect(_fs.default.readFile).toHaveBeenCalledTimes(3);
  expect(_fs.default.writeFile).toHaveBeenCalledTimes(0);
  const unchangedOutput = expect.stringMatching(/3.*?files.*?unchanged/);
  expect(console.error).toHaveBeenCalledWith(unchangedOutput);
});
test('will report unchanged files even if not written', async () => {
  const fileGlob = 'no-change/*.js';
  await (0, _formatFiles.default)({
    _: [fileGlob],
    write: false
  });
  expect(_fs.default.readFile).toHaveBeenCalledTimes(3);
  expect(_fs.default.writeFile).toHaveBeenCalledTimes(0);
  const unchangedOutput = expect.stringMatching(/3.*?files.*?unchanged/);
  expect(console.error).toHaveBeenCalledWith(unchangedOutput);
});
test('allows you to specify an ignore glob', async () => {
  const ignore = ['src/ignore/thing', 'src/ignore/otherthing'];
  const fileGlob = 'src/**/1*.js';
  await (0, _formatFiles.default)({
    _: [fileGlob],
    ignore
  });
  const globOptions = expect.objectContaining({
    ignore: [...ignore, '**/node_modules/**']
  });
  const callback = expect.any(Function);
  expect(_glob.default).toHaveBeenCalledWith(fileGlob, globOptions, callback);
});
test('wont modify a file if it is eslint ignored', async () => {
  await (0, _formatFiles.default)({
    _: ['src/**/eslintignored*.js'],
    write: true
  });
  expect(_fs.default.readFile).toHaveBeenCalledTimes(1);
  expect(_fs.default.writeFile).toHaveBeenCalledTimes(1);
  expect(_fs.default.readFile).toHaveBeenCalledWith(expect.stringMatching(/applied/), 'utf8', expect.any(Function));
  expect(_fs.default.writeFile).toHaveBeenCalledWith(expect.stringMatching(/applied/), expect.stringMatching(/MOCK_OUTPUT.*?applied/), expect.any(Function));
  const ignoredOutput = expect.stringMatching(/success.*1.*file/);
  expect(console.error).toHaveBeenCalledWith(ignoredOutput);
});
test('will modify a file if it is eslint ignored with noIgnore', async () => {
  await (0, _formatFiles.default)({
    _: ['src/**/eslintignored*.js'],
    write: true,
    eslintIgnore: false
  });
  expect(_fs.default.readFile).toHaveBeenCalledTimes(4);
  expect(_fs.default.writeFile).toHaveBeenCalledTimes(4);
  const ignoredOutput = expect.stringMatching(/success.*4.*files/);
  expect(console.error).toHaveBeenCalledWith(ignoredOutput);
});
test('wont modify a file if it is prettier ignored', async () => {
  await (0, _formatFiles.default)({
    _: ['src/**/prettierignored*.js'],
    write: true
  });
  expect(_fs.default.readFile).toHaveBeenCalledTimes(1);
  expect(_fs.default.writeFile).toHaveBeenCalledTimes(1);
  expect(_fs.default.readFile).toHaveBeenCalledWith(expect.stringMatching(/applied/), 'utf8', expect.any(Function));
  expect(_fs.default.writeFile).toHaveBeenCalledWith(expect.stringMatching(/applied/), expect.stringMatching(/MOCK_OUTPUT.*?applied/), expect.any(Function));
  const ignoredOutput = expect.stringMatching(/success.*1.*file/);
  expect(console.error).toHaveBeenCalledWith(ignoredOutput);
});
test('will modify a file if it is prettier ignored with noIgnore', async () => {
  await (0, _formatFiles.default)({
    _: ['src/**/prettierignored*.js'],
    write: true,
    prettierIgnore: false
  });
  expect(_fs.default.readFile).toHaveBeenCalledTimes(4);
  expect(_fs.default.writeFile).toHaveBeenCalledTimes(4);
  const ignoredOutput = expect.stringMatching(/success.*4.*files/);
  expect(console.error).toHaveBeenCalledWith(ignoredOutput);
});
test('will not blow up if an .eslintignore or .prettierignore cannot be found', async () => {
  const originalSync = _findUp.default.sync;

  _findUp.default.sync = () => null;

  try {
    await (0, _formatFiles.default)({
      _: ['src/**/no-ignore/*.js'],
      write: true
    });
  } finally {
    _findUp.default.sync = originalSync;
  }
});
describe('listDifferent', () => {
  test('will list different files', async () => {
    await (0, _formatFiles.default)({
      _: ['src/**/1*.js', 'src/**/no-change*.js'],
      listDifferent: true
    });
    expect(_fs.default.readFile).toHaveBeenCalledTimes(7);
    expect(_fs.default.writeFile).toHaveBeenCalledTimes(0);
    const unchangedOutput = expect.stringMatching(/3.*files were.*unchanged/);
    const successOutput = expect.stringMatching(/success.*4.*files/);
    expect(console.error).toHaveBeenCalledTimes(2);
    expect(console.error).toHaveBeenCalledWith(unchangedOutput);
    expect(console.error).toHaveBeenCalledWith(successOutput);
    const path = '/Users/fredFlintstone/Developer/top-secret/footless-carriage/';
    expect(console.log).toHaveBeenCalledTimes(4);
    expect(console.log).toHaveBeenCalledWith(`${path}stop/log.js`);
    expect(console.log).toHaveBeenCalledWith(`${path}stop/index.js`);
    expect(console.log).toHaveBeenCalledWith(`${path}index.js`);
    expect(console.log).toHaveBeenCalledWith(`${path}start.js`);
  });
  test('will error out when contents did change', async () => {
    const fileGlob = 'src/**/1*.js';
    await (0, _formatFiles.default)({
      _: [fileGlob],
      listDifferent: true
    });
    expect(process.exitCode).toBe(1);
  });
  test('wont error out when contents did not change', async () => {
    const fileGlob = 'no-change/*.js';
    await (0, _formatFiles.default)({
      _: [fileGlob],
      listDifferent: true
    });
    expect(process.exitCode).toBe(0);
  });
});
describe('eslintConfigPath', () => {
  test('will use eslintrc', async () => {
    await (0, _formatFiles.default)({
      _: ['src/**/1*.js'],
      eslintConfigPath: '.eslintrc'
    });
    expect(process.exitCode).toBe(0);
  });
});