Add coding symbol rail

This commit is contained in:
slhx agent
2026-06-21 02:21:32 +02:00
parent cfbacb3cd2
commit f793ecd726
6 changed files with 324 additions and 2 deletions
+53
View File
@@ -4,6 +4,7 @@ const leader_mod = @import("leader.zig");
const protocol = @import("protocol.zig");
const replay = @import("replay.zig");
const session_mod = @import("session.zig");
const symbol_mod = @import("symbol.zig");
// First terminal thin client surface, scriptable for E2E-style tests.
// req: session/001, session/003, ui/001, coding/001, testing/001, testing/002
@@ -180,6 +181,7 @@ pub const Client = struct {
defer self.allocator.free(line);
try self.applyProtocol(line);
},
.symbol => |symbol| try self.applyProtocol(symbol_mod.protocolCommand(symbol)),
.not_built => {},
}
}
@@ -414,3 +416,54 @@ test "adversarial: unknown leader input recovers without saving or quitting" {
try std.testing.expect(!client.quit);
try std.testing.expectError(Error.NothingSaved, client.saved());
}
fn expectSymbolTrace(symbol_key: []const u8, expected_bytes: []const u8, expected_cursor_byte: usize) !void {
var client = try Client.init(std.testing.allocator, .{ .width = 64, .height = 4 });
defer client.deinit();
try client.handleTraceLine("open base");
try client.handleTraceLine("key space");
try client.handleTraceLine("key p");
const rail = try client.render(std.testing.allocator);
defer std.testing.allocator.free(rail);
try std.testing.expect(std.mem.indexOf(u8, rail, "symbols:") != null);
const line = try std.fmt.allocPrint(std.testing.allocator, "key {s}", .{symbol_key});
defer std.testing.allocator.free(line);
try client.handleTraceLine(line);
const snap = try client.session.snapshot();
try std.testing.expectEqualStrings(expected_bytes, snap.bytes);
try std.testing.expectEqual(expected_cursor_byte, snap.cursor_byte);
}
test "regular: symbol rail inserts paired braces brackets parens and quotes with cursor inside" {
try expectSymbolTrace("p", "()base", 1);
try expectSymbolTrace("b", "[]base", 1);
try expectSymbolTrace("c", "{}base", 1);
try expectSymbolTrace("q", "\"\"base", 1);
try expectSymbolTrace("e", "''base", 1);
try expectSymbolTrace("t", "``base", 1);
}
test "regular: symbol rail inserts slash pipe and underscore as single symbols" {
try expectSymbolTrace("s", "/base", 1);
try expectSymbolTrace("v", "|base", 1);
try expectSymbolTrace("u", "_base", 1);
}
test "adversarial: unknown symbol key does not mutate the buffer" {
var client = try Client.init(std.testing.allocator, .{ .width = 64, .height = 4 });
defer client.deinit();
try client.handleTraceLine("open base");
try client.handleTraceLine("key space");
try client.handleTraceLine("key p");
try client.handleTraceLine("key ?");
const snap = try client.session.snapshot();
try std.testing.expectEqualStrings("base", snap.bytes);
const frame = try client.render(std.testing.allocator);
defer std.testing.allocator.free(frame);
try std.testing.expect(std.mem.indexOf(u8, frame, "unknown symbol key") != null);
}