summaryrefslogtreecommitdiff
path: root/test/output.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-15 18:33:12 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:14 -0300
commit505dedb2459e7b51cbdb0c066698c6e5596d19dd (patch)
tree2f91a90b6889ca00817bbfa58b44af1403d1ec4b /test/output.zig
parent4a3c5a48224cf542429504e8728e10c802e1fd52 (diff)
downloadpardes-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.zig64
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.?);
+ }
+}