mirror of
https://github.com/c-cube/linol.git
synced 2025-12-09 12:45:53 -05:00
521 lines
11 KiB
TypeScript
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,
|
|
},
|
|
},
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
});
|