Skip to content

WillLillis/lspresso-shot

Repository files navigation

LSPresso-Shot

A concentrated dose of LSP testing power!

WIP

This library is currently a work in progress and is not ready for use in other projects!

Goal

Provide an easy way to perform integration tests on language servers implemented in Rust.

Usage

First, add lspresso-shot as a dependency to your Rust project:

cargo add --dev lspresso-shot

Write a test:

#[test]
fn it_does_the_hover_thing() {
    let hover_test_case = TestCase::new(
        "Path to server",
        TestFile::new("Source file name", "Contents")
    )
    .cursor_pos(Some(Position::new(0, 0)))
    .other_file( // Optional
        TestFile::new("Other file name", "Other contents")
    );

    lspresso_shot!(test_hover(
        hover_test_case,
        Some(&Hover {
            range: Some(Range {
                start: lsp_types::Position {
                    line: 1,
                    character: 2,
                },
                end: lsp_types::Position {
                    line: 1,
                    character: 3,
                },
            }),
            contents: lsp_types::HoverContents::Markup(MarkupContent {
                kind: lsp_types::MarkupKind::Markdown,
                value: "Hover window contents here".to_string(),
            })
        })
    ));
}

That's it!

Dependencies:

Neovim must be available on your $PATH. See the project's documentation for installation instructions. Versions at or later than 517ecb85f58ed6ac8b4d5443931612e75e7c7dc2 are necessary.

Examples:

  • The library's test corpus uses rust-analyzer. See src/test.rs for examples of how to use the library.
  • TODO: Add asm-lsp/other LSPs here once it's being used.

TODOs/Ideas:

  • Clean up Lua logic (I'm unfamiliar with the neovim API)
    • Add Lua unit tests? (Do we roll our own/ is there an easy framework?)
  • Add CI and whatnot (Improvements to current lua workflow?)
  • It may be possible to extend this library's functionality as a CLI tool.
    • Users could specify test cases through JSON, which we can then deserialize and run the testing logic on as normal.
    • This would allow lspresso-shot to be used with non-Rust LSPs, which would be nice.
    • It probably doesn't make sense to work on this logic until the library internals are more flushed out.

As an eventual end goal, we'd obviously like to provide test coverage for all LSP methods. To start though, let's focus on the following TODOs:

  • Sync up test server test coverage with current rust-analyzer coverage
  • textDocument/completion
  • textDocument/declaration
  • textDocument/definition
  • textDocument/documentSymbol
  • textDocument/formatting
  • textDocument/hover
  • textDocument/publishDiagnostics
  • textDocument/references
  • textDocument/rename
  • textDocument/typeDefinition
  • textDocument/implementation
  • Figure out what methods we want to add next.

Gotchas

  • If your server undergoes some sort of indexing process at startup before it's ready to service a given request, you need to account for this by specifying ServerStartType::Progress(NonZeroU32, String) to the test case. The NonZeroU32 specifies which end message to issue the request after (in case there are multiple). The String provides the relevant progress token.

  • String comparison of results: Many LSP client implementations do some post processing of responses returned by a given language server, primarily removing newlines. Your expected response may need to be minimally altered from what you originally expect in order for tests to pass.

  • Uri fields: If a response contains a Uri field with an absolute path, this field will be sanitizd to a relative path up to the test case's root directory. Your test case's expected results may need to be adjusted to reflect this.

  • Variance in LSP client implementation: The LSP Spec is somewhat loosely defined, leaving plenty of room for client implementations to behave differently from one another. This project utilizes neovim's, meaning that unexpected behavior may occur when your server is used with other editors' clients.

Contributing

  • In addition to neovim, working on this project also requires having having rust-analyzer 1.85 on your $PATH, as it is used in the project's test suite.

About

A concentrated dose of LSP testing power!

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published