summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/e2e_harness.zig37
-rw-r--r--test/snapshot.zig63
2 files changed, 41 insertions, 59 deletions
diff --git a/test/e2e_harness.zig b/test/e2e_harness.zig
index 6354aa4b..9099f13e 100644
--- a/test/e2e_harness.zig
+++ b/test/e2e_harness.zig
@@ -1,8 +1,11 @@
const std = @import("std");
const posix = std.posix;
-const linux = std.os.linux;
+const libc = std.c;
const ghostty_vt = @import("ghostty-vt");
+// TIOCSWINSZ: absent from std.c.T on darwin — _IOW('t', 103, winsize)
+const TIOCSWINSZ: c_int = @bitCast(@as(u32, if (@hasDecl(posix.T, "IOCSWINSZ")) posix.T.IOCSWINSZ else 0x80087467));
+
extern "c" fn forkpty(
amaster: *c_int,
name: ?[*:0]u8,
@@ -13,9 +16,9 @@ extern "c" fn execvp(file: [*:0]const u8, argv: [*:null]const ?[*:0]const u8) c_
extern "c" fn _exit(status: c_int) noreturn;
fn nowMs() i64 {
- var ts: linux.timespec = undefined;
- _ = linux.clock_gettime(linux.CLOCK.MONOTONIC, &ts);
- return ts.sec * 1000 + @divFloor(@as(i64, ts.nsec), 1_000_000);
+ var ts: libc.timespec = undefined;
+ _ = libc.clock_gettime(.MONOTONIC, &ts);
+ return @as(i64, @intCast(ts.sec)) * 1000 + @divFloor(@as(i64, @intCast(ts.nsec)), 1_000_000);
}
/// E2E test harness: forks the app in a pty and parses its output with a
@@ -92,7 +95,7 @@ pub const Harness = struct {
pub fn deinit(self: *Harness) void {
posix.kill(self.pid, posix.SIG.KILL) catch {};
- _ = linux.close(self.master);
+ _ = libc.close(self.master);
self.stream.deinit();
self.raw.deinit(self.gpa);
self.term.deinit(self.gpa);
@@ -103,10 +106,9 @@ pub const Harness = struct {
pub fn send(self: *Harness, bytes: []const u8) !void {
var off: usize = 0;
while (off < bytes.len) {
- const rc = linux.write(self.master, bytes[off..].ptr, bytes.len - off);
- const n: isize = @bitCast(rc);
+ const n = libc.write(self.master, bytes[off..].ptr, bytes.len - off);
if (n < 0) {
- if (n == -@as(isize, @intFromEnum(linux.E.INTR))) continue;
+ if (libc.errno(n) == .INTR) continue;
return error.WriteFailed;
}
off += @intCast(n);
@@ -139,7 +141,7 @@ pub const Harness = struct {
self.cols = cols;
self.term.resize(self.gpa, cols, rows) catch {};
const ws = posix.winsize{ .row = rows, .col = cols, .xpixel = 0, .ypixel = 0 };
- _ = posix.system.ioctl(self.master, posix.T.IOCSWINSZ, @intFromPtr(&ws));
+ _ = posix.system.ioctl(self.master, TIOCSWINSZ, @intFromPtr(&ws));
}
/// The full viewport text (plainString), newline-joined rows. Caller frees.
@@ -261,18 +263,15 @@ pub const Harness = struct {
}
};
-/// Write a file (helper for test setup, raw linux syscalls).
+/// Write a file (helper for test setup, raw libc).
pub fn writeFile(path: [*:0]const u8, data: []const u8) !void {
- const rc = linux.open(path, .{ .ACCMODE = .WRONLY, .CREAT = true, .TRUNC = true }, 0o644);
- const sfd: isize = @bitCast(rc);
- if (sfd < 0) return error.OpenFailed;
- const fd: c_int = @intCast(sfd);
- defer _ = linux.close(fd);
+ const fd = libc.open(path, .{ .ACCMODE = .WRONLY, .CREAT = true, .TRUNC = true }, @as(libc.mode_t, 0o644));
+ if (fd < 0) return error.OpenFailed;
+ defer _ = libc.close(fd);
var off: usize = 0;
while (off < data.len) {
- const w = linux.write(fd, data[off..].ptr, data.len - off);
- const sw: isize = @bitCast(w);
- if (sw <= 0) break;
- off += @intCast(sw);
+ const w = libc.write(fd, data[off..].ptr, data.len - off);
+ if (w <= 0) break;
+ off += @intCast(w);
}
}
diff --git a/test/snapshot.zig b/test/snapshot.zig
index c1bf03c0..10aa0c86 100644
--- a/test/snapshot.zig
+++ b/test/snapshot.zig
@@ -28,8 +28,7 @@
// snap <label> capture grid text + cursor
// snapstyle <label> capture per-cell style runs (fg,bg,attrs)
const std = @import("std");
-const posix = std.posix;
-const linux = std.os.linux;
+const libc = std.c;
const ghostty_vt = @import("ghostty-vt");
const eh = @import("e2e_harness.zig");
@@ -48,9 +47,8 @@ pub fn main(init: std.process.Init) !void {
// argv: exe-under-test, then flags/scripts. All paths made absolute up
// front because runScript chdirs into a per-script workdir.
var cwd_buf: [4096]u8 = undefined;
- const cwd_rc: isize = @bitCast(linux.getcwd(&cwd_buf, cwd_buf.len));
- if (cwd_rc <= 0) fatal("getcwd failed", .{});
- const orig_cwd = cwd_buf[0..@intCast(cwd_rc - 1)];
+ const cwd_p = libc.getcwd(&cwd_buf, cwd_buf.len) orelse fatal("getcwd failed", .{});
+ const orig_cwd = std.mem.span(@as([*:0]u8, @ptrCast(cwd_p)));
var exe: ?[]const u8 = null;
var update = false;
@@ -461,41 +459,26 @@ fn absPath(arena: std.mem.Allocator, cwd: []const u8, p: []const u8) ![]const u8
fn listSnaps(arena: std.mem.Allocator, dir_path: []const u8, scripts: *std.ArrayList([]const u8)) !void {
const dir_z = try arena.dupeZ(u8, dir_path);
- const rc = linux.open(dir_z, .{ .ACCMODE = .RDONLY, .DIRECTORY = true }, 0);
- const sfd: isize = @bitCast(rc);
- if (sfd < 0) fatal("no snapshots/ dir at {s}", .{dir_path});
- const fd: i32 = @intCast(sfd);
- defer _ = linux.close(fd);
- var buf: [8192]u8 align(@alignOf(linux.dirent64)) = undefined;
- while (true) {
- const r = linux.getdents64(fd, &buf, buf.len);
- const n: isize = @bitCast(r);
- if (n <= 0) break;
- var off: usize = 0;
- while (off < @as(usize, @intCast(n))) {
- const d: *align(1) linux.dirent64 = @ptrCast(&buf[off]);
- const name = std.mem.span(@as([*:0]const u8, @ptrCast(&d.name)));
- if (std.mem.endsWith(u8, name, ".snap"))
- try scripts.append(arena, try std.fmt.allocPrint(arena, "{s}/{s}", .{ dir_path, name }));
- off += d.reclen;
- }
+ const dir = libc.opendir(dir_z) orelse fatal("no snapshots/ dir at {s}", .{dir_path});
+ defer _ = libc.closedir(dir);
+ while (libc.readdir(dir)) |d| {
+ const name = std.mem.sliceTo(@as([*:0]const u8, @ptrCast(&d.name)), 0);
+ if (std.mem.endsWith(u8, name, ".snap"))
+ try scripts.append(arena, try std.fmt.allocPrint(arena, "{s}/{s}", .{ dir_path, name }));
}
}
fn readFileAlloc(arena: std.mem.Allocator, path: []const u8) ![]u8 {
const path_z = try arena.dupeZ(u8, path);
- const rc = linux.open(path_z, .{ .ACCMODE = .RDONLY }, 0);
- const sfd: isize = @bitCast(rc);
- if (sfd < 0) return error.OpenFailed;
- const fd: i32 = @intCast(sfd);
- defer _ = linux.close(fd);
+ const fd = libc.open(path_z, .{ .ACCMODE = .RDONLY });
+ if (fd < 0) return error.OpenFailed;
+ defer _ = libc.close(fd);
var buf: std.ArrayList(u8) = .empty;
var chunk: [16384]u8 = undefined;
while (true) {
- const r = linux.read(fd, &chunk, chunk.len);
- const n: isize = @bitCast(r);
+ const n = libc.read(fd, &chunk, chunk.len);
if (n < 0) {
- if (n == -@as(isize, @intFromEnum(linux.E.INTR))) continue;
+ if (libc.errno(n) == .INTR) continue;
return error.ReadFailed;
}
if (n == 0) break;
@@ -506,15 +489,15 @@ fn readFileAlloc(arena: std.mem.Allocator, path: []const u8) ![]u8 {
fn mkdir(arena: std.mem.Allocator, path: []const u8, exist_ok: bool) !void {
const path_z = try arena.dupeZ(u8, path);
- const n: isize = @bitCast(linux.mkdir(path_z, 0o755));
- if (n < 0) {
- if (exist_ok and n == -@as(isize, @intFromEnum(linux.E.EXIST))) return;
+ const rc = libc.mkdir(path_z, 0o755);
+ if (rc != 0) {
+ if (exist_ok and libc.errno(rc) == .EXIST) return;
return error.MkdirFailed;
}
}
-fn chdirRc(path_z: [:0]const u8) isize {
- return @bitCast(linux.chdir(path_z.ptr));
+fn chdirRc(path_z: [:0]const u8) c_int {
+ return libc.chdir(path_z.ptr);
}
fn rmrf(path: []const u8) void {
@@ -522,15 +505,15 @@ fn rmrf(path: []const u8) void {
if (path.len >= path_buf.len) return;
@memcpy(path_buf[0..path.len], path);
path_buf[path.len] = 0;
- const pid: isize = @bitCast(linux.fork());
+ const pid = libc.fork();
if (pid == 0) {
const argv: [4:null]?[*:0]const u8 = .{ "rm", "-rf", @as([*:0]const u8, @ptrCast(&path_buf)), null };
_ = execvp("rm", &argv);
- linux.exit_group(127);
+ libc._exit(127);
}
if (pid < 0) return;
- var status: u32 = 0;
- _ = linux.wait4(@intCast(pid), &status, 0, null);
+ var status: c_int = 0;
+ _ = libc.waitpid(pid, &status, 0);
}
fn printFirstDiff(golden: []const u8, actual: []const u8) void {