diff --git a/.eslintrc.json b/.eslintrc.json index 5d5fa8ee..d0610ac6 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,7 +1,17 @@ { - "extends": "eslint-config-atomic/strict", + "extends": ["eslint-config-atomic/strict", "plugin:chai-friendly/recommended"], "ignorePatterns": ["build/", "node_modules/"], "rules": { + "no-eq-null": "warn", + "eqeqeq": "warn", + "no-empty-function": "warn", + "class-methods-use-this": "warn", + "default-case": "warn", + "no-new": "warn", + "no-shadow": "warn", + "no-invalid-this": "warn", + "require-await": "warn", + "no-useless-constructor": "warn", "@typescript-eslint/ban-types": [ "error", { @@ -16,7 +26,7 @@ "allowArgumentsExplicitlyTypedAsAny": true } ], - "@typescript-eslint/no-empty-function": "off", + "@typescript-eslint/no-empty-function": "warn", "@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/no-unused-vars": [ "error", diff --git a/lib/adapters/command-execution-adapter.ts b/lib/adapters/command-execution-adapter.ts index 3edab77d..b6b895f7 100644 --- a/lib/adapters/command-execution-adapter.ts +++ b/lib/adapters/command-execution-adapter.ts @@ -14,7 +14,8 @@ export default class CommandExecutionAdapter { this.commandsCustomCallbacks.set(command, callback) } - public static async executeCommand( + /** Returns a {Promise} */ + public static executeCommand( connection: LanguageClientConnection, command: string, commandArgs?: any[] @@ -23,13 +24,13 @@ export default class CommandExecutionAdapter { const commandCustomCallback = this.commandsCustomCallbacks.get(command) return commandCustomCallback !== undefined - ? await commandCustomCallback(executeCommandParams) - : await connection.executeCommand(executeCommandParams) + ? commandCustomCallback(executeCommandParams) + : connection.executeCommand(executeCommandParams) } private static createExecuteCommandParams(command: string, commandArgs?: any[]): ExecuteCommandParams { return { - command: command, + command, arguments: commandArgs, } } diff --git a/lib/adapters/outline-view-adapter.ts b/lib/adapters/outline-view-adapter.ts index 6bf03ba2..1a56fa40 100644 --- a/lib/adapters/outline-view-adapter.ts +++ b/lib/adapters/outline-view-adapter.ts @@ -111,11 +111,13 @@ export default class OutlineViewAdapter { * @returns An {OutlineTree} containing the given symbols that the Outline View can display. */ public static createOutlineTrees(symbols: SymbolInformation[]): atomIde.OutlineTree[] { - symbols.sort((a, b) => - a.location.range.start.line === b.location.range.start.line - ? a.location.range.start.character - b.location.range.start.character - : a.location.range.start.line - b.location.range.start.line - ) + symbols.sort((a, b) => { + if (a.location.range.start.line === b.location.range.start.line) { + return a.location.range.start.character - b.location.range.start.character + } else { + return a.location.range.start.line - b.location.range.start.line + } + }) // Temporarily keep containerName through the conversion process // Also filter out symbols without a name - it's part of the spec but some don't include it diff --git a/lib/auto-languageclient.ts b/lib/auto-languageclient.ts index 62eed42b..e0a3651d 100644 --- a/lib/auto-languageclient.ts +++ b/lib/auto-languageclient.ts @@ -428,7 +428,9 @@ export default class AutoLanguageClient { lsProcess.on("close", (code, signal) => this.onSpawnClose(code, signal)) lsProcess.on("disconnect", () => this.onSpawnDisconnect()) lsProcess.on("exit", (code, signal) => this.onSpawnExit(code, signal)) + // eslint-disable-next-line chai-friendly/no-unused-expressions lsProcess.stderr?.setEncoding("utf8") + // eslint-disable-next-line chai-friendly/no-unused-expressions lsProcess.stderr?.on("data", (chunk: Buffer) => this.onSpawnStdErrData(chunk, projectPath)) } diff --git a/lib/download-file.ts b/lib/download-file.ts index 2e0c0ddf..bb998327 100644 --- a/lib/download-file.ts +++ b/lib/download-file.ts @@ -60,6 +60,8 @@ async function streamWithProgress( // eslint-disable-next-line no-constant-condition while (true) { + // TODO use Promise.all + // eslint-disable-next-line no-await-in-loop const result = await reader.read() if (result.done) { if (progressCallback != null) { diff --git a/lib/server-manager.ts b/lib/server-manager.ts index 42035730..ca3db69b 100644 --- a/lib/server-manager.ts +++ b/lib/server-manager.ts @@ -138,7 +138,8 @@ export class ServerManager { if (startingPromise) { return startingPromise } - + // TODO remove eslint-disable + // eslint-disable-next-line no-return-await return shouldStart && this._startForEditor(textEditor) ? await this.startServer(finalProjectPath) : null } diff --git a/package.json b/package.json index 333c478c..f2c31c78 100644 --- a/package.json +++ b/package.json @@ -38,11 +38,9 @@ "@types/mocha": "^8.2.0", "@types/node": "14.14.22", "@types/sinon": "^9.0.10", - "@typescript-eslint/eslint-plugin": "^4.14.1", - "@typescript-eslint/parser": "^4.14.1", "chai": "^4.2.0", - "eslint": "^7.18.0", - "eslint-config-atomic": "1.10.1", + "eslint-config-atomic": "^1.14.0", + "eslint-plugin-chai-friendly": "^0.6.0", "mocha": "^8.2.1", "mocha-appveyor-reporter": "^0.4.2", "shx": "^0.3.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 977a0c06..5725aa20 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,7 +15,8 @@ devDependencies: '@typescript-eslint/parser': 4.15.2_eslint@7.20.0+typescript@4.1.5 chai: 4.3.0 eslint: 7.20.0 - eslint-config-atomic: 1.10.2_eslint@7.20.0 + eslint-config-atomic: 1.12.2_eslint@7.20.0 + eslint-plugin-chai-friendly: 0.6.0_eslint@7.20.0 mocha: 8.3.0 mocha-appveyor-reporter: 0.4.2 shx: 0.3.3 @@ -1384,7 +1385,7 @@ packages: eslint-plugin-react-hooks: ^4 || ^3 || ^2.3.0 || ^1.7.0 resolution: integrity: sha512-glZNDEZ36VdlZWoxn/bUR1r/sdFKPd1mHPbqUtkctgNG4yT2DLLtJ3D+yCV+jzZCc2V1nBVkmdknOJBZ5Hc0fg== - /eslint-config-atomic/1.10.2_eslint@7.20.0: + /eslint-config-atomic/1.12.2_eslint@7.20.0: dependencies: '@babel/core': 7.13.1 '@typescript-eslint/eslint-plugin': 4.15.2_bd37cc6d9e4ef1f78f94a852ca0107ce @@ -1392,7 +1393,7 @@ packages: babel-eslint: 10.1.0_eslint@7.20.0 coffeescript: 1.12.7 eslint: 7.20.0 - eslint-config-prettier: 7.2.0_eslint@7.20.0 + eslint-config-prettier: 8.1.0_eslint@7.20.0 eslint-plugin-coffee: 0.1.14_eslint@7.20.0 eslint-plugin-import: 2.22.1_eslint@7.20.0 eslint-plugin-json: 2.1.2 @@ -1407,8 +1408,8 @@ packages: peerDependencies: eslint: '>=7' resolution: - integrity: sha512-hLut/mAB6tBzpHI93A9+ej26AGc7LKt+ZmUtJbWgohEFyXcEWnJqMuJ9F0kYCvlUbR61BFdvxKN6PGtuYtad4Q== - /eslint-config-prettier/7.2.0_eslint@7.20.0: + integrity: sha512-3RxvRCSWTV8B3iINXGCPiZh8m63YyaWrIbBMSoRMkqdE1eTnUD8Zy1miP44ypadldisqgk7ezWuUywjYqxpIJA== + /eslint-config-prettier/8.1.0_eslint@7.20.0: dependencies: eslint: 7.20.0 dev: true @@ -1416,7 +1417,7 @@ packages: peerDependencies: eslint: '>=7.0.0' resolution: - integrity: sha512-rV4Qu0C3nfJKPOAhFujFxB7RMP+URFyQqqOZW9DMRD7ZDTFyjaIlETU3xzHELt++4ugC0+Jm084HQYkkJe+Ivg== + integrity: sha512-oKMhGv3ihGbCIimCAjqkdzx2Q+jthoqnXSP+d86M9tptwugycmTFdVR4IpLgq2c4SHifbwO90z2fQ8/Aio73yw== /eslint-import-resolver-node/0.3.4: dependencies: debug: 2.6.9 @@ -1433,6 +1434,16 @@ packages: node: '>=4' resolution: integrity: sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA== + /eslint-plugin-chai-friendly/0.6.0_eslint@7.20.0: + dependencies: + eslint: 7.20.0 + dev: true + engines: + node: '>=0.10.0' + peerDependencies: + eslint: '>=3.0.0' + resolution: + integrity: sha512-Uvvv1gkbRGp/qfN15B0kQyQWg+oFA8buDSqrwmW3egNSk/FpqH2MjQqKOuKwmEL6w4QIQrIjDp+gg6kGGmD3oQ== /eslint-plugin-coffee/0.1.14_eslint@7.20.0: dependencies: axe-core: 3.5.5 @@ -3885,7 +3896,8 @@ specifiers: atom-ide-base: ^2.4.0 chai: ^4.2.0 eslint: ^7.18.0 - eslint-config-atomic: ^1.10.1 + eslint-config-atomic: ^1.12.2 + eslint-plugin-chai-friendly: ^0.6.0 mocha: ^8.2.1 mocha-appveyor-reporter: ^0.4.2 shx: ^0.3.3 diff --git a/test/adapters/apply-edit-adapter.test.ts b/test/adapters/apply-edit-adapter.test.ts index 406e4818..429e3f53 100644 --- a/test/adapters/apply-edit-adapter.test.ts +++ b/test/adapters/apply-edit-adapter.test.ts @@ -12,7 +12,7 @@ const TEST_PATH4 = normalizeDriveLetterName(path.join(__dirname, "test4.txt")) function normalizeDriveLetterName(filePath: string): string { if (process.platform === "win32") { - return filePath.replace(/^([a-z]):/, ([driveLetter]) => driveLetter.toUpperCase() + ":") + return filePath.replace(/^([a-z]):/, ([driveLetter]) => `${driveLetter.toUpperCase()}:`) } else { return filePath } diff --git a/test/adapters/autocomplete-adapter.test.ts b/test/adapters/autocomplete-adapter.test.ts index dacdd76a..8fd5b645 100644 --- a/test/adapters/autocomplete-adapter.test.ts +++ b/test/adapters/autocomplete-adapter.test.ts @@ -44,7 +44,7 @@ describe("AutoCompleteAdapter", () => { type getSuggestionParams = Parameters /** Function that stubs `server.connection.completion` and returns the `autoCompleteAdapter.getSuggestions(...)` */ - async function getSuggestionsMock( + function getSuggestionsMock( items: CompletionItem[], request: getSuggestionParams[1], onDidConvertCompletionItem?: getSuggestionParams[2], @@ -288,7 +288,7 @@ describe("AutoCompleteAdapter", () => { it("respects onDidConvertCompletionItem", async () => { const results = await getSuggestionsMock([{ label: "label" }], createRequest({}), (c, a, r) => { - ;(a as ac.TextSuggestion).text = c.label + " ok" + ;(a as ac.TextSuggestion).text = `${c.label} ok` a.displayText = r.scopeDescriptor.getScopesArray()[0] }) @@ -448,7 +448,7 @@ describe("AutoCompleteAdapter", () => { expect(result.replacementPrefix).equals("") }) - describe("applies changes from TextEdit to text", async () => { + describe("applies changes from TextEdit to text", () => { const customRequest = createRequest({ prefix: "", position: new Point(0, 10) }) customRequest.editor.setText("foo #align bar") @@ -473,7 +473,7 @@ describe("AutoCompleteAdapter", () => { expect((results[0] as TextSuggestion).customReplacmentPrefix).equals("#align") }) - describe("applies the change if shouldReplace is true", async () => { + describe("applies the change if shouldReplace is true", () => { it("1", async () => { const results = await getSuggestionsMock( [ @@ -575,7 +575,7 @@ describe("AutoCompleteAdapter", () => { }) }) - describe("applies the change if shouldReplace is false", async () => { + describe("applies the change if shouldReplace is false", () => { it("1", async () => { const results = await getSuggestionsMock( [ diff --git a/test/adapters/code-action-adapter.test.ts b/test/adapters/code-action-adapter.test.ts index 635d6874..c9121a38 100644 --- a/test/adapters/code-action-adapter.test.ts +++ b/test/adapters/code-action-adapter.test.ts @@ -57,7 +57,7 @@ describe("CodeActionAdapter", () => { expect((languageClient as any).codeAction.called).to.be.true const args = (languageClient as any).codeAction.getCalls()[0].args const params: ls.CodeActionParams = args[0] - expect(params.textDocument.uri).to.equal("file://" + testPath) + expect(params.textDocument.uri).to.equal(`file://${testPath}`) expect(params.range).to.deep.equal({ start: { line: 1, character: 2 }, end: { line: 3, character: 4 }, diff --git a/test/adapters/show-document-adapter.test.ts b/test/adapters/show-document-adapter.test.ts index 900e2497..ce6b85d6 100644 --- a/test/adapters/show-document-adapter.test.ts +++ b/test/adapters/show-document-adapter.test.ts @@ -10,21 +10,23 @@ import { createSpyConnection } from "../helpers" describe("ShowDocumentAdapter", () => { describe("can attach to a server", () => { - it("subscribes to onShowDocument", async () => { + it("subscribes to onShowDocument", () => { const connection = createSpyConnection() const lcc = new LanguageClientConnection(connection) const spy = sinon.spy() - lcc["_onRequest"] = spy + // eslint-disable-next-line dot-notation + lcc["_onRequest"] = spy // private method access ShowDocumentAdapter.attach(lcc) + // eslint-disable-next-line dot-notation expect((lcc["_onRequest"] as sinon.SinonSpy).calledOnce).to.be.true const spyArgs = spy.firstCall.args expect(spyArgs[0]).to.deep.equal({ method: "window/showDocument" }) expect(spyArgs[1]).to.equal(ShowDocumentAdapter.showDocument) }) - it("onRequest connection is called", async () => { + it("onRequest connection is called", () => { const connection = createSpyConnection() const lcc = new LanguageClientConnection(connection) @@ -39,7 +41,7 @@ describe("ShowDocumentAdapter", () => { }) }) describe("can show documents", () => { - describe("shows the document inside Atom", async () => { + describe("shows the document inside Atom", () => { const helloPath = join(dirname(__dirname), "fixtures", "hello.js") async function canShowDocumentInAtom(params: ShowDocumentParams) { diff --git a/test/auto-languageclient.test.ts b/test/auto-languageclient.test.ts index 94b9c9c2..52b0e355 100644 --- a/test/auto-languageclient.test.ts +++ b/test/auto-languageclient.test.ts @@ -31,12 +31,12 @@ describe("AutoLanguageClient", () => { }) it("does not select documents in unsupported language", () => { - const editor = mockEditor("/path/to/somewhere", client.getGrammarScopes()[0] + "-dummy") + const editor = mockEditor("/path/to/somewhere", `${client.getGrammarScopes()[0]}-dummy`) expect(client.shouldSyncForEditor(editor, "/path/to/somewhere")).equals(false) }) it("does not select documents in unsupported language outside of project", () => { - const editor = mockEditor("/path/to/elsewhere/file", client.getGrammarScopes()[0] + "-dummy") + const editor = mockEditor("/path/to/elsewhere/file", `${client.getGrammarScopes()[0]}-dummy`) expect(client.shouldSyncForEditor(editor, "/path/to/somewhere")).equals(false) }) }) diff --git a/test/convert.test.ts b/test/convert.test.ts index ae87ed3d..526dacbb 100644 --- a/test/convert.test.ts +++ b/test/convert.test.ts @@ -132,7 +132,7 @@ describe("Convert", () => { it("uses getath which returns a path to create the URI", () => { const path = "/c/d/e/f/g/h/i/j.txt" const identifier = Convert.editorToTextDocumentIdentifier(createFakeEditor(path)) - expect(identifier.uri).equals("file://" + path) + expect(identifier.uri).equals(`file://${path}`) }) }) @@ -142,7 +142,7 @@ describe("Convert", () => { const editor = createFakeEditor(path, "abc\ndefgh\nijkl") editor.setCursorBufferPosition(new Point(1, 2)) const params = Convert.editorToTextDocumentPositionParams(editor) - expect(params.textDocument.uri).equals("file://" + path) + expect(params.textDocument.uri).equals(`file://${path}`) expect(params.position).deep.equals({ line: 1, character: 2 }) }) @@ -152,7 +152,7 @@ describe("Convert", () => { const editor = createFakeEditor(path, "abcdef\nghijkl\nmnopq") editor.setCursorBufferPosition(new Point(1, 1)) const params = Convert.editorToTextDocumentPositionParams(editor, specifiedPoint) - expect(params.textDocument.uri).equals("file://" + path) + expect(params.textDocument.uri).equals(`file://${path}`) expect(params.position).deep.equals({ line: 911, character: 112 }) }) }) diff --git a/test/utils.test.ts b/test/utils.test.ts index 731680c0..2f3fda0d 100644 --- a/test/utils.test.ts +++ b/test/utils.test.ts @@ -50,7 +50,7 @@ describe("Utils", () => { it("returns the exe path under bin folder by default", () => { let expectedExe = join(process.cwd(), "bin", `${process.platform}-${process.arch}`, "serve-d") if (process.platform === "win32") { - expectedExe = expectedExe + ".exe" + expectedExe = `${expectedExe}.exe` } const fsMock = sinon.mock(fs) @@ -65,7 +65,7 @@ describe("Utils", () => { const rootPath = join(__dirname, `${process.platform}-${process.arch}`) let expectedExe = join(rootPath, "serve-d") if (process.platform === "win32") { - expectedExe = expectedExe + ".exe" + expectedExe = `${expectedExe}.exe` } const fsMock = sinon.mock(fs)