From 741d088c60da40fd811dedc80d8e62753959bfea Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Wed, 30 Sep 2026 20:03:16 -0300 Subject: A look at a PDF's page past its last is a miss, "has no page N", never the last page in its place manual.pdf:999 on a twelve-page PDF showed page 12 and said nothing, so a stale or mistyped page number looked like a place found. It is now the miss a line past a file's end is, whether the PDF is open (it stays on its page) or not (nothing opens). A restore or a start-up page past the end still lands on the last. Co-Authored-By: Claude Opus 5.5 --- test/mode.zig | 2 +- test/pdf.zig | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/mode.zig b/test/mode.zig index 767cda93..f49c434c 100644 --- a/test/mode.zig +++ b/test/mode.zig @@ -109,7 +109,7 @@ test "Mode leaves image and PDF document modes unchanged" { const len = try tmp.dir.realPath(std.testing.io, &buffer); const path = try std.fmt.allocPrint(std.testing.allocator, "{s}/mode.pdf", .{buffer[0..len]}); defer std.testing.allocator.free(path); - const document = try panes.Pdf.openPane(p, 2, path, 1); + const document = try panes.Pdf.openPane(p, 2, path, 1, .last); const page = document.pdf.?.page; try mode(p, 2, .normal); try std.testing.expectEqual(page, document.pdf.?.page); diff --git a/test/pdf.zig b/test/pdf.zig index 48869de1..36b3570e 100644 --- a/test/pdf.zig +++ b/test/pdf.zig @@ -343,7 +343,7 @@ test "PdfSections Look follows the exact owning PDF, not an equal path" { try std.testing.expectEqual(first_revision, first_output.file.?.revision); const duplicate_id = p.freeSlot() orelse return error.NoDuplicatePdfSlot; - const duplicate = try panes.Pdf.openPane(p, duplicate_id, path, 0); + const duplicate = try panes.Pdf.openPane(p, duplicate_id, path, 0, .last); pardes.exec.placeNew(p, 0, 0, duplicate_id, .doc); layout.compute(p); panes.Pdf.openSections(p, duplicate_id); @@ -386,6 +386,40 @@ test "PdfSections caches an empty outline output" { try std.testing.expectEqual(serial, p.panes[output_id].?.serial); } +test "a look at a PDF's page past its last is a miss, never the last page" { + if (!pdf_enabled or platform == .web) return; + const gpa = std.testing.allocator; + var tmp = std.testing.tmpDir(.{}); + defer tmp.cleanup(); + const fixture = try pdf_impl.makeNoOutlineTestPdf(gpa); + defer gpa.free(fixture); + try tmp.dir.writeFile(std.testing.io, .{ .sub_path = "plain.pdf", .data = fixture }); + try tmp.dir.writeFile(std.testing.io, .{ .sub_path = "other.pdf", .data = fixture }); + var dir_buf: [4096]u8 = undefined; + const dir = dir_buf[0..try tmp.dir.realPath(std.testing.io, &dir_buf)]; + var path_buf: [4200]u8 = undefined; + const path = try std.fmt.bufPrint(&path_buf, "{s}/plain.pdf", .{dir}); + const p = try Pardes.init(gpa, .{ .file = path, .cols = 80, .rows = 28 }); + defer p.deinit(); + const doc = p.panes[0].?; + try std.testing.expect(doc.hasPdf()); + var line: [4300]u8 = undefined; + // Open: it stays on its page. + const page = doc.pdf.?.page; + pardes.look.lookAt(p, 0, try std.fmt.bufPrint(&line, "{s}:999", .{path})); + try std.testing.expect(p.look_missed); + try std.testing.expectEqual(page, doc.pdf.?.page); + // Not open: nothing opens. + p.look_missed = false; + var before: usize = 0; + for (p.panes) |slot| before += @intFromBool(slot != null); + pardes.look.lookAt(p, 0, try std.fmt.bufPrint(&line, "{s}/other.pdf:999", .{dir})); + try std.testing.expect(p.look_missed); + var after: usize = 0; + for (p.panes) |slot| after += @intFromBool(slot != null); + try std.testing.expectEqual(before, after); +} + test "SDL PDF raster policy is materially denser than Kitty" { try std.testing.expect( pardes.sdl_pdf_raster_policy.dpi >= pardes.kitty_pdf_raster_policy.dpi * 2, -- cgit v1.3