|
| 1 | +const std = @import("std"); |
| 2 | +const zls = @import("zls"); |
| 3 | + |
| 4 | +const Context = @import("../context.zig").Context; |
| 5 | + |
| 6 | +const types = zls.lsp.types; |
| 7 | + |
| 8 | +const allocator: std.mem.Allocator = std.testing.allocator; |
| 9 | + |
| 10 | +test "workspace symbols" { |
| 11 | + var ctx: Context = try .init(); |
| 12 | + defer ctx.deinit(); |
| 13 | + |
| 14 | + try ctx.addWorkspace("Animal Shelter", "/animal_shelter/"); |
| 15 | + |
| 16 | + _ = try ctx.addDocument(.{ .source = |
| 17 | + \\const SalamanderCrab = struct { |
| 18 | + \\ fn salamander_crab() void {} |
| 19 | + \\}; |
| 20 | + , .base_directory = "/animal_shelter/" }); |
| 21 | + |
| 22 | + _ = try ctx.addDocument(.{ .source = |
| 23 | + \\const Dog = struct { |
| 24 | + \\ const sheltie: Dog = .{}; |
| 25 | + \\ var @"Mr Crabs" = @compileError("hold up"); |
| 26 | + \\}; |
| 27 | + \\test "walk the dog" { |
| 28 | + \\ const dog: Dog = .sheltie; |
| 29 | + \\ _ = dog; // nah |
| 30 | + \\} |
| 31 | + , .base_directory = "/animal_shelter/" }); |
| 32 | + |
| 33 | + _ = try ctx.addDocument(.{ .source = |
| 34 | + \\const Lion = struct { |
| 35 | + \\ extern fn evolveToMonke() void; |
| 36 | + \\ fn roar() void { |
| 37 | + \\ var lion = "cool!"; |
| 38 | + \\ const Lion2 = struct { |
| 39 | + \\ const lion_for_real = 0; |
| 40 | + \\ }; |
| 41 | + \\ } |
| 42 | + \\}; |
| 43 | + , .base_directory = "/animal_shelter/" }); |
| 44 | + |
| 45 | + _ = try ctx.addDocument(.{ .source = |
| 46 | + \\const PotatoDoctor = struct {}; |
| 47 | + , .base_directory = "/farm/" }); |
| 48 | + |
| 49 | + try testDocumentSymbol(&ctx, "Sal", |
| 50 | + \\Constant SalamanderCrab |
| 51 | + \\Function salamander_crab |
| 52 | + ); |
| 53 | + try testDocumentSymbol(&ctx, "_cr___a_b_", |
| 54 | + \\Constant SalamanderCrab |
| 55 | + \\Function salamander_crab |
| 56 | + \\Variable @"Mr Crabs" |
| 57 | + ); |
| 58 | + try testDocumentSymbol(&ctx, "dog", |
| 59 | + \\Constant Dog |
| 60 | + \\Method walk the dog |
| 61 | + ); |
| 62 | + try testDocumentSymbol(&ctx, "potato_d", ""); |
| 63 | + // Becomes S\x00\x00 which matches nothing |
| 64 | + try testDocumentSymbol(&ctx, "S", ""); |
| 65 | + try testDocumentSymbol(&ctx, "lion", |
| 66 | + \\Constant Lion |
| 67 | + \\Constant lion_for_real |
| 68 | + ); |
| 69 | + try testDocumentSymbol(&ctx, "monke", |
| 70 | + \\Function evolveToMonke |
| 71 | + ); |
| 72 | +} |
| 73 | + |
| 74 | +fn testDocumentSymbol(ctx: *Context, query: []const u8, expected: []const u8) !void { |
| 75 | + const response = try ctx.server.sendRequestSync( |
| 76 | + ctx.arena.allocator(), |
| 77 | + "workspace/symbol", |
| 78 | + .{ .query = query }, |
| 79 | + ) orelse { |
| 80 | + std.debug.print("Server returned `null` as the result\n", .{}); |
| 81 | + return error.InvalidResponse; |
| 82 | + }; |
| 83 | + |
| 84 | + var actual: std.ArrayList(u8) = .empty; |
| 85 | + defer actual.deinit(allocator); |
| 86 | + |
| 87 | + for (response.workspace_symbols) |workspace_symbol| { |
| 88 | + std.debug.assert(workspace_symbol.tags == null); // unsupported for now |
| 89 | + std.debug.assert(workspace_symbol.containerName == null); // unsupported for now |
| 90 | + try actual.print(allocator, "{t} {s}\n", .{ |
| 91 | + workspace_symbol.kind, |
| 92 | + workspace_symbol.name, |
| 93 | + }); |
| 94 | + } |
| 95 | + |
| 96 | + if (actual.items.len != 0) { |
| 97 | + _ = actual.pop(); // Final \n |
| 98 | + } |
| 99 | + |
| 100 | + try zls.testing.expectEqualStrings(expected, actual.items); |
| 101 | +} |
0 commit comments