linol/thirdparty/lsp/ocaml-lsp-server/test/e2e/__tests__/textDocument-selectionRange.test.ts

521 lines
11 KiB
TypeScript

import outdent from "outdent";
import * as Protocol from "vscode-languageserver-protocol";
import * as Types from "vscode-languageserver-types";
import * as LanguageServer from "../src/LanguageServer";
describe("textDocument/selectionRange", () => {
let languageServer: LanguageServer.LanguageServer;
beforeEach(async () => {
languageServer = await LanguageServer.startAndInitialize();
});
afterEach(async () => {
await LanguageServer.exit(languageServer);
});
function openDocument(source: string) {
languageServer.sendNotification(
Protocol.DidOpenTextDocumentNotification.type,
{
textDocument: Types.TextDocumentItem.create(
"file:///test.ml",
"ocaml",
0,
source,
),
},
);
}
async function selectionRange(positions: Types.Position[]) {
return await languageServer.sendRequest(
Protocol.SelectionRangeRequest.type,
{
textDocument: Types.TextDocumentIdentifier.create("file:///test.ml"),
positions: positions,
},
);
}
it("returns a selection range for modules", async () => {
openDocument(outdent`
let foo a b =
let min_ab = min a b in
let max_ab = max a b in
min_ab * max_ab
`);
const result = await selectionRange([Types.Position.create(1, 17)]);
expect(result).toMatchInlineSnapshot(`
[
{
"parent": {
"parent": {
"parent": {
"parent": {
"parent": {
"range": {
"end": {
"character": 17,
"line": 3,
},
"start": {
"character": 0,
"line": 0,
},
},
},
"range": {
"end": {
"character": 17,
"line": 3,
},
"start": {
"character": 8,
"line": 0,
},
},
},
"range": {
"end": {
"character": 17,
"line": 3,
},
"start": {
"character": 2,
"line": 1,
},
},
},
"range": {
"end": {
"character": 22,
"line": 1,
},
"start": {
"character": 2,
"line": 1,
},
},
},
"range": {
"end": {
"character": 22,
"line": 1,
},
"start": {
"character": 15,
"line": 1,
},
},
},
"range": {
"end": {
"character": 18,
"line": 1,
},
"start": {
"character": 15,
"line": 1,
},
},
},
]
`);
});
it("returns a selection range for more complex documents", async () => {
openDocument(outdent`
type _ typ =
| TInt : int typ
| TBool : bool typ
module M = struct
type t
let f (_ : _ typ) = ()
end
`);
const result = await selectionRange([Types.Position.create(5, 23)]);
expect(result).toMatchInlineSnapshot(`
[
{
"parent": {
"parent": {
"parent": {
"parent": {
"parent": {
"parent": {
"range": {
"end": {
"character": 3,
"line": 6,
},
"start": {
"character": 0,
"line": 0,
},
},
},
"range": {
"end": {
"character": 3,
"line": 6,
},
"start": {
"character": 0,
"line": 3,
},
},
},
"range": {
"end": {
"character": 3,
"line": 6,
},
"start": {
"character": 11,
"line": 3,
},
},
},
"range": {
"end": {
"character": 24,
"line": 5,
},
"start": {
"character": 2,
"line": 4,
},
},
},
"range": {
"end": {
"character": 24,
"line": 5,
},
"start": {
"character": 2,
"line": 5,
},
},
},
"range": {
"end": {
"character": 24,
"line": 5,
},
"start": {
"character": 8,
"line": 5,
},
},
},
"range": {
"end": {
"character": 24,
"line": 5,
},
"start": {
"character": 22,
"line": 5,
},
},
},
]
`);
});
it("returns a selection range for functors", async () => {
openDocument(outdent`
module M = Map.Make (struct
type t = { o: < rank : int > }
let compare a b = a.o#rank - b.o#rank
end)`);
const result = await selectionRange([Types.Position.create(2, 26)]);
expect(result).toMatchInlineSnapshot(`
[
{
"parent": {
"parent": {
"parent": {
"parent": {
"parent": {
"parent": {
"parent": {
"parent": {
"range": {
"end": {
"character": 4,
"line": 3,
},
"start": {
"character": 0,
"line": 0,
},
},
},
"range": {
"end": {
"character": 4,
"line": 3,
},
"start": {
"character": 11,
"line": 0,
},
},
},
"range": {
"end": {
"character": 3,
"line": 3,
},
"start": {
"character": 21,
"line": 0,
},
},
},
"range": {
"end": {
"character": 39,
"line": 2,
},
"start": {
"character": 2,
"line": 1,
},
},
},
"range": {
"end": {
"character": 39,
"line": 2,
},
"start": {
"character": 2,
"line": 2,
},
},
},
"range": {
"end": {
"character": 39,
"line": 2,
},
"start": {
"character": 14,
"line": 2,
},
},
},
"range": {
"end": {
"character": 39,
"line": 2,
},
"start": {
"character": 20,
"line": 2,
},
},
},
"range": {
"end": {
"character": 28,
"line": 2,
},
"start": {
"character": 20,
"line": 2,
},
},
},
"range": {
"end": {
"character": 28,
"line": 2,
},
"start": {
"character": 23,
"line": 2,
},
},
},
]
`);
});
it("returns a reasonable selection range for ill-typed modules", async () => {
openDocument(outdent`
module M = struct
let f x : int = string_of_int x
end`);
const result = await selectionRange([Types.Position.create(1, 34)]);
expect(result).toMatchInlineSnapshot(`
[
{
"parent": {
"parent": {
"parent": {
"parent": {
"parent": {
"range": {
"end": {
"character": 3,
"line": 2,
},
"start": {
"character": 0,
"line": 0,
},
},
},
"range": {
"end": {
"character": 3,
"line": 2,
},
"start": {
"character": 11,
"line": 0,
},
},
},
"range": {
"end": {
"character": 35,
"line": 1,
},
"start": {
"character": 4,
"line": 1,
},
},
},
"range": {
"end": {
"character": 35,
"line": 1,
},
"start": {
"character": 10,
"line": 1,
},
},
},
"range": {
"end": {
"character": 35,
"line": 1,
},
"start": {
"character": 20,
"line": 1,
},
},
},
"range": {
"end": {
"character": 35,
"line": 1,
},
"start": {
"character": 34,
"line": 1,
},
},
},
]
`);
});
it("returns a reasonable selection range in the presence of syntax errors", async () => {
openDocument(outdent`
module M = struct
let f x : int = string_of_int x
ed`);
const result = await selectionRange([Types.Position.create(1, 34)]);
expect(result).toMatchInlineSnapshot(`
[
{
"parent": {
"parent": {
"parent": {
"parent": {
"parent": {
"range": {
"end": {
"character": 2,
"line": 2,
},
"start": {
"character": 0,
"line": 0,
},
},
},
"range": {
"end": {
"character": 2,
"line": 2,
},
"start": {
"character": 11,
"line": 0,
},
},
},
"range": {
"end": {
"character": 2,
"line": 2,
},
"start": {
"character": 4,
"line": 1,
},
},
},
"range": {
"end": {
"character": 2,
"line": 2,
},
"start": {
"character": 10,
"line": 1,
},
},
},
"range": {
"end": {
"character": 2,
"line": 2,
},
"start": {
"character": 20,
"line": 1,
},
},
},
"range": {
"end": {
"character": 35,
"line": 1,
},
"start": {
"character": 34,
"line": 1,
},
},
},
]
`);
});
});