From d59ff217cefa3a8bb55fa2cfeaf90206fece8d36 Mon Sep 17 00:00:00 2001 From: skovhus Date: Tue, 3 Mar 2020 11:14:40 +0100 Subject: [PATCH 1/2] Relax TypeScript, eslint will take care of this --- .eslintrc.js | 1 + tsconfig.base.json | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index d5c86c2fb..5eccb269a 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -50,6 +50,7 @@ module.exports = { 'prefer-const': 'error', 'prefer-template': 'error', 'simple-import-sort/sort': 'error', + 'object-shorthand': 'error', '@typescript-eslint/explicit-function-return-type': 'off', '@typescript-eslint/explicit-member-accessibility': 'off', diff --git a/tsconfig.base.json b/tsconfig.base.json index 0bc130438..8d4211ac9 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -1,7 +1,5 @@ { "compilerOptions": { - "noUnusedLocals": true, - "noUnusedParameters": true, "noImplicitAny": true, "noImplicitReturns": true, "strict": true, From 8a86d4c5d779190e80bd5dc0230cacbf3ca6a3f3 Mon Sep 17 00:00:00 2001 From: skovhus Date: Tue, 3 Mar 2020 11:16:16 +0100 Subject: [PATCH 2/2] Increase server test coverage from 53 to 70% --- .../__snapshots__/server.test.ts.snap | 15 ++ server/src/__tests__/server.test.ts | 178 ++++++++++++++++++ testing/fixtures.ts | 23 ++- 3 files changed, 208 insertions(+), 8 deletions(-) create mode 100644 server/src/__tests__/__snapshots__/server.test.ts.snap create mode 100644 server/src/__tests__/server.test.ts diff --git a/server/src/__tests__/__snapshots__/server.test.ts.snap b/server/src/__tests__/__snapshots__/server.test.ts.snap new file mode 100644 index 000000000..b3a440109 --- /dev/null +++ b/server/src/__tests__/__snapshots__/server.test.ts.snap @@ -0,0 +1,15 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`server initializes and responds to capabilities 1`] = ` +Object { + "completionProvider": Object { + "resolveProvider": true, + }, + "definitionProvider": true, + "documentHighlightProvider": true, + "documentSymbolProvider": true, + "hoverProvider": true, + "referencesProvider": true, + "textDocumentSync": 1, +} +`; diff --git a/server/src/__tests__/server.test.ts b/server/src/__tests__/server.test.ts new file mode 100644 index 000000000..8fc74981f --- /dev/null +++ b/server/src/__tests__/server.test.ts @@ -0,0 +1,178 @@ +import * as lsp from 'vscode-languageserver' + +import { FIXTURE_FOLDER, FIXTURE_URI } from '../../../testing/fixtures' +import LspServer from '../server' + +async function initializeServer() { + const diagnostics: Array = undefined + const console: any = { + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + log: jest.fn(), + } + + const connection: jest.Mocked = { + client: {} as any, + console, + dispose: jest.fn(), + listen: jest.fn(), + onCodeAction: jest.fn(), + onCodeLens: jest.fn(), + onCodeLensResolve: jest.fn(), + onColorPresentation: jest.fn(), + onCompletion: jest.fn(), + onCompletionResolve: jest.fn(), + onDeclaration: jest.fn(), + onDefinition: jest.fn(), + onDidChangeConfiguration: jest.fn(), + onDidChangeTextDocument: jest.fn(), + onDidChangeWatchedFiles: jest.fn(), + onDidCloseTextDocument: jest.fn(), + onDidOpenTextDocument: jest.fn(), + onDidSaveTextDocument: jest.fn(), + onDocumentColor: jest.fn(), + onDocumentFormatting: jest.fn(), + onDocumentHighlight: jest.fn(), + onDocumentLinkResolve: jest.fn(), + onDocumentLinks: jest.fn(), + onDocumentOnTypeFormatting: jest.fn(), + onDocumentRangeFormatting: jest.fn(), + onDocumentSymbol: jest.fn(), + onExecuteCommand: jest.fn(), + onExit: jest.fn(), + onFoldingRanges: jest.fn(), + onHover: jest.fn(), + onImplementation: jest.fn(), + onInitialize: jest.fn(), + onInitialized: jest.fn(), + onNotification: jest.fn(), + onPrepareRename: jest.fn(), + onReferences: jest.fn(), + onRenameRequest: jest.fn(), + onRequest: jest.fn(), + onShutdown: jest.fn(), + onSignatureHelp: jest.fn(), + onTypeDefinition: jest.fn(), + onWillSaveTextDocument: jest.fn(), + onWillSaveTextDocumentWaitUntil: jest.fn(), + onWorkspaceSymbol: jest.fn(), + sendDiagnostics: jest.fn(), + sendNotification: jest.fn(), + sendRequest: jest.fn(), + telemetry: {} as any, + tracer: {} as any, + window: {} as any, + workspace: {} as any, + } + + const server = await LspServer.initialize(connection, { + rootPath: FIXTURE_FOLDER, + rootUri: undefined, + processId: 42, + capabilities: {} as any, + workspaceFolders: null, + }) + + return { + connection, + console, + diagnostics, + server, + } +} + +describe('server', () => { + it('initializes and responds to capabilities', async () => { + const { server } = await initializeServer() + expect(server.capabilities()).toMatchSnapshot() + }) + + it('register LSP connection', async () => { + const { connection, server } = await initializeServer() + + server.register(connection) + + expect(connection.onHover).toHaveBeenCalledTimes(1) + expect(connection.onDefinition).toHaveBeenCalledTimes(1) + expect(connection.onDocumentSymbol).toHaveBeenCalledTimes(1) + expect(connection.onDocumentHighlight).toHaveBeenCalledTimes(1) + expect(connection.onReferences).toHaveBeenCalledTimes(1) + expect(connection.onCompletion).toHaveBeenCalledTimes(1) + expect(connection.onCompletionResolve).toHaveBeenCalledTimes(1) + }) + + it('responds to onHover', async () => { + const { connection, server } = await initializeServer() + server.register(connection) + + const onHover = connection.onHover.mock.calls[0][0] + + const result = await onHover( + { + textDocument: { + uri: FIXTURE_URI.INSTALL, + }, + position: { + line: 25, + character: 5, + }, + }, + {} as any, + ) + + expect(result).toBeDefined() + expect(result).toEqual({ + contents: { + kind: 'markdown', + value: expect.stringContaining('RM(1)'), + }, + }) + }) + + it('responds to onCompletion when word is found', async () => { + const { connection, server } = await initializeServer() + server.register(connection) + + const onCompletion = connection.onCompletion.mock.calls[0][0] + + const result = await onCompletion( + { + textDocument: { + uri: FIXTURE_URI.INSTALL, + }, + position: { + line: 25, + character: 5, + }, + }, + {} as any, + ) + + // Entire list + expect('length' in result && result.length > 50) + }) + + it('responds to onCompletion when no word is found', async () => { + const { connection, server } = await initializeServer() + server.register(connection) + + const onCompletion = connection.onCompletion.mock.calls[0][0] + + const result = await onCompletion( + { + textDocument: { + uri: FIXTURE_URI.INSTALL, + }, + position: { + line: 2, + character: 1, + }, + }, + {} as any, + ) + + // Entire list + expect('length' in result && result.length > 50) + }) +}) diff --git a/testing/fixtures.ts b/testing/fixtures.ts index 1c3624d40..e3aaf5095 100644 --- a/testing/fixtures.ts +++ b/testing/fixtures.ts @@ -4,20 +4,27 @@ import * as LSP from 'vscode-languageserver' export const FIXTURE_FOLDER = path.join(__dirname, './fixtures/') -function getFixture(filename: string) { +function getDocument(uri: string) { return LSP.TextDocument.create( 'foo', 'bar', 0, - fs.readFileSync(path.join(FIXTURE_FOLDER, filename), 'utf8'), + fs.readFileSync(uri.replace('file://', ''), 'utf8'), ) } -const FIXTURES = { - MISSING_NODE: getFixture('missing-node.sh'), - ISSUE101: getFixture('issue101.sh'), - INSTALL: getFixture('install.sh'), - PARSE_PROBLEMS: getFixture('parse-problems.sh'), +export const FIXTURE_URI = { + MISSING_NODE: `file://${path.join(FIXTURE_FOLDER, 'missing-node.sh')}`, + ISSUE101: `file://${path.join(FIXTURE_FOLDER, 'issue101.sh')}`, + INSTALL: `file://${path.join(FIXTURE_FOLDER, 'install.sh')}`, + PARSE_PROBLEMS: `file://${path.join(FIXTURE_FOLDER, 'parse-problems.sh')}`, } -export default FIXTURES +export const FIXTURE_DOCUMENT = { + MISSING_NODE: getDocument(FIXTURE_URI.MISSING_NODE), + ISSUE101: getDocument(FIXTURE_URI.ISSUE101), + INSTALL: getDocument(FIXTURE_URI.INSTALL), + PARSE_PROBLEMS: getDocument(FIXTURE_URI.PARSE_PROBLEMS), +} + +export default FIXTURE_DOCUMENT