From f03344b1c61b1867afae4df859f099460c2319a0 Mon Sep 17 00:00:00 2001 From: "Jeffrey C. Ollie" Date: Sun, 5 Oct 2025 19:46:04 -0500 Subject: osc: reorder osc tests and name them consistently --- src/terminal/osc.zig | 766 ++++++++++++++++++++++++--------------------- src/terminal/osc/color.zig | 22 +- 2 files changed, 418 insertions(+), 370 deletions(-) (limited to 'src') diff --git a/src/terminal/osc.zig b/src/terminal/osc.zig index 897a5ef0f..1d41d95f2 100644 --- a/src/terminal/osc.zig +++ b/src/terminal/osc.zig @@ -1691,7 +1691,7 @@ test { _ = osc_color; } -test "OSC: change_window_title" { +test "OSC 0: change_window_title" { const testing = std.testing; var p: Parser = .init(); @@ -1704,53 +1704,49 @@ test "OSC: change_window_title" { try testing.expectEqualStrings("ab", cmd.change_window_title); } -test "OSC: change_window_title with 2" { +test "OSC 0: longer than buffer" { const testing = std.testing; var p: Parser = .init(); - p.next('2'); - p.next(';'); - p.next('a'); - p.next('b'); - const cmd = p.end(null).?.*; - try testing.expect(cmd == .change_window_title); - try testing.expectEqualStrings("ab", cmd.change_window_title); + + const input = "0;" ++ "a" ** (Parser.MAX_BUF + 2); + for (input) |ch| p.next(ch); + + try testing.expect(p.end(null) == null); + try testing.expect(p.complete == false); } -test "OSC: change_window_title with utf8" { +test "OSC 0: one shorter than buffer length" { const testing = std.testing; var p: Parser = .init(); - p.next('2'); - p.next(';'); - // '—' EM DASH U+2014 (E2 80 94) - p.next(0xE2); - p.next(0x80); - p.next(0x94); - p.next(' '); - // '‐' HYPHEN U+2010 (E2 80 90) - // Intententionally chosen to conflict with the 0x90 C1 control - p.next(0xE2); - p.next(0x80); - p.next(0x90); + const prefix = "0;"; + const title = "a" ** (Parser.MAX_BUF - prefix.len - 1); + const input = prefix ++ title; + for (input) |ch| p.next(ch); + const cmd = p.end(null).?.*; try testing.expect(cmd == .change_window_title); - try testing.expectEqualStrings("— ‐", cmd.change_window_title); + try testing.expectEqualStrings(title, cmd.change_window_title); } -test "OSC: change_window_title empty" { +test "OSC 0: exactly at buffer length" { const testing = std.testing; var p: Parser = .init(); - p.next('2'); - p.next(';'); - const cmd = p.end(null).?.*; - try testing.expect(cmd == .change_window_title); - try testing.expectEqualStrings("", cmd.change_window_title); + + const prefix = "0;"; + const title = "a" ** (Parser.MAX_BUF - prefix.len); + const input = prefix ++ title; + for (input) |ch| p.next(ch); + + // This should be null because we always reserve space for a null terminator. + try testing.expect(p.end(null) == null); + try testing.expect(p.complete == false); } -test "OSC: change_window_icon" { +test "OSC 1: change_window_icon" { const testing = std.testing; var p: Parser = .init(); @@ -1763,274 +1759,229 @@ test "OSC: change_window_icon" { try testing.expectEqualStrings("ab", cmd.change_window_icon); } -test "OSC: prompt_start" { - const testing = std.testing; - - var p: Parser = .init(); - - const input = "133;A"; - for (input) |ch| p.next(ch); - - const cmd = p.end(null).?.*; - try testing.expect(cmd == .prompt_start); - try testing.expect(cmd.prompt_start.aid == null); - try testing.expect(cmd.prompt_start.redraw); -} - -test "OSC: prompt_start with single option" { +test "OSC 2: change_window_title with 2" { const testing = std.testing; var p: Parser = .init(); - - const input = "133;A;aid=14"; - for (input) |ch| p.next(ch); - + p.next('2'); + p.next(';'); + p.next('a'); + p.next('b'); const cmd = p.end(null).?.*; - try testing.expect(cmd == .prompt_start); - try testing.expectEqualStrings("14", cmd.prompt_start.aid.?); + try testing.expect(cmd == .change_window_title); + try testing.expectEqualStrings("ab", cmd.change_window_title); } -test "OSC: prompt_start with redraw disabled" { +test "OSC 2: change_window_title with utf8" { const testing = std.testing; var p: Parser = .init(); + p.next('2'); + p.next(';'); + // '—' EM DASH U+2014 (E2 80 94) + p.next(0xE2); + p.next(0x80); + p.next(0x94); - const input = "133;A;redraw=0"; - for (input) |ch| p.next(ch); - + p.next(' '); + // '‐' HYPHEN U+2010 (E2 80 90) + // Intententionally chosen to conflict with the 0x90 C1 control + p.next(0xE2); + p.next(0x80); + p.next(0x90); const cmd = p.end(null).?.*; - try testing.expect(cmd == .prompt_start); - try testing.expect(!cmd.prompt_start.redraw); + try testing.expect(cmd == .change_window_title); + try testing.expectEqualStrings("— ‐", cmd.change_window_title); } -test "OSC: prompt_start with redraw invalid value" { +test "OSC 2: change_window_title empty" { const testing = std.testing; var p: Parser = .init(); - - const input = "133;A;redraw=42"; - for (input) |ch| p.next(ch); - + p.next('2'); + p.next(';'); const cmd = p.end(null).?.*; - try testing.expect(cmd == .prompt_start); - try testing.expect(cmd.prompt_start.redraw); - try testing.expect(cmd.prompt_start.kind == .primary); + try testing.expect(cmd == .change_window_title); + try testing.expectEqualStrings("", cmd.change_window_title); } -test "OSC: prompt_start with continuation" { +test "OSC 4: empty param" { const testing = std.testing; var p: Parser = .init(); - const input = "133;A;k=c"; + const input = "4;;"; for (input) |ch| p.next(ch); - const cmd = p.end(null).?.*; - try testing.expect(cmd == .prompt_start); - try testing.expect(cmd.prompt_start.kind == .continuation); + const cmd = p.end('\x1b'); + try testing.expect(cmd == null); } -test "OSC: prompt_start with secondary" { - const testing = std.testing; - - var p: Parser = .init(); - - const input = "133;A;k=s"; - for (input) |ch| p.next(ch); +// See src/terminal/osc/color.zig for more OSC 4 tests. - const cmd = p.end(null).?.*; - try testing.expect(cmd == .prompt_start); - try testing.expect(cmd.prompt_start.kind == .secondary); -} +// See src/terminal/osc/color.zig for OSC 5 tests. -test "OSC: end_of_command no exit code" { +test "OSC 7: report pwd" { const testing = std.testing; var p: Parser = .init(); - const input = "133;D"; + const input = "7;file:///tmp/example"; for (input) |ch| p.next(ch); const cmd = p.end(null).?.*; - try testing.expect(cmd == .end_of_command); + try testing.expect(cmd == .report_pwd); + try testing.expectEqualStrings("file:///tmp/example", cmd.report_pwd.value); } -test "OSC: end_of_command with exit code" { +test "OSC 7: report pwd empty" { const testing = std.testing; var p: Parser = .init(); - const input = "133;D;25"; + const input = "7;"; for (input) |ch| p.next(ch); - const cmd = p.end(null).?.*; - try testing.expect(cmd == .end_of_command); - try testing.expectEqual(@as(u8, 25), cmd.end_of_command.exit_code.?); + try testing.expect(cmd == .report_pwd); + try testing.expectEqualStrings("", cmd.report_pwd.value); } -test "OSC: prompt_end" { +test "OSC 8: hyperlink" { const testing = std.testing; var p: Parser = .init(); - const input = "133;B"; + const input = "8;;http://example.com"; for (input) |ch| p.next(ch); - const cmd = p.end(null).?.*; - try testing.expect(cmd == .prompt_end); + const cmd = p.end('\x1b').?.*; + try testing.expect(cmd == .hyperlink_start); + try testing.expectEqualStrings(cmd.hyperlink_start.uri, "http://example.com"); } -test "OSC: end_of_input" { +test "OSC 8: hyperlink with id set" { const testing = std.testing; var p: Parser = .init(); - const input = "133;C"; + const input = "8;id=foo;http://example.com"; for (input) |ch| p.next(ch); - const cmd = p.end(null).?.*; - try testing.expect(cmd == .end_of_input); + const cmd = p.end('\x1b').?.*; + try testing.expect(cmd == .hyperlink_start); + try testing.expectEqualStrings(cmd.hyperlink_start.id.?, "foo"); + try testing.expectEqualStrings(cmd.hyperlink_start.uri, "http://example.com"); } -test "OSC: get/set clipboard" { +test "OSC 8: hyperlink with empty id" { const testing = std.testing; var p: Parser = .init(); - const input = "52;s;?"; + const input = "8;id=;http://example.com"; for (input) |ch| p.next(ch); - const cmd = p.end(null).?.*; - try testing.expect(cmd == .clipboard_contents); - try testing.expect(cmd.clipboard_contents.kind == 's'); - try testing.expectEqualStrings("?", cmd.clipboard_contents.data); + const cmd = p.end('\x1b').?.*; + try testing.expect(cmd == .hyperlink_start); + try testing.expectEqual(null, cmd.hyperlink_start.id); + try testing.expectEqualStrings(cmd.hyperlink_start.uri, "http://example.com"); } -test "OSC: get/set clipboard (optional parameter)" { +test "OSC 8: hyperlink with incomplete key" { const testing = std.testing; var p: Parser = .init(); - const input = "52;;?"; - for (input) |ch| p.next(ch); - - const cmd = p.end(null).?.*; - try testing.expect(cmd == .clipboard_contents); - try testing.expect(cmd.clipboard_contents.kind == 'c'); - try testing.expectEqualStrings("?", cmd.clipboard_contents.data); -} - -test "OSC: get/set clipboard with allocator" { - const testing = std.testing; - - var p: Parser = .initAlloc(testing.allocator); - defer p.deinit(); - - const input = "52;s;?"; + const input = "8;id;http://example.com"; for (input) |ch| p.next(ch); - const cmd = p.end(null).?.*; - try testing.expect(cmd == .clipboard_contents); - try testing.expect(cmd.clipboard_contents.kind == 's'); - try testing.expectEqualStrings("?", cmd.clipboard_contents.data); + const cmd = p.end('\x1b').?.*; + try testing.expect(cmd == .hyperlink_start); + try testing.expectEqual(null, cmd.hyperlink_start.id); + try testing.expectEqualStrings(cmd.hyperlink_start.uri, "http://example.com"); } -test "OSC: clear clipboard" { +test "OSC 8: hyperlink with empty key" { const testing = std.testing; var p: Parser = .init(); - defer p.deinit(); - const input = "52;;"; + const input = "8;=value;http://example.com"; for (input) |ch| p.next(ch); - const cmd = p.end(null).?.*; - try testing.expect(cmd == .clipboard_contents); - try testing.expect(cmd.clipboard_contents.kind == 'c'); - try testing.expectEqualStrings("", cmd.clipboard_contents.data); + const cmd = p.end('\x1b').?.*; + try testing.expect(cmd == .hyperlink_start); + try testing.expectEqual(null, cmd.hyperlink_start.id); + try testing.expectEqualStrings(cmd.hyperlink_start.uri, "http://example.com"); } -test "OSC: report pwd" { +test "OSC 8: hyperlink with empty key and id" { const testing = std.testing; var p: Parser = .init(); - const input = "7;file:///tmp/example"; + const input = "8;=value:id=foo;http://example.com"; for (input) |ch| p.next(ch); - const cmd = p.end(null).?.*; - try testing.expect(cmd == .report_pwd); - try testing.expectEqualStrings("file:///tmp/example", cmd.report_pwd.value); -} - -test "OSC: report pwd empty" { - const testing = std.testing; - - var p: Parser = .init(); - - const input = "7;"; - for (input) |ch| p.next(ch); - const cmd = p.end(null).?.*; - try testing.expect(cmd == .report_pwd); - try testing.expectEqualStrings("", cmd.report_pwd.value); + const cmd = p.end('\x1b').?.*; + try testing.expect(cmd == .hyperlink_start); + try testing.expectEqualStrings(cmd.hyperlink_start.id.?, "foo"); + try testing.expectEqualStrings(cmd.hyperlink_start.uri, "http://example.com"); } -test "OSC: pointer cursor" { +test "OSC 8: hyperlink with empty uri" { const testing = std.testing; var p: Parser = .init(); - const input = "22;pointer"; + const input = "8;id=foo;"; for (input) |ch| p.next(ch); - const cmd = p.end(null).?.*; - try testing.expect(cmd == .mouse_shape); - try testing.expectEqualStrings("pointer", cmd.mouse_shape.value); + const cmd = p.end('\x1b'); + try testing.expect(cmd == null); } -test "OSC: longer than buffer" { +test "OSC 8: hyperlink end" { const testing = std.testing; var p: Parser = .init(); - const input = "0;" ++ "a" ** (Parser.MAX_BUF + 2); + const input = "8;;"; for (input) |ch| p.next(ch); - try testing.expect(p.end(null) == null); - try testing.expect(p.complete == false); + const cmd = p.end('\x1b').?.*; + try testing.expect(cmd == .hyperlink_end); } -test "OSC: one shorter than buffer length" { +test "OSC 9: show desktop notification" { const testing = std.testing; var p: Parser = .init(); - const prefix = "0;"; - const title = "a" ** (Parser.MAX_BUF - prefix.len - 1); - const input = prefix ++ title; + const input = "9;Hello world"; for (input) |ch| p.next(ch); - const cmd = p.end(null).?.*; - try testing.expect(cmd == .change_window_title); - try testing.expectEqualStrings(title, cmd.change_window_title); + const cmd = p.end('\x1b').?.*; + try testing.expect(cmd == .show_desktop_notification); + try testing.expectEqualStrings("", cmd.show_desktop_notification.title); + try testing.expectEqualStrings("Hello world", cmd.show_desktop_notification.body); } -test "OSC: exactly at buffer length" { +test "OSC 9: show single character desktop notification" { const testing = std.testing; var p: Parser = .init(); - const prefix = "0;"; - const title = "a" ** (Parser.MAX_BUF - prefix.len); - const input = prefix ++ title; + const input = "9;H"; for (input) |ch| p.next(ch); - // This should be null because we always reserve space for a null terminator. - try testing.expect(p.end(null) == null); - try testing.expect(p.complete == false); + const cmd = p.end('\x1b').?.*; + try testing.expect(cmd == .show_desktop_notification); + try testing.expectEqualStrings("", cmd.show_desktop_notification.title); + try testing.expectEqualStrings("H", cmd.show_desktop_notification.body); } -test "OSC: OSC 9;1 ConEmu sleep" { +test "OSC 9;1: ConEmu sleep" { const testing = std.testing; var p: Parser = .init(); @@ -2044,7 +1995,7 @@ test "OSC: OSC 9;1 ConEmu sleep" { try testing.expectEqual(420, cmd.conemu_sleep.duration_ms); } -test "OSC: OSC 9;1 ConEmu sleep with no value default to 100ms" { +test "OSC 9;1: ConEmu sleep with no value default to 100ms" { const testing = std.testing; var p: Parser = .init(); @@ -2058,7 +2009,7 @@ test "OSC: OSC 9;1 ConEmu sleep with no value default to 100ms" { try testing.expectEqual(100, cmd.conemu_sleep.duration_ms); } -test "OSC: OSC 9;1 conemu sleep cannot exceed 10000ms" { +test "OSC 9;1: conemu sleep cannot exceed 10000ms" { const testing = std.testing; var p: Parser = .init(); @@ -2072,7 +2023,7 @@ test "OSC: OSC 9;1 conemu sleep cannot exceed 10000ms" { try testing.expectEqual(10000, cmd.conemu_sleep.duration_ms); } -test "OSC: OSC 9;1 conemu sleep invalid input" { +test "OSC 9;1: conemu sleep invalid input" { const testing = std.testing; var p: Parser = .init(); @@ -2086,7 +2037,7 @@ test "OSC: OSC 9;1 conemu sleep invalid input" { try testing.expectEqual(100, cmd.conemu_sleep.duration_ms); } -test "OSC: OSC 9;1 conemu sleep -> desktop notification 1" { +test "OSC 9;1: conemu sleep -> desktop notification 1" { const testing = std.testing; var p: Parser = .init(); @@ -2100,7 +2051,7 @@ test "OSC: OSC 9;1 conemu sleep -> desktop notification 1" { try testing.expectEqualStrings("1", cmd.show_desktop_notification.body); } -test "OSC: OSC 9;1 conemu sleep -> desktop notification 2" { +test "OSC 9;1: conemu sleep -> desktop notification 2" { const testing = std.testing; var p: Parser = .init(); @@ -2114,67 +2065,25 @@ test "OSC: OSC 9;1 conemu sleep -> desktop notification 2" { try testing.expectEqualStrings("1a", cmd.show_desktop_notification.body); } -test "OSC: OSC 9 show desktop notification" { +test "OSC 9;2: ConEmu message box" { const testing = std.testing; var p: Parser = .init(); - const input = "9;Hello world"; + const input = "9;2;hello world"; for (input) |ch| p.next(ch); const cmd = p.end('\x1b').?.*; - try testing.expect(cmd == .show_desktop_notification); - try testing.expectEqualStrings("", cmd.show_desktop_notification.title); - try testing.expectEqualStrings("Hello world", cmd.show_desktop_notification.body); + try testing.expect(cmd == .conemu_show_message_box); + try testing.expectEqualStrings("hello world", cmd.conemu_show_message_box); } -test "OSC: OSC 9 show single character desktop notification" { +test "OSC 9;2: ConEmu message box invalid input" { const testing = std.testing; var p: Parser = .init(); - const input = "9;H"; - for (input) |ch| p.next(ch); - - const cmd = p.end('\x1b').?.*; - try testing.expect(cmd == .show_desktop_notification); - try testing.expectEqualStrings("", cmd.show_desktop_notification.title); - try testing.expectEqualStrings("H", cmd.show_desktop_notification.body); -} - -test "OSC: OSC 777 show desktop notification with title" { - const testing = std.testing; - - var p: Parser = .init(); - - const input = "777;notify;Title;Body"; - for (input) |ch| p.next(ch); - - const cmd = p.end('\x1b').?.*; - try testing.expect(cmd == .show_desktop_notification); - try testing.expectEqualStrings(cmd.show_desktop_notification.title, "Title"); - try testing.expectEqualStrings(cmd.show_desktop_notification.body, "Body"); -} - -test "OSC: OSC 9;2 ConEmu message box" { - const testing = std.testing; - - var p: Parser = .init(); - - const input = "9;2;hello world"; - for (input) |ch| p.next(ch); - - const cmd = p.end('\x1b').?.*; - try testing.expect(cmd == .conemu_show_message_box); - try testing.expectEqualStrings("hello world", cmd.conemu_show_message_box); -} - -test "OSC: 9;2 ConEmu message box invalid input" { - const testing = std.testing; - - var p: Parser = .init(); - - const input = "9;2"; + const input = "9;2"; for (input) |ch| p.next(ch); const cmd = p.end('\x1b').?.*; @@ -2182,7 +2091,7 @@ test "OSC: 9;2 ConEmu message box invalid input" { try testing.expectEqualStrings("2", cmd.show_desktop_notification.body); } -test "OSC: 9;2 ConEmu message box empty message" { +test "OSC 9;2: ConEmu message box empty message" { const testing = std.testing; var p: Parser = .init(); @@ -2195,7 +2104,7 @@ test "OSC: 9;2 ConEmu message box empty message" { try testing.expectEqualStrings("", cmd.conemu_show_message_box); } -test "OSC: 9;2 ConEmu message box spaces only message" { +test "OSC 9;2: ConEmu message box spaces only message" { const testing = std.testing; var p: Parser = .init(); @@ -2208,7 +2117,7 @@ test "OSC: 9;2 ConEmu message box spaces only message" { try testing.expectEqualStrings(" ", cmd.conemu_show_message_box); } -test "OSC: OSC 9;2 message box -> desktop notification 1" { +test "OSC 9;2: message box -> desktop notification 1" { const testing = std.testing; var p: Parser = .init(); @@ -2222,7 +2131,7 @@ test "OSC: OSC 9;2 message box -> desktop notification 1" { try testing.expectEqualStrings("2", cmd.show_desktop_notification.body); } -test "OSC: OSC 9;2 message box -> desktop notification 2" { +test "OSC 9;2: message box -> desktop notification 2" { const testing = std.testing; var p: Parser = .init(); @@ -2236,7 +2145,7 @@ test "OSC: OSC 9;2 message box -> desktop notification 2" { try testing.expectEqualStrings("2a", cmd.show_desktop_notification.body); } -test "OSC: 9;3 ConEmu change tab title" { +test "OSC 9;3: ConEmu change tab title" { const testing = std.testing; var p: Parser = .init(); @@ -2249,7 +2158,7 @@ test "OSC: 9;3 ConEmu change tab title" { try testing.expectEqualStrings("foo bar", cmd.conemu_change_tab_title.value); } -test "OSC: 9;3 ConEmu change tab title reset" { +test "OSC 9;3: ConEmu change tab title reset" { const testing = std.testing; var p: Parser = .init(); @@ -2263,7 +2172,7 @@ test "OSC: 9;3 ConEmu change tab title reset" { try testing.expectEqual(expected_command, cmd); } -test "OSC: 9;3 ConEmu change tab title spaces only" { +test "OSC 9;3: ConEmu change tab title spaces only" { const testing = std.testing; var p: Parser = .init(); @@ -2277,7 +2186,7 @@ test "OSC: 9;3 ConEmu change tab title spaces only" { try testing.expectEqualStrings(" ", cmd.conemu_change_tab_title.value); } -test "OSC: OSC 9;3 change tab title -> desktop notification 1" { +test "OSC 9;3: change tab title -> desktop notification 1" { const testing = std.testing; var p: Parser = .init(); @@ -2291,7 +2200,7 @@ test "OSC: OSC 9;3 change tab title -> desktop notification 1" { try testing.expectEqualStrings("3", cmd.show_desktop_notification.body); } -test "OSC: OSC 9;3 message box -> desktop notification 2" { +test "OSC 9;3: message box -> desktop notification 2" { const testing = std.testing; var p: Parser = .init(); @@ -2305,7 +2214,7 @@ test "OSC: OSC 9;3 message box -> desktop notification 2" { try testing.expectEqualStrings("3a", cmd.show_desktop_notification.body); } -test "OSC: OSC 9;4 ConEmu progress set" { +test "OSC 9;4: ConEmu progress set" { const testing = std.testing; var p: Parser = .init(); @@ -2319,7 +2228,7 @@ test "OSC: OSC 9;4 ConEmu progress set" { try testing.expect(cmd.conemu_progress_report.progress == 100); } -test "OSC: OSC 9;4 ConEmu progress set overflow" { +test "OSC 9;4: ConEmu progress set overflow" { const testing = std.testing; var p: Parser = .init(); @@ -2333,7 +2242,7 @@ test "OSC: OSC 9;4 ConEmu progress set overflow" { try testing.expectEqual(100, cmd.conemu_progress_report.progress); } -test "OSC: OSC 9;4 ConEmu progress set single digit" { +test "OSC 9;4: ConEmu progress set single digit" { const testing = std.testing; var p: Parser = .init(); @@ -2347,7 +2256,7 @@ test "OSC: OSC 9;4 ConEmu progress set single digit" { try testing.expect(cmd.conemu_progress_report.progress == 9); } -test "OSC: OSC 9;4 ConEmu progress set double digit" { +test "OSC 9;4: ConEmu progress set double digit" { const testing = std.testing; var p: Parser = .init(); @@ -2361,7 +2270,7 @@ test "OSC: OSC 9;4 ConEmu progress set double digit" { try testing.expectEqual(94, cmd.conemu_progress_report.progress); } -test "OSC: OSC 9;4 ConEmu progress set extra semicolon ignored" { +test "OSC 9;4: ConEmu progress set extra semicolon ignored" { const testing = std.testing; var p: Parser = .init(); @@ -2375,7 +2284,7 @@ test "OSC: OSC 9;4 ConEmu progress set extra semicolon ignored" { try testing.expectEqual(100, cmd.conemu_progress_report.progress); } -test "OSC: OSC 9;4 ConEmu progress remove with no progress" { +test "OSC 9;4: ConEmu progress remove with no progress" { const testing = std.testing; var p: Parser = .init(); @@ -2389,7 +2298,7 @@ test "OSC: OSC 9;4 ConEmu progress remove with no progress" { try testing.expect(cmd.conemu_progress_report.progress == null); } -test "OSC: OSC 9;4 ConEmu progress remove with double semicolon" { +test "OSC 9;4: ConEmu progress remove with double semicolon" { const testing = std.testing; var p: Parser = .init(); @@ -2403,7 +2312,7 @@ test "OSC: OSC 9;4 ConEmu progress remove with double semicolon" { try testing.expect(cmd.conemu_progress_report.progress == null); } -test "OSC: OSC 9;4 ConEmu progress remove ignores progress" { +test "OSC 9;4: ConEmu progress remove ignores progress" { const testing = std.testing; var p: Parser = .init(); @@ -2417,7 +2326,7 @@ test "OSC: OSC 9;4 ConEmu progress remove ignores progress" { try testing.expect(cmd.conemu_progress_report.progress == null); } -test "OSC: OSC 9;4 ConEmu progress remove extra semicolon" { +test "OSC 9;4: ConEmu progress remove extra semicolon" { const testing = std.testing; var p: Parser = .init(); @@ -2430,7 +2339,7 @@ test "OSC: OSC 9;4 ConEmu progress remove extra semicolon" { try testing.expect(cmd.conemu_progress_report.state == .remove); } -test "OSC: OSC 9;4 ConEmu progress error" { +test "OSC 9;4: ConEmu progress error" { const testing = std.testing; var p: Parser = .init(); @@ -2444,7 +2353,7 @@ test "OSC: OSC 9;4 ConEmu progress error" { try testing.expect(cmd.conemu_progress_report.progress == null); } -test "OSC: OSC 9;4 ConEmu progress error with progress" { +test "OSC 9;4: ConEmu progress error with progress" { const testing = std.testing; var p: Parser = .init(); @@ -2458,7 +2367,7 @@ test "OSC: OSC 9;4 ConEmu progress error with progress" { try testing.expect(cmd.conemu_progress_report.progress == 100); } -test "OSC: OSC 9;4 progress pause" { +test "OSC 9;4: progress pause" { const testing = std.testing; var p: Parser = .init(); @@ -2472,7 +2381,7 @@ test "OSC: OSC 9;4 progress pause" { try testing.expect(cmd.conemu_progress_report.progress == null); } -test "OSC: OSC 9;4 ConEmu progress pause with progress" { +test "OSC 9;4: ConEmu progress pause with progress" { const testing = std.testing; var p: Parser = .init(); @@ -2486,7 +2395,7 @@ test "OSC: OSC 9;4 ConEmu progress pause with progress" { try testing.expect(cmd.conemu_progress_report.progress == 100); } -test "OSC: OSC 9;4 progress -> desktop notification 1" { +test "OSC 9;4: progress -> desktop notification 1" { const testing = std.testing; var p: Parser = .init(); @@ -2500,7 +2409,7 @@ test "OSC: OSC 9;4 progress -> desktop notification 1" { try testing.expectEqualStrings("4", cmd.show_desktop_notification.body); } -test "OSC: OSC 9;4 progress -> desktop notification 2" { +test "OSC 9;4: progress -> desktop notification 2" { const testing = std.testing; var p: Parser = .init(); @@ -2514,7 +2423,7 @@ test "OSC: OSC 9;4 progress -> desktop notification 2" { try testing.expectEqualStrings("4;", cmd.show_desktop_notification.body); } -test "OSC: OSC 9;4 progress -> desktop notification 3" { +test "OSC 9;4: progress -> desktop notification 3" { const testing = std.testing; var p: Parser = .init(); @@ -2528,7 +2437,7 @@ test "OSC: OSC 9;4 progress -> desktop notification 3" { try testing.expectEqualStrings("4;5", cmd.show_desktop_notification.body); } -test "OSC: OSC 9;4 progress -> desktop notification 4" { +test "OSC 9;4: progress -> desktop notification 4" { const testing = std.testing; var p: Parser = .init(); @@ -2542,7 +2451,7 @@ test "OSC: OSC 9;4 progress -> desktop notification 4" { try testing.expectEqualStrings("4;5a", cmd.show_desktop_notification.body); } -test "OSC: OSC 9;5 ConEmu wait input" { +test "OSC 9;5: ConEmu wait input" { const testing = std.testing; var p: Parser = .init(); @@ -2554,7 +2463,7 @@ test "OSC: OSC 9;5 ConEmu wait input" { try testing.expect(cmd == .conemu_wait_input); } -test "OSC: OSC 9;5 ConEmu wait ignores trailing characters" { +test "OSC 9;5: ConEmu wait ignores trailing characters" { const testing = std.testing; var p: Parser = .init(); @@ -2566,126 +2475,69 @@ test "OSC: OSC 9;5 ConEmu wait ignores trailing characters" { try testing.expect(cmd == .conemu_wait_input); } -test "OSC: empty param" { +test "OSC 9;6: ConEmu guimacro 1" { const testing = std.testing; - var p: Parser = .init(); - - const input = "4;;"; - for (input) |ch| p.next(ch); - - const cmd = p.end('\x1b'); - try testing.expect(cmd == null); -} - -test "OSC: hyperlink" { - const testing = std.testing; - - var p: Parser = .init(); - - const input = "8;;http://example.com"; - for (input) |ch| p.next(ch); - - const cmd = p.end('\x1b').?.*; - try testing.expect(cmd == .hyperlink_start); - try testing.expectEqualStrings(cmd.hyperlink_start.uri, "http://example.com"); -} - -test "OSC: hyperlink with id set" { - const testing = std.testing; - - var p: Parser = .init(); - - const input = "8;id=foo;http://example.com"; - for (input) |ch| p.next(ch); - - const cmd = p.end('\x1b').?.*; - try testing.expect(cmd == .hyperlink_start); - try testing.expectEqualStrings(cmd.hyperlink_start.id.?, "foo"); - try testing.expectEqualStrings(cmd.hyperlink_start.uri, "http://example.com"); -} - -test "OSC: hyperlink with empty id" { - const testing = std.testing; - - var p: Parser = .init(); + var p: Parser = .initAlloc(testing.allocator); + defer p.deinit(); - const input = "8;id=;http://example.com"; + const input = "9;6;a"; for (input) |ch| p.next(ch); const cmd = p.end('\x1b').?.*; - try testing.expect(cmd == .hyperlink_start); - try testing.expectEqual(null, cmd.hyperlink_start.id); - try testing.expectEqualStrings(cmd.hyperlink_start.uri, "http://example.com"); + try testing.expect(cmd == .conemu_guimacro); + try testing.expectEqualStrings("a", cmd.conemu_guimacro); } -test "OSC: hyperlink with incomplete key" { +test "OSC: 9;6: ConEmu guimacro 2" { const testing = std.testing; - var p: Parser = .init(); + var p: Parser = .initAlloc(testing.allocator); + defer p.deinit(); - const input = "8;id;http://example.com"; + const input = "9;6;ab"; for (input) |ch| p.next(ch); const cmd = p.end('\x1b').?.*; - try testing.expect(cmd == .hyperlink_start); - try testing.expectEqual(null, cmd.hyperlink_start.id); - try testing.expectEqualStrings(cmd.hyperlink_start.uri, "http://example.com"); + try testing.expect(cmd == .conemu_guimacro); + try testing.expectEqualStrings("ab", cmd.conemu_guimacro); } -test "OSC: hyperlink with empty key" { +test "OSC: 9;6: ConEmu guimacro 3 incomplete -> desktop notification" { const testing = std.testing; - var p: Parser = .init(); + var p: Parser = .initAlloc(testing.allocator); + defer p.deinit(); - const input = "8;=value;http://example.com"; + const input = "9;6"; for (input) |ch| p.next(ch); const cmd = p.end('\x1b').?.*; - try testing.expect(cmd == .hyperlink_start); - try testing.expectEqual(null, cmd.hyperlink_start.id); - try testing.expectEqualStrings(cmd.hyperlink_start.uri, "http://example.com"); + try testing.expect(cmd == .show_desktop_notification); + try testing.expectEqualStrings("6", cmd.show_desktop_notification.body); } -test "OSC: hyperlink with empty key and id" { - const testing = std.testing; - - var p: Parser = .init(); - - const input = "8;=value:id=foo;http://example.com"; - for (input) |ch| p.next(ch); +// See src/terminal/osc/color.zig for OSC 10 tests. - const cmd = p.end('\x1b').?.*; - try testing.expect(cmd == .hyperlink_start); - try testing.expectEqualStrings(cmd.hyperlink_start.id.?, "foo"); - try testing.expectEqualStrings(cmd.hyperlink_start.uri, "http://example.com"); -} +// See src/terminal/osc/color.zig for OSC 11 tests. -test "OSC: hyperlink with empty uri" { - const testing = std.testing; +// See src/terminal/osc/color.zig for OSC 12 tests. - var p: Parser = .init(); +// See src/terminal/osc/color.zig for OSC 13 tests. - const input = "8;id=foo;"; - for (input) |ch| p.next(ch); +// See src/terminal/osc/color.zig for OSC 14 tests. - const cmd = p.end('\x1b'); - try testing.expect(cmd == null); -} +// See src/terminal/osc/color.zig for OSC 15 tests. -test "OSC: hyperlink end" { - const testing = std.testing; +// See src/terminal/osc/color.zig for OSC 16 tests. - var p: Parser = .init(); +// See src/terminal/osc/color.zig for OSC 17 tests. - const input = "8;;"; - for (input) |ch| p.next(ch); +// See src/terminal/osc/color.zig for OSC 18 tests. - const cmd = p.end('\x1b').?.*; - try testing.expect(cmd == .hyperlink_end); -} +// See src/terminal/osc/color.zig for OSC 19 tests. -test "OSC: kitty color protocol" { +test "OSC 21: kitty color protocol" { const testing = std.testing; const Kind = kitty_color.Kind; @@ -2757,7 +2609,7 @@ test "OSC: kitty color protocol" { } } -test "OSC: kitty color protocol without allocator" { +test "OSC 21: kitty color protocol without allocator" { const testing = std.testing; var p: Parser = .init(); @@ -2768,7 +2620,7 @@ test "OSC: kitty color protocol without allocator" { try testing.expect(p.end('\x1b') == null); } -test "OSC: kitty color protocol double reset" { +test "OSC 21: kitty color protocol double reset" { const testing = std.testing; var p: Parser = .initAlloc(testing.allocator); @@ -2784,7 +2636,7 @@ test "OSC: kitty color protocol double reset" { p.reset(); } -test "OSC: kitty color protocol reset after invalid" { +test "OSC 21: kitty color protocol reset after invalid" { const testing = std.testing; var p: Parser = .initAlloc(testing.allocator); @@ -2805,7 +2657,7 @@ test "OSC: kitty color protocol reset after invalid" { p.reset(); } -test "OSC: kitty color protocol no key" { +test "OSC 21: kitty color protocol no key" { const testing = std.testing; var p: Parser = .initAlloc(testing.allocator); @@ -2819,44 +2671,240 @@ test "OSC: kitty color protocol no key" { try testing.expectEqual(0, cmd.kitty_color_protocol.list.items.len); } -test "OSC: 9;6: ConEmu guimacro 1" { +test "OSC 22: pointer cursor" { const testing = std.testing; - var p: Parser = .initAlloc(testing.allocator); - defer p.deinit(); + var p: Parser = .init(); - const input = "9;6;a"; + const input = "22;pointer"; for (input) |ch| p.next(ch); - const cmd = p.end('\x1b').?.*; - try testing.expect(cmd == .conemu_guimacro); - try testing.expectEqualStrings("a", cmd.conemu_guimacro); + const cmd = p.end(null).?.*; + try testing.expect(cmd == .mouse_shape); + try testing.expectEqualStrings("pointer", cmd.mouse_shape.value); } -test "OSC: 9;6: ConEmu guimacro 2" { +test "OSC 52: get/set clipboard" { + const testing = std.testing; + + var p: Parser = .init(); + + const input = "52;s;?"; + for (input) |ch| p.next(ch); + + const cmd = p.end(null).?.*; + try testing.expect(cmd == .clipboard_contents); + try testing.expect(cmd.clipboard_contents.kind == 's'); + try testing.expectEqualStrings("?", cmd.clipboard_contents.data); +} + +test "OSC 52: get/set clipboard (optional parameter)" { + const testing = std.testing; + + var p: Parser = .init(); + + const input = "52;;?"; + for (input) |ch| p.next(ch); + + const cmd = p.end(null).?.*; + try testing.expect(cmd == .clipboard_contents); + try testing.expect(cmd.clipboard_contents.kind == 'c'); + try testing.expectEqualStrings("?", cmd.clipboard_contents.data); +} + +test "OSC 52: get/set clipboard with allocator" { const testing = std.testing; var p: Parser = .initAlloc(testing.allocator); defer p.deinit(); - const input = "9;6;ab"; + const input = "52;s;?"; for (input) |ch| p.next(ch); - const cmd = p.end('\x1b').?.*; - try testing.expect(cmd == .conemu_guimacro); - try testing.expectEqualStrings("ab", cmd.conemu_guimacro); + const cmd = p.end(null).?.*; + try testing.expect(cmd == .clipboard_contents); + try testing.expect(cmd.clipboard_contents.kind == 's'); + try testing.expectEqualStrings("?", cmd.clipboard_contents.data); } -test "OSC: 9;6: ConEmu guimacro 3 incomplete -> desktop notification" { +test "OSC 52: clear clipboard" { const testing = std.testing; - var p: Parser = .initAlloc(testing.allocator); + var p: Parser = .init(); defer p.deinit(); - const input = "9;6"; + const input = "52;;"; + for (input) |ch| p.next(ch); + + const cmd = p.end(null).?.*; + try testing.expect(cmd == .clipboard_contents); + try testing.expect(cmd.clipboard_contents.kind == 'c'); + try testing.expectEqualStrings("", cmd.clipboard_contents.data); +} + +// See src/terminal/osc/color.zig for OSC 104 tests. + +// See src/terminal/osc/color.zig for OSC 105 tests. + +// See src/terminal/osc/color.zig for OSC 110 tests. + +// See src/terminal/osc/color.zig for OSC 111 tests. + +// See src/terminal/osc/color.zig for OSC 112 tests. + +// See src/terminal/osc/color.zig for OSC 113 tests. + +// See src/terminal/osc/color.zig for OSC 114 tests. + +// See src/terminal/osc/color.zig for OSC 115 tests. + +// See src/terminal/osc/color.zig for OSC 116 tests. + +// See src/terminal/osc/color.zig for OSC 117 tests. + +// See src/terminal/osc/color.zig for OSC 118 tests. + +// See src/terminal/osc/color.zig for OSC 119 tests. + +test "OSC 133: prompt_start" { + const testing = std.testing; + + var p: Parser = .init(); + + const input = "133;A"; + for (input) |ch| p.next(ch); + + const cmd = p.end(null).?.*; + try testing.expect(cmd == .prompt_start); + try testing.expect(cmd.prompt_start.aid == null); + try testing.expect(cmd.prompt_start.redraw); +} + +test "OSC 133: prompt_start with single option" { + const testing = std.testing; + + var p: Parser = .init(); + + const input = "133;A;aid=14"; + for (input) |ch| p.next(ch); + + const cmd = p.end(null).?.*; + try testing.expect(cmd == .prompt_start); + try testing.expectEqualStrings("14", cmd.prompt_start.aid.?); +} + +test "OSC 133: prompt_start with redraw disabled" { + const testing = std.testing; + + var p: Parser = .init(); + + const input = "133;A;redraw=0"; + for (input) |ch| p.next(ch); + + const cmd = p.end(null).?.*; + try testing.expect(cmd == .prompt_start); + try testing.expect(!cmd.prompt_start.redraw); +} + +test "OSC 133: prompt_start with redraw invalid value" { + const testing = std.testing; + + var p: Parser = .init(); + + const input = "133;A;redraw=42"; + for (input) |ch| p.next(ch); + + const cmd = p.end(null).?.*; + try testing.expect(cmd == .prompt_start); + try testing.expect(cmd.prompt_start.redraw); + try testing.expect(cmd.prompt_start.kind == .primary); +} + +test "OSC 133: prompt_start with continuation" { + const testing = std.testing; + + var p: Parser = .init(); + + const input = "133;A;k=c"; + for (input) |ch| p.next(ch); + + const cmd = p.end(null).?.*; + try testing.expect(cmd == .prompt_start); + try testing.expect(cmd.prompt_start.kind == .continuation); +} + +test "OSC 133: prompt_start with secondary" { + const testing = std.testing; + + var p: Parser = .init(); + + const input = "133;A;k=s"; + for (input) |ch| p.next(ch); + + const cmd = p.end(null).?.*; + try testing.expect(cmd == .prompt_start); + try testing.expect(cmd.prompt_start.kind == .secondary); +} + +test "OSC 133: end_of_command no exit code" { + const testing = std.testing; + + var p: Parser = .init(); + + const input = "133;D"; + for (input) |ch| p.next(ch); + + const cmd = p.end(null).?.*; + try testing.expect(cmd == .end_of_command); +} + +test "OSC 133: end_of_command with exit code" { + const testing = std.testing; + + var p: Parser = .init(); + + const input = "133;D;25"; + for (input) |ch| p.next(ch); + + const cmd = p.end(null).?.*; + try testing.expect(cmd == .end_of_command); + try testing.expectEqual(@as(u8, 25), cmd.end_of_command.exit_code.?); +} + +test "OSC 133: prompt_end" { + const testing = std.testing; + + var p: Parser = .init(); + + const input = "133;B"; + for (input) |ch| p.next(ch); + + const cmd = p.end(null).?.*; + try testing.expect(cmd == .prompt_end); +} + +test "OSC 133: end_of_input" { + const testing = std.testing; + + var p: Parser = .init(); + + const input = "133;C"; + for (input) |ch| p.next(ch); + + const cmd = p.end(null).?.*; + try testing.expect(cmd == .end_of_input); +} + +test "OSC: OSC 777 show desktop notification with title" { + const testing = std.testing; + + var p: Parser = .init(); + + const input = "777;notify;Title;Body"; for (input) |ch| p.next(ch); const cmd = p.end('\x1b').?.*; try testing.expect(cmd == .show_desktop_notification); - try testing.expectEqualStrings("6", cmd.show_desktop_notification.body); + try testing.expectEqualStrings(cmd.show_desktop_notification.title, "Title"); + try testing.expectEqualStrings(cmd.show_desktop_notification.body, "Body"); } diff --git a/src/terminal/osc/color.zig b/src/terminal/osc/color.zig index 8a8e8b942..9fd81ed63 100644 --- a/src/terminal/osc/color.zig +++ b/src/terminal/osc/color.zig @@ -279,7 +279,7 @@ pub const ColoredTarget = struct { color: RGB, }; -test "osc4" { +test "OSC 4:" { const testing = std.testing; const alloc = testing.allocator; @@ -401,7 +401,7 @@ test "osc4" { } } -test "osc5" { +test "OSC 5:" { const testing = std.testing; const alloc = testing.allocator; @@ -433,7 +433,7 @@ test "osc5" { } } -test "osc4: multiple requests" { +test "OSC 4: multiple requests" { const testing = std.testing; const alloc = testing.allocator; @@ -489,7 +489,7 @@ test "osc4: multiple requests" { } } -test "osc104" { +test "OSC 104:" { const testing = std.testing; const alloc = testing.allocator; @@ -540,7 +540,7 @@ test "osc104" { } } -test "osc104 empty index" { +test "OSC 104: empty index" { const testing = std.testing; const alloc = testing.allocator; @@ -557,7 +557,7 @@ test "osc104 empty index" { ); } -test "osc104 invalid index" { +test "OSC 104: invalid index" { const testing = std.testing; const alloc = testing.allocator; @@ -570,7 +570,7 @@ test "osc104 invalid index" { ); } -test "osc104 reset all" { +test "OSC 104: reset all" { const testing = std.testing; const alloc = testing.allocator; @@ -583,7 +583,7 @@ test "osc104 reset all" { ); } -test "osc105 reset all" { +test "OSC 105: reset all" { const testing = std.testing; const alloc = testing.allocator; @@ -597,7 +597,7 @@ test "osc105 reset all" { } // OSC 10-19: Get/Set Dynamic Colors -test "dynamic" { +test "OSC 10: OSC 11: OSC 12: OSC: 13: OSC 14: OSC 15: OSC: 16: OSC 17: OSC 18: OSC 19: dynamic" { const testing = std.testing; const alloc = testing.allocator; @@ -625,7 +625,7 @@ test "dynamic" { } } -test "dynamic multiple" { +test "OSC 10: OSC 11: OSC 12: OSC: 13: OSC 14: OSC 15: OSC: 16: OSC 17: OSC 18: OSC 19: dynamic multiple" { const testing = std.testing; const alloc = testing.allocator; @@ -657,7 +657,7 @@ test "dynamic multiple" { } // OSC 110-119: Reset Dynamic Colors -test "reset dynamic" { +test "OSC 110: OSC 111: OSC 112: OSC: 113: OSC 114: OSC 115: OSC: 116: OSC 117: OSC 118: OSC 119: reset dynamic" { const testing = std.testing; const alloc = testing.allocator; -- cgit v1.2.3