diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-15 18:33:12 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:14 -0300 |
| commit | 505dedb2459e7b51cbdb0c066698c6e5596d19dd (patch) | |
| tree | 2f91a90b6889ca00817bbfa58b44af1403d1ec4b /test/output.zig | |
| parent | 4a3c5a48224cf542429504e8728e10c802e1fd52 (diff) | |
| download | pardes-505dedb2459e7b51cbdb0c066698c6e5596d19dd.tar.gz pardes-505dedb2459e7b51cbdb0c066698c6e5596d19dd.zip | |
Bound preceding result context by its outermost tree-sitter declaration
Diffstat (limited to 'test/output.zig')
| -rw-r--r-- | test/output.zig | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/test/output.zig b/test/output.zig index ede8e7dd..c162c1d1 100644 --- a/test/output.zig +++ b/test/output.zig @@ -1381,3 +1381,67 @@ test "LSP occurrence tint follows the supplied source span through context" { try std.testing.expectEqualStrings(text, source.file.?.content); } } + +test "result context upper bound stops at earliest enclosing declaration" { + if (!pardes.syntax.enabled) return error.SkipZigTest; + const text = "// unrelated prelude\n" ++ + "const unrelated = 1;\n" ++ + "\n" ++ + "const Outer = struct {\n" ++ + " pub fn run(\n" ++ + " value: u32,\n" ++ + " ) void {\n" ++ + " _ = value;\n" ++ + " }\n" ++ + "};\n" ++ + "// trailing context remains available"; + for ([_]panes.Output.Origin{ .search, .{ .query = .references } }) |origin| { + for ([_]bool{ false, true }) |tscontext| { + for ([_]bool{ false, true }) |visible| { + const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true }); + defer p.deinit(); + const source = try p.setTestFile(text); + p.gpa.free(source.file.?.path); + source.file.?.path = try p.gpa.dupe(u8, "/bounded-context.zig"); + p.locations_config = .{ .context = 100, .tscontext = tscontext, .tslocations = visible }; + const input = try std.fmt.allocPrint(p.gpa, "{s}:8:13 {s}\n", .{ source.file.?.path, modal.lineSlice(text, 7) }); + try panes.Output.fillResults(p, 0, "/", origin, "upper bound", input, 0); + const file = &p.panes[source.search_pane.?].?.file.?; + const first: usize = if (tscontext) 4 else 1; + try std.testing.expectEqual(first, file.location_rows[0].at.line); + try std.testing.expectEqual(@as(usize, 11), file.location_rows[file.location_rows.len - 1].at.line); + try std.testing.expectEqual(@as(usize, 8) - first, source.search_row.?); + var matches: usize = 0; + for (file.location_rows, 0..) |row, index| { + try std.testing.expectEqual(first + index, row.at.line); + try std.testing.expectEqualStrings(modal.lineSlice(text, row.at.line - 1), modal.lineSlice(file.content, index)[row.code_start..]); + if (row.kind == .match) { + try std.testing.expectEqual(@as(usize, 8), row.at.line); + matches += 1; + } + } + try std.testing.expectEqual(@as(usize, 1), matches); + try std.testing.expectEqualStrings(text, source.file.?.content); + } + } + } + + // A top-level comment has no enclosing declaration, and a plain-text + // file has no grammar. Neither should lose its preceding ordinary rows. + for ([_][]const u8{ "/no-ancestor.zig", "/no-grammar.txt" }) |path| { + const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true }); + defer p.deinit(); + const plain = "// first\n// second\n// matched\n// trailing"; + const source = try p.setTestFile(plain); + p.gpa.free(source.file.?.path); + source.file.?.path = try p.gpa.dupe(u8, path); + p.locations_config = .{ .context = 100, .tscontext = true, .tslocations = false }; + const input = try std.fmt.allocPrint(p.gpa, "{s}:3:4 // matched\n", .{path}); + try panes.Output.fillResults(p, 0, "/", .search, "unbounded", input, 0); + const file = &p.panes[source.search_pane.?].?.file.?; + try std.testing.expectEqual(@as(usize, 4), file.location_rows.len); + try std.testing.expectEqual(@as(usize, 1), file.location_rows[0].at.line); + try std.testing.expectEqual(@as(usize, 4), file.location_rows[3].at.line); + try std.testing.expectEqual(@as(usize, 2), source.search_row.?); + } +} |
