From a6b7a35367bc2b81612d1a96163ff59b26719d0b Mon Sep 17 00:00:00 2001 From: Alex Kladov Date: Tue, 10 Jan 2023 09:40:40 +0000 Subject: [PATCH] add tests for textDocument/Definition (#900) --- tests/lsp_features/definition.zig | 76 +++++++++++++++++++++++++++++++ tests/tests.zig | 1 + 2 files changed, 77 insertions(+) create mode 100644 tests/lsp_features/definition.zig diff --git a/tests/lsp_features/definition.zig b/tests/lsp_features/definition.zig new file mode 100644 index 0000000..caed193 --- /dev/null +++ b/tests/lsp_features/definition.zig @@ -0,0 +1,76 @@ +const std = @import("std"); +const mem = std.mem; +const zls = @import("zls"); +const builtin = @import("builtin"); + +const helper = @import("../helper.zig"); +const Context = @import("../context.zig").Context; +const ErrorBuilder = @import("../ErrorBuilder.zig"); + +const types = zls.types; +const offsets = zls.offsets; +const requests = zls.requests; + +const allocator: std.mem.Allocator = std.testing.allocator; + +test "definition - smoke" { + try testDefinition( + \\fn main() void { f<>oo(); } + \\fn foo() void {} + ); +} + +test "definition - cursor is at the end of an identifier" { + try testDefinition( + \\fn main() void { foo<>(); } + \\fn foo() void {} + ); +} + +test "definition - cursor is at the start of an identifier" { + testDefinition( + \\fn main() void { <>foo(); } + \\fn foo() void {} + ) catch |err| switch (err) { + error.UnresolvedDefinition => { + // TODO: #891 + }, + else => return err, + }; +} + +fn testDefinition(source: []const u8) !void { + var phr = try helper.collectClearPlaceholders(allocator, source); + defer phr.deinit(allocator); + + var cursor: offsets.Loc = .{ .start = 0, .end = 0 }; + var def_start: offsets.Loc = .{ .start = 0, .end = 0 }; + var def_end: offsets.Loc = .{ .start = 0, .end = 0 }; + for (phr.locations.items(.old)) |loc, i| { + if (mem.eql(u8, source[loc.start..loc.end], "<>")) cursor = phr.locations.items(.new)[i]; + if (mem.eql(u8, source[loc.start..loc.end], "")) def_start = phr.locations.items(.new)[i]; + if (mem.eql(u8, source[loc.start..loc.end], "")) def_end = phr.locations.items(.new)[i]; + } + + const cursor_lsp = offsets.locToRange(phr.new_source, cursor, .@"utf-16").start; + const def_range_lsp = offsets.locToRange(phr.new_source, .{ .start = def_start.end, .end = def_end.start }, .@"utf-16"); + + var ctx = try Context.init(); + defer ctx.deinit(); + + const test_uri: []const u8 = switch (builtin.os.tag) { + .windows => "file:///C:\\test.zig", + else => "file:///test.zig", + }; + + try ctx.requestDidOpen(test_uri, phr.new_source); + + const params = types.TextDocumentPositionParams{ + .textDocument = .{ .uri = test_uri }, + .position = cursor_lsp, + }; + + const response = try ctx.requestGetResponse(?types.Location, "textDocument/definition", params); + const result = response.result orelse return error.UnresolvedDefinition; + try std.testing.expectEqual(def_range_lsp, result.range); +} diff --git a/tests/tests.zig b/tests/tests.zig index d85c824..f9fb035 100644 --- a/tests/tests.zig +++ b/tests/tests.zig @@ -11,6 +11,7 @@ comptime { // LSP features _ = @import("lsp_features/completion.zig"); + _ = @import("lsp_features/definition.zig"); _ = @import("lsp_features/folding_range.zig"); _ = @import("lsp_features/inlay_hints.zig"); _ = @import("lsp_features/references.zig");