onivim / oni

Oni: Modern Modal Editing - powered by Neovim
https://www.onivim.io
MIT License
11.36k stars 300 forks source link

Implement testing strategy for Language Server Client #2246

Open akinsho opened 6 years ago

akinsho commented 6 years ago

Oni Version: Neovim Version (Linux only): Operating System:

Describe your issue

Following on from discussion in #1717, @bryphe raised the point that we could/should develop a strategy to test the lsp intergration separately for from the UI, possibly querying an lsp and testing how we handle responses. I've extracted this discussion out of #1717 to allow for clearer tracking of how to implement this this.

bryphe commented 6 years ago

Sweet, thanks for opening this issue @Akin909 !

Yes, definitely, I'd like to be able to test the LSP layer independently of Oni. This will give us much more agility when it comes to adding new features, and validating the existing set of features. Believe it or not, the LSP stuff is (relatively) stand-alone. I could see testing it at one of two layers - either at the LanguageClient layer, or at the LanguageManager layer (the LanguageManager layer is a bit higher, on top of LanguageClient, and depends a bit more on Oni abstractions).

For the LanguageClient layer, we'd need to: 1) Create a LanguageClientProcess. That takes a ServerRunOptions and InitializationOptions - it's pretty lightweight. An example might be:

const simplePathResolver = (filePath: string) => Promise.resolve(filePath)
const languageClientProcess = new LanguageClientProcess({ module: "/path/to/lang-server.js" }, simplePathResolver)

2) Once we have our LanguageClientProcess, we can create our LanguageClient:

const languageClient = new LanguageClient("language-identifier", languageClientProcess)

// Implementing the strong-typing as proposed in #1717 might help make this more readable! 
languageClient.sendNotification("test.ts", "textDocument/didOpen", { ...arguments ... })
...
await response = languageClient.sendRequest("test.ts", "textDocument/codeAction", {...codeActionArgs..})

// validate response matches what we expect

This is all relatively self-contained, so it'd be great to have tests for the languages we support against as much of the protocol we want to cover. These tests would be a bit simpler than writing CiTests to validate the full language support against the UI.

Hope that helps give some ideas.