Skip to content

Commit

Permalink
Add ESLint6 (#471)
Browse files Browse the repository at this point in the history
* Bring channel/eslint-4 missing dep (#461)

* Upgrade eslint-plugin-ember (#467)

* Upgrade Eslint plugin packages (#470)

* Update ESLint

* wip

* Use node_gc - erroring for whatever reason

* Format

* Disable problematics - to be reverted and fixed

* ESLint6 patch module loading

* Remove eslint5 patch

* Fix typos

* Fix configuration loading

* Disabled blocked rules

* Add prettier

* Avoid printing warn of disabling a rule that is already off

* Add blocked settings and clean ups

* Remove unused

* Avoid too much STDERR messages

* Remove unused

* Code format

* Fix debugger data

* Rules and Settings blocking might be hooked into the final config extraction to properly work

* Better output
  • Loading branch information
filipesperandio authored Nov 18, 2019
1 parent e202de2 commit 7dc6d36
Show file tree
Hide file tree
Showing 29 changed files with 1,334 additions and 1,905 deletions.
1 change: 1 addition & 0 deletions .codeclimate.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
engines:
eslint:
enabled: true
channel: eslint-5
duplication:
enabled: true
config:
Expand Down
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
**/*{.,-}min.js
20 changes: 20 additions & 0 deletions .eslintrc.base.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module.exports = {
rules: {
"brace-style": [2, "1tbs", { allowSingleLine: true }],
camelcase: [2, { properties: "always" }],
"comma-style": [2, "first", { exceptions: { ArrayExpression: true, ObjectExpression: true } }],
complexity: [2, 6],
curly: [2, "all"],
eqeqeq: [2, "allow-null"],
"no-shadow-restricted-names": 2,
"no-nested-ternary": 2,
"no-undef": 2,
"no-unused-vars": [2, { argsIgnorePattern: "^_" }],
"no-use-before-define": 2,
quotes: [2, "double", "avoid-escape"],
radix: 2,
semi: 2,
"space-infix-ops": 2,
strict: 0,
},
}
31 changes: 31 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module.exports = {
env: {
browser: true,
jquery: true,
es6: true,
},
parserOptions: {
sourceType: "module",
ecmaFeatures: {
experimentalObjectRestSpread: true,
},
},
extends: ["eslint:recommended", "plugin:react/recommended", ".eslintrc.base.js"],
rules: {
semi: 0,
"brace-style": 0,
"comma-style": 0,
},
globals: {
Chart: true,
Cookies: true,
flatpickr: true,
FS: true,
heap: true,
Highcharts: true,
Intercom: true,
Stripe: true,
THREE: true,
Tablesort: true,
},
}
5 changes: 5 additions & 0 deletions .prettierrc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
arrowParens: "always"
jsxBracketSameLine: true
semi: false
trailingComma: "es5"
printWidth: 100
Empty file.
226 changes: 140 additions & 86 deletions integration/eslint_test.js
Original file line number Diff line number Diff line change
@@ -1,164 +1,218 @@
const sinon = require("sinon");
const expect = require("chai").expect;
const sinon = require("sinon")
const expect = require("chai").expect

const ESLint = require('../lib/eslint');
const fs = require("fs");
const ESLint = require("../lib/eslint")
const fs = require("fs")
const path = require("path")
const temp = require('temp');
const temp = require("temp")

describe("eslint integration", function() {
let consoleMock = {};
let consoleMock = {}
const STDERR = console.error

function executeConfig(configPath) {
return ESLint.run(consoleMock, { dir: __dirname, configPath: `${__dirname}/${configPath}`});
return ESLint.run(consoleMock, { dir: __dirname, configPath: `${__dirname}/${configPath}` })
}

beforeEach(function() {
consoleMock.output = [];
consoleMock.log = function(msg) { consoleMock.output.push(msg) };
consoleMock.error = sinon.spy();
});
consoleMock.output = []
consoleMock.outputErr = []
consoleMock.log = function() {
consoleMock.output.push(...arguments)
}
consoleMock.error = console.error = function() {
consoleMock.outputErr.push(...arguments)
}
})

describe("eslintrc has not supported plugins", function() {
afterEach(function() {
console.error = STDERR
})

describe("eslintrc files with not supported plugins in it", function() {
it("does not raise any error", function() {
this.timeout(3000);
this.timeout(3000)

function executeUnsupportedPlugins() {
executeConfig("with_unsupported_plugins/config.json");
executeConfig("with_unsupported_plugins/config.json")
}

expect(executeUnsupportedPlugins).to.not.throw();
expect(consoleMock.output).to.not.be.empty;
});
});
expect(executeUnsupportedPlugins).to.not.throw()
expect(consoleMock.output).to.not.be.empty
})
})

describe("validating config", function() {
it("warns about empty config but not raise error", function() {
function executeEmptyConfig() {
executeConfig("empty_config/config.json");
executeConfig("empty_config/config.json")
}

expect(executeEmptyConfig).to.not.throw();
sinon.assert.calledWith(consoleMock.error, 'No rules are configured. Make sure you have added a config file with rules enabled.');
});
});
expect(executeEmptyConfig).to.not.throw()
expect(consoleMock.outputErr).to.include(
"No rules are configured. Make sure you have added a config file with rules enabled."
)
})

it("raise on file not found", function() {
function executeNoLintrc() {
executeConfig("no_lintrc/config.json")
}

expect(executeNoLintrc).to.throw()
})

it("turns off blocked rules", function() {
executeConfig("with_unsupported_rules/config.json")

expect(consoleMock.outputErr).to.include(
"Ignoring the following rules that rely on module resolution:",
"\n\t * import/extensions"
)
})

it("remove blocked setting", function() {
executeConfig("with_unsupported_rules/config.json")

expect(consoleMock.outputErr).to.include(
"Ignoring the following settings that rely on module resolution:",
"\n\t * import/resolver"
)
})
})

describe("extends plugin", function() {
it("loads the plugin and does not include repeated issues of not found rules", function() {
this.timeout(5000);
executeConfig("extends_airbnb/config.json");
this.timeout(8000)

executeConfig("extends_airbnb/config.json")

const ruleDefinitionIssues = consoleMock.output.filter(function(o) { return o.includes("Definition for rule"); });
expect(ruleDefinitionIssues).to.be.empty;
});
});
const ruleDefinitionIssues = consoleMock.output.filter(function(o) {
return o.includes("Definition for rule")
})
expect(ruleDefinitionIssues).to.be.empty
})
})

describe("sanitization", function() {
function withMinifiedSource(config, cb, done) {
temp.mkdir("code", function(err, directory) {
if (err) { throw err; }
if (err) {
throw err
}

process.chdir(directory);
process.chdir(directory)

const eslintConfigPath = path.join(directory, ".eslintrc.json");
const eslintConfigPath = path.join(directory, ".eslintrc.json")
fs.writeFile(eslintConfigPath, "{}", function(err) {
if (err) { throw err; }

const sourcePath = path.join(directory, "index.js");
fs.writeFile(sourcePath,
[...Array(13).keys()].map(()=>{ return "void(0);"; }).join(""), // a long string of voids
if (err) {
throw err
}

const sourcePath = path.join(directory, "index.js")
fs.writeFile(
sourcePath,
[...Array(13).keys()]
.map(() => {
return "void(0);"
})
.join(""), // a long string of voids
function(err) {
if (err) { throw err; }
if (err) {
throw err
}

const configPath = path.join(directory, "config.json");
const configPath = path.join(directory, "config.json")
fs.writeFile(
configPath,
JSON.stringify({
"enabled": true,
"config": config,
"include_paths": [sourcePath]
enabled: true,
config: config,
include_paths: [sourcePath],
}),
function(err) {
if (err) { throw err; }
if (err) {
throw err
}

cb(directory);
cb(directory)

done();
done()
}
);
)
}
);
});
});
)
})
})
}

const BatchSanitizer = require("../lib/batch_sanitizer");
const CLIEngine = require('../lib/eslint-patch')().CLIEngine;
const BatchSanitizer = require("../lib/batch_sanitizer")
const CLIEngine = require("../lib/eslint6-patch")().eslint.CLIEngine

beforeEach(() => {
sinon.spy(BatchSanitizer.prototype, "sanitizedFiles");
sinon.spy(CLIEngine.prototype, "executeOnFiles");
});
sinon.spy(BatchSanitizer.prototype, "sanitizedFiles")
sinon.spy(CLIEngine.prototype, "executeOnFiles")
})

afterEach(() => {
BatchSanitizer.prototype.sanitizedFiles.restore();
CLIEngine.prototype.executeOnFiles.restore();
});
BatchSanitizer.prototype.sanitizedFiles.restore()
CLIEngine.prototype.executeOnFiles.restore()
})

it("is performed by default", function(done) {
this.timeout(5000);
this.timeout(5000)

withMinifiedSource(
{},
function(dir) {
ESLint.run(consoleMock, { dir: dir, configPath: `${dir}/config.json`});
ESLint.run(consoleMock, { dir: dir, configPath: `${dir}/config.json` })

expect(BatchSanitizer.prototype.sanitizedFiles.callCount).to.eql(1);
expect(CLIEngine.prototype.executeOnFiles.firstCall.args).to.eql([[]]);
expect(BatchSanitizer.prototype.sanitizedFiles.callCount).to.eql(1)
expect(CLIEngine.prototype.executeOnFiles.firstCall.args).to.eql([[]])
},
done
);
});
)
})

it("is performed by when explicitly specified", function(done) {
this.timeout(5000);
it("is performed when explicitly specified", function(done) {
this.timeout(5000)

withMinifiedSource(
{ sanitize_batch: true },
function(dir) {
ESLint.run(consoleMock, { dir: dir, configPath: `${dir}/config.json`});
ESLint.run(consoleMock, { dir: dir, configPath: `${dir}/config.json` })

expect(BatchSanitizer.prototype.sanitizedFiles.callCount).to.eql(1);
expect(CLIEngine.prototype.executeOnFiles.firstCall.args).to.eql([[]]);
expect(BatchSanitizer.prototype.sanitizedFiles.callCount).to.eql(1)
expect(CLIEngine.prototype.executeOnFiles.firstCall.args).to.eql([[]])
},
done
);
});
)
})

it("is can be disabled", function(done) {
this.timeout(5000);
it("can be disabled", function(done) {
this.timeout(5000)

withMinifiedSource(
{ sanitize_batch: false },
function(dir) {
ESLint.run(consoleMock, { dir: dir, configPath: `${dir}/config.json`});
ESLint.run(consoleMock, { dir: dir, configPath: `${dir}/config.json` })

expect(BatchSanitizer.prototype.sanitizedFiles.callCount).to.eql(0);
expect(CLIEngine.prototype.executeOnFiles.firstCall.args).to.eql([[`${dir}/index.js`]]);
expect(BatchSanitizer.prototype.sanitizedFiles.callCount).to.eql(0)
expect(CLIEngine.prototype.executeOnFiles.firstCall.args).to.eql([[`${dir}/index.js`]])
},
done
);
});
});
)
})
})

describe("output", function() {
it("is not messed up", function() {
this.timeout(5000);

executeConfig("output_mess/config.json");
this.timeout(5000)

expect(consoleMock.output).to.have.lengthOf(1);
expect(consoleMock.output[0]).to.match(/^\{.*/);
});
});
executeConfig("output_mess/config.json")

});
expect(consoleMock.output).to.have.lengthOf(1)
expect(consoleMock.output[0]).to.match(/^\{.*/)
})
})
})
10 changes: 10 additions & 0 deletions integration/no_lintrc/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"enabled": true,
"config": {
"config": "no_lintrc/eslintrc.yml",
"debug": "false"
},
"include_paths": [
"/usr/src/app/integration/no_lintrc/index.js"
]
}
2 changes: 2 additions & 0 deletions integration/no_lintrc/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
function dummy() {
}
10 changes: 10 additions & 0 deletions integration/with_unsupported_rules/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"enabled": true,
"config": {
"config": "with_unsupported_rules/eslintrc.yml",
"debug": "true"
},
"include_paths": [
"/usr/src/app/integration/with_unsupported_rules/index.js"
]
}
Loading

0 comments on commit 7dc6d36

Please sign in to comment.