parser: add unit tests
Test (nearly?) implementation so far Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
This commit is contained in:
parent
4ac15e2195
commit
244ad8b68e
2 changed files with 176 additions and 13 deletions
|
@ -6,4 +6,6 @@ pub const Event = union(enum) {
|
||||||
key_press: Key,
|
key_press: Key,
|
||||||
focus_in,
|
focus_in,
|
||||||
focus_out,
|
focus_out,
|
||||||
|
paste_start,
|
||||||
|
paste_end,
|
||||||
};
|
};
|
||||||
|
|
187
src/parser.zig
187
src/parser.zig
|
@ -106,13 +106,12 @@ pub fn parse(input: []const u8) !Result {
|
||||||
};
|
};
|
||||||
return .{
|
return .{
|
||||||
.event = .{ .key_press = key },
|
.event = .{ .key_press = key },
|
||||||
.n = i,
|
.n = i + 1,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.ss3 => {
|
.ss3 => {
|
||||||
state = .ground;
|
|
||||||
const key: Key = switch (b) {
|
const key: Key = switch (b) {
|
||||||
'A' => .{ .codepoint = Key.up },
|
'A' => .{ .codepoint = Key.up },
|
||||||
'B' => .{ .codepoint = Key.down },
|
'B' => .{ .codepoint = Key.down },
|
||||||
|
@ -128,13 +127,13 @@ pub fn parse(input: []const u8) !Result {
|
||||||
log.warn("unhandled ss3: {x}", .{b});
|
log.warn("unhandled ss3: {x}", .{b});
|
||||||
return .{
|
return .{
|
||||||
.event = null,
|
.event = null,
|
||||||
.n = i,
|
.n = i + 1,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
return .{
|
return .{
|
||||||
.event = .{ .key_press = key },
|
.event = .{ .key_press = key },
|
||||||
.n = i,
|
.n = i + 1,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
.csi => {
|
.csi => {
|
||||||
|
@ -231,12 +230,16 @@ pub fn parse(input: []const u8) !Result {
|
||||||
23 => break :blk Key.f11,
|
23 => break :blk Key.f11,
|
||||||
24 => break :blk Key.f12,
|
24 => break :blk Key.f12,
|
||||||
200 => {
|
200 => {
|
||||||
// TODO: bracketed paste
|
return .{
|
||||||
continue;
|
.event = .paste_start,
|
||||||
|
.n = i + 1,
|
||||||
|
};
|
||||||
},
|
},
|
||||||
201 => {
|
201 => {
|
||||||
// TODO: bracketed paste
|
return .{
|
||||||
continue;
|
.event = .paste_end,
|
||||||
|
.n = i + 1,
|
||||||
|
};
|
||||||
},
|
},
|
||||||
57427 => break :blk Key.kp_begin,
|
57427 => break :blk Key.kp_begin,
|
||||||
else => {
|
else => {
|
||||||
|
@ -262,10 +265,10 @@ pub fn parse(input: []const u8) !Result {
|
||||||
},
|
},
|
||||||
|
|
||||||
'I' => { // focus in
|
'I' => { // focus in
|
||||||
return .{ .event = .focus_in, .n = i };
|
return .{ .event = .focus_in, .n = i + 1 };
|
||||||
},
|
},
|
||||||
'O' => { // focus out
|
'O' => { // focus out
|
||||||
return .{ .event = .focus_out, .n = i };
|
return .{ .event = .focus_out, .n = i + 1 };
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
log.warn("unhandled csi: CSI {s}", .{input[start + 1 .. i + 1]});
|
log.warn("unhandled csi: CSI {s}", .{input[start + 1 .. i + 1]});
|
||||||
|
@ -316,7 +319,7 @@ pub fn parse(input: []const u8) !Result {
|
||||||
}
|
}
|
||||||
return .{
|
return .{
|
||||||
.event = .{ .key_press = key },
|
.event = .{ .key_press = key },
|
||||||
.n = i,
|
.n = i + 1,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -332,7 +335,7 @@ pub fn parse(input: []const u8) !Result {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
test "parse: single legacy keypress" {
|
test "parse: single xterm keypress" {
|
||||||
const input = "a";
|
const input = "a";
|
||||||
const result = try parse(input);
|
const result = try parse(input);
|
||||||
const expected_key: Key = .{ .codepoint = 'a' };
|
const expected_key: Key = .{ .codepoint = 'a' };
|
||||||
|
@ -342,7 +345,7 @@ test "parse: single legacy keypress" {
|
||||||
try testing.expectEqual(expected_event, result.event);
|
try testing.expectEqual(expected_event, result.event);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "parse: single legacy keypress with more buffer" {
|
test "parse: single xterm keypress with more buffer" {
|
||||||
const input = "ab";
|
const input = "ab";
|
||||||
const result = try parse(input);
|
const result = try parse(input);
|
||||||
const expected_key: Key = .{ .codepoint = 'a' };
|
const expected_key: Key = .{ .codepoint = 'a' };
|
||||||
|
@ -351,3 +354,161 @@ test "parse: single legacy keypress with more buffer" {
|
||||||
try testing.expectEqual(1, result.n);
|
try testing.expectEqual(1, result.n);
|
||||||
try testing.expectEqual(expected_event, result.event);
|
try testing.expectEqual(expected_event, result.event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "parse: xterm escape keypress" {
|
||||||
|
const input = "\x1b";
|
||||||
|
const result = try parse(input);
|
||||||
|
const expected_key: Key = .{ .codepoint = Key.escape };
|
||||||
|
const expected_event: Event = .{ .key_press = expected_key };
|
||||||
|
|
||||||
|
try testing.expectEqual(1, result.n);
|
||||||
|
try testing.expectEqual(expected_event, result.event);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "parse: xterm ctrl+a" {
|
||||||
|
const input = "\x01";
|
||||||
|
const result = try parse(input);
|
||||||
|
const expected_key: Key = .{ .codepoint = 'a', .mods = .{ .ctrl = true } };
|
||||||
|
const expected_event: Event = .{ .key_press = expected_key };
|
||||||
|
|
||||||
|
try testing.expectEqual(1, result.n);
|
||||||
|
try testing.expectEqual(expected_event, result.event);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "parse: xterm alt+a" {
|
||||||
|
const input = "\x1ba";
|
||||||
|
const result = try parse(input);
|
||||||
|
const expected_key: Key = .{ .codepoint = 'a', .mods = .{ .alt = true } };
|
||||||
|
const expected_event: Event = .{ .key_press = expected_key };
|
||||||
|
|
||||||
|
try testing.expectEqual(2, result.n);
|
||||||
|
try testing.expectEqual(expected_event, result.event);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "parse: xterm invalid ss3" {
|
||||||
|
const input = "\x1bOZ";
|
||||||
|
const result = try parse(input);
|
||||||
|
|
||||||
|
try testing.expectEqual(3, result.n);
|
||||||
|
try testing.expectEqual(null, result.event);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "parse: xterm key up" {
|
||||||
|
{
|
||||||
|
// normal version
|
||||||
|
const input = "\x1bOA";
|
||||||
|
const result = try parse(input);
|
||||||
|
const expected_key: Key = .{ .codepoint = Key.up };
|
||||||
|
const expected_event: Event = .{ .key_press = expected_key };
|
||||||
|
|
||||||
|
try testing.expectEqual(3, result.n);
|
||||||
|
try testing.expectEqual(expected_event, result.event);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// application keys version
|
||||||
|
const input = "\x1b[2~";
|
||||||
|
const result = try parse(input);
|
||||||
|
const expected_key: Key = .{ .codepoint = Key.insert };
|
||||||
|
const expected_event: Event = .{ .key_press = expected_key };
|
||||||
|
|
||||||
|
try testing.expectEqual(4, result.n);
|
||||||
|
try testing.expectEqual(expected_event, result.event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "parse: xterm shift+up" {
|
||||||
|
const input = "\x1b[1;2A";
|
||||||
|
const result = try parse(input);
|
||||||
|
const expected_key: Key = .{ .codepoint = Key.up, .mods = .{ .shift = true } };
|
||||||
|
const expected_event: Event = .{ .key_press = expected_key };
|
||||||
|
|
||||||
|
try testing.expectEqual(6, result.n);
|
||||||
|
try testing.expectEqual(expected_event, result.event);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "parse: xterm insert" {
|
||||||
|
const input = "\x1b[1;2A";
|
||||||
|
const result = try parse(input);
|
||||||
|
const expected_key: Key = .{ .codepoint = Key.up, .mods = .{ .shift = true } };
|
||||||
|
const expected_event: Event = .{ .key_press = expected_key };
|
||||||
|
|
||||||
|
try testing.expectEqual(6, result.n);
|
||||||
|
try testing.expectEqual(expected_event, result.event);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "parse: paste_start" {
|
||||||
|
const input = "\x1b[200~";
|
||||||
|
const result = try parse(input);
|
||||||
|
const expected_event: Event = .paste_start;
|
||||||
|
|
||||||
|
try testing.expectEqual(6, result.n);
|
||||||
|
try testing.expectEqual(expected_event, result.event);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "parse: paste_end" {
|
||||||
|
const input = "\x1b[201~";
|
||||||
|
const result = try parse(input);
|
||||||
|
const expected_event: Event = .paste_end;
|
||||||
|
|
||||||
|
try testing.expectEqual(6, result.n);
|
||||||
|
try testing.expectEqual(expected_event, result.event);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "parse: focus_in" {
|
||||||
|
const input = "\x1b[I";
|
||||||
|
const result = try parse(input);
|
||||||
|
const expected_event: Event = .focus_in;
|
||||||
|
|
||||||
|
try testing.expectEqual(3, result.n);
|
||||||
|
try testing.expectEqual(expected_event, result.event);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "parse: focus_out" {
|
||||||
|
const input = "\x1b[O";
|
||||||
|
const result = try parse(input);
|
||||||
|
const expected_event: Event = .focus_out;
|
||||||
|
|
||||||
|
try testing.expectEqual(3, result.n);
|
||||||
|
try testing.expectEqual(expected_event, result.event);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "parse: kitty: shift+a without text reporting" {
|
||||||
|
const input = "\x1b[97:65;2u";
|
||||||
|
const result = try parse(input);
|
||||||
|
const expected_key: Key = .{
|
||||||
|
.codepoint = 'a',
|
||||||
|
.shifted_codepoint = 'A',
|
||||||
|
.mods = .{ .shift = true },
|
||||||
|
};
|
||||||
|
const expected_event: Event = .{ .key_press = expected_key };
|
||||||
|
|
||||||
|
try testing.expectEqual(10, result.n);
|
||||||
|
try testing.expectEqual(expected_event, result.event);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "parse: kitty: alt+shift+a without text reporting" {
|
||||||
|
const input = "\x1b[97:65;4u";
|
||||||
|
const result = try parse(input);
|
||||||
|
const expected_key: Key = .{
|
||||||
|
.codepoint = 'a',
|
||||||
|
.shifted_codepoint = 'A',
|
||||||
|
.mods = .{ .shift = true, .alt = true },
|
||||||
|
};
|
||||||
|
const expected_event: Event = .{ .key_press = expected_key };
|
||||||
|
|
||||||
|
try testing.expectEqual(10, result.n);
|
||||||
|
try testing.expectEqual(expected_event, result.event);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "parse: kitty: a without text reporting" {
|
||||||
|
const input = "\x1b[97u";
|
||||||
|
const result = try parse(input);
|
||||||
|
const expected_key: Key = .{
|
||||||
|
.codepoint = 'a',
|
||||||
|
};
|
||||||
|
const expected_event: Event = .{ .key_press = expected_key };
|
||||||
|
|
||||||
|
try testing.expectEqual(5, result.n);
|
||||||
|
try testing.expectEqual(expected_event, result.event);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue