ref(event): split Size into two Points (one for the size and one for the anchor / origin)
All checks were successful
Zig Project Action / Lint, Spell-check and test zig project (push) Successful in 39s

This commit is contained in:
2025-03-04 00:04:56 +01:00
parent 91ac6241f4
commit 591b990087
23 changed files with 477 additions and 459 deletions

View File

@@ -5,8 +5,7 @@ const Container = @import("container.zig").Container;
const Cell = @import("cell.zig");
const DisplayWidth = @import("DisplayWidth");
const Position = @import("size.zig").Position;
const Size = @import("size.zig").Size;
const Point = @import("point.zig").Point;
// TODO how would I describe the expected screens?
// - including styling?
@@ -15,11 +14,11 @@ const Size = @import("size.zig").Size;
/// Single-buffer test rendering pipeline for testing purposes.
pub const Renderer = struct {
allocator: std.mem.Allocator,
size: Size,
size: Point,
screen: []Cell,
pub fn init(allocator: std.mem.Allocator, size: Size) @This() {
const screen = allocator.alloc(Cell, @as(usize, size.cols) * @as(usize, size.rows)) catch @panic("testing.zig: Out of memory.");
pub fn init(allocator: std.mem.Allocator, size: Point) @This() {
const screen = allocator.alloc(Cell, @as(usize, size.x) * @as(usize, size.y)) catch @panic("testing.zig: Out of memory.");
@memset(screen, .{});
return .{
@@ -33,9 +32,9 @@ pub const Renderer = struct {
this.allocator.free(this.screen);
}
pub fn resize(this: *@This(), size: Size) !void {
pub fn resize(this: *@This(), size: Point) !void {
this.size = size;
const n = @as(usize, size.cols) * @as(usize, size.rows);
const n = @as(usize, size.cols) * @as(usize, size.y);
this.allocator.free(this.screen);
this.screen = this.allocator.alloc(Cell, n) catch @panic("testing.zig: Out of memory.");
@@ -47,21 +46,22 @@ pub const Renderer = struct {
}
pub fn render(this: *@This(), comptime T: type, container: *const T) !void {
const size: Size = container.size;
const size: Point = container.size;
const origin: Point = container.origin;
const cells: []const Cell = try container.contents();
if (cells.len == 0) return;
var idx: usize = 0;
const anchor = (@as(usize, size.anchor.row) * @as(usize, this.size.cols)) + @as(usize, size.anchor.col);
const anchor = (@as(usize, origin.y) * @as(usize, this.size.x)) + @as(usize, origin.x);
blk: for (0..size.rows) |row| {
for (0..size.cols) |col| {
blk: for (0..size.y) |row| {
for (0..size.x) |col| {
const cell = cells[idx];
idx += 1;
this.screen[anchor + (row * this.size.cols) + col].style = cell.style;
this.screen[anchor + (row * this.size.cols) + col].cp = cell.cp;
this.screen[anchor + (row * this.size.x) + col].style = cell.style;
this.screen[anchor + (row * this.size.x) + col].cp = cell.cp;
if (cells.len == idx) break :blk;
}
@@ -92,7 +92,7 @@ pub const Renderer = struct {
/// var renderer: testing.Renderer = .init(allocator, size);
/// defer renderer.deinit();
///
/// try container.handle(.{ .resize = size });
/// try container.handle(.{ .size = size });
/// try renderer.render(Container(event.SystemEvent), &container);
/// try renderer.save(file.writer());
/// ```
@@ -115,34 +115,34 @@ pub const Renderer = struct {
/// .cols = 30,
/// }, &container, @import("test/container/border.all.zon"));
/// ```
pub fn expectContainerScreen(size: Size, container: *Container(event.SystemEvent), expected: []const Cell) !void {
pub fn expectContainerScreen(size: Point, container: *Container(event.SystemEvent), expected: []const Cell) !void {
const allocator = std.testing.allocator;
var renderer: Renderer = .init(allocator, size);
defer renderer.deinit();
try container.handle(.{ .resize = size });
try container.handle(.{ .size = size });
try renderer.render(Container(event.SystemEvent), container);
try expectEqualCells(renderer.size, expected, renderer.screen);
try expectEqualCells(.{}, renderer.size, expected, renderer.screen);
}
/// This function is intended to be used only in tests. Test if the two
/// provided cell arrays are identical. Usually the `Cell` slices are
/// the contents of a given screen from the `zterm.testing.Renderer`. See
/// `zterm.testing.expectContainerScreen` for an example usage.
pub fn expectEqualCells(size: Size, expected: []const Cell, actual: []const Cell) !void {
pub fn expectEqualCells(origin: Point, size: Point, expected: []const Cell, actual: []const Cell) !void {
const allocator = std.testing.allocator;
try std.testing.expectEqual(expected.len, actual.len);
try std.testing.expectEqual(expected.len, @as(usize, size.rows) * @as(usize, size.cols));
try std.testing.expectEqual(expected.len, @as(usize, size.y) * @as(usize, size.x));
var expected_cps = try std.ArrayList(Cell).initCapacity(allocator, size.cols -| size.anchor.col);
var expected_cps = try std.ArrayList(Cell).initCapacity(allocator, size.x);
defer expected_cps.deinit();
var actual_cps = try std.ArrayList(Cell).initCapacity(allocator, size.cols -| size.anchor.col);
var actual_cps = try std.ArrayList(Cell).initCapacity(allocator, size.x);
defer actual_cps.deinit();
var output = try std.ArrayList(u8).initCapacity(allocator, expected_cps.capacity * actual_cps.capacity + 5 * size.rows);
var output = try std.ArrayList(u8).initCapacity(allocator, expected_cps.capacity * actual_cps.capacity + 5 * size.y);
defer output.deinit();
var buffer = std.io.bufferedWriter(output.writer());
@@ -155,23 +155,22 @@ pub fn expectEqualCells(size: Size, expected: []const Cell, actual: []const Cell
defer dwd.deinit();
const dw: DisplayWidth = .{ .data = &dwd };
const expected_centered = try dw.center(allocator, "Expected Screen", size.cols, " ");
const expected_centered = try dw.center(allocator, "Expected Screen", size.x, " ");
defer allocator.free(expected_centered);
const actual_centered = try dw.center(allocator, "Actual Screen", size.cols, " ");
const actual_centered = try dw.center(allocator, "Actual Screen", size.x, " ");
defer allocator.free(actual_centered);
try writer.print("Screens are not equivalent.\n{s} ┆ {s}\n", .{ expected_centered, actual_centered });
const anchor = (size.anchor.row * size.cols) + size.anchor.col;
for (size.anchor.row..size.rows) |row| {
for (origin.y..size.y) |row| {
defer {
expected_cps.clearRetainingCapacity();
actual_cps.clearRetainingCapacity();
}
for (size.anchor.col..size.cols) |col| {
const expected_cell = expected[anchor + (row * size.cols) + col];
const actual_cell = actual[anchor + (row * size.cols) + col];
for (origin.x..size.x) |col| {
const expected_cell = expected[(row * size.x) + col];
const actual_cell = actual[(row * size.x) + col];
if (!expected_cell.eql(actual_cell)) differ = true;