37d0105c83
This change only affects clients that are subscribed to events, which should be the main cause of our problems. In the common case (no buffered data) the behaviour doesn't change at all: the message is sent directly, no ev_io / ev_timeout callback is enabled. Once a write to a client's socket is not completed fully (returns with EAGAIN error), we put the message in the tail of a queue and init an ev_io callback and a corresponding timer. If the timer is triggered first, the socket is closed and the client connection is removed. If the socket becomes writeable before the timeout we either reset the timer if we couldn't push all the buffered data or completely remove it if everything was pushed. We could also replace ipc_send_message() for all client connections in i3, not just those subscribed to events. Furthermore, we could limit the amount of messages stored and increase the timeout (or use multiple timeouts): eg it's ok if a client is not reading for 10 seconds and we are only holding 5KB of messages for them but it is not ok if they are inactive for 5 seconds and we have 30MB of messages held. Closes #2999 Closes #2539
744 lines
20 KiB
Raku
744 lines
20 KiB
Raku
#!perl
|
||
# vim:ts=4:sw=4:expandtab
|
||
#
|
||
# Please read the following documents before working on tests:
|
||
# • https://build.i3wm.org/docs/testsuite.html
|
||
# (or docs/testsuite)
|
||
#
|
||
# • https://build.i3wm.org/docs/lib-i3test.html
|
||
# (alternatively: perldoc ./testcases/lib/i3test.pm)
|
||
#
|
||
# • https://build.i3wm.org/docs/ipc.html
|
||
# (or docs/ipc)
|
||
#
|
||
# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
|
||
# (unless you are already familiar with Perl)
|
||
#
|
||
# Tests the standalone parser binary to see if it calls the right code when
|
||
# confronted with various commands, if it prints proper error messages for
|
||
# wrong commands and if it terminates in every case.
|
||
#
|
||
use i3test i3_autostart => 0;
|
||
use IPC::Run qw(run);
|
||
|
||
sub parser_calls {
|
||
my ($command) = @_;
|
||
|
||
my $stdout;
|
||
run [ 'test.config_parser', $command ],
|
||
'>/dev/null',
|
||
'2>', \$stdout;
|
||
# TODO: use a timeout, so that we can error out if it doesn’t terminate
|
||
|
||
# Filter out all debugging output.
|
||
my @lines = split("\n", $stdout);
|
||
@lines = grep { not /^# / } @lines;
|
||
|
||
# The criteria management calls are irrelevant and not what we want to test
|
||
# in the first place.
|
||
@lines = grep { !(/cfg_criteria_init/ || /cfg_criteria_pop_state/) } @lines;
|
||
return join("\n", @lines) . "\n";
|
||
}
|
||
|
||
my $config = <<'EOT';
|
||
mode "meh" {
|
||
bindsym Mod1 + Shift + x resize grow
|
||
bindcode Mod1+44 resize shrink
|
||
bindsym --release Mod1+x exec foo
|
||
bindsym --whole-window button3 nop
|
||
bindsym --release --whole-window button3 nop
|
||
bindsym --border button3 nop
|
||
bindsym --release --border button3 nop
|
||
bindsym --exclude-titlebar button3 nop
|
||
bindsym --whole-window --border --exclude-titlebar button3 nop
|
||
}
|
||
EOT
|
||
|
||
my $expected = <<'EOT';
|
||
cfg_enter_mode((null), meh)
|
||
cfg_mode_binding(bindsym, Mod1,Shift, x, (null), (null), (null), (null), resize grow)
|
||
cfg_mode_binding(bindcode, Mod1, 44, (null), (null), (null), (null), resize shrink)
|
||
cfg_mode_binding(bindsym, Mod1, x, --release, (null), (null), (null), exec foo)
|
||
cfg_mode_binding(bindsym, (null), button3, (null), (null), --whole-window, (null), nop)
|
||
cfg_mode_binding(bindsym, (null), button3, --release, (null), --whole-window, (null), nop)
|
||
cfg_mode_binding(bindsym, (null), button3, (null), --border, (null), (null), nop)
|
||
cfg_mode_binding(bindsym, (null), button3, --release, --border, (null), (null), nop)
|
||
cfg_mode_binding(bindsym, (null), button3, (null), (null), (null), --exclude-titlebar, nop)
|
||
cfg_mode_binding(bindsym, (null), button3, (null), --border, --whole-window, --exclude-titlebar, nop)
|
||
EOT
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'mode bindings ok');
|
||
|
||
################################################################################
|
||
# exec and exec_always
|
||
################################################################################
|
||
|
||
$config = <<'EOT';
|
||
exec geeqie
|
||
exec --no-startup-id /tmp/foo.sh
|
||
exec_always firefox
|
||
exec_always --no-startup-id /tmp/bar.sh
|
||
EOT
|
||
|
||
$expected = <<'EOT';
|
||
cfg_exec(exec, (null), geeqie)
|
||
cfg_exec(exec, --no-startup-id, /tmp/foo.sh)
|
||
cfg_exec(exec_always, (null), firefox)
|
||
cfg_exec(exec_always, --no-startup-id, /tmp/bar.sh)
|
||
EOT
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'exec okay');
|
||
|
||
################################################################################
|
||
# for_window
|
||
################################################################################
|
||
|
||
$config = <<'EOT';
|
||
for_window [class="^Chrome"] floating enable
|
||
EOT
|
||
|
||
$expected = <<'EOT';
|
||
cfg_criteria_add(class, ^Chrome)
|
||
cfg_for_window(floating enable)
|
||
EOT
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'for_window okay');
|
||
|
||
################################################################################
|
||
# assign
|
||
################################################################################
|
||
|
||
$config = <<'EOT';
|
||
assign [class="^Chrome"] 4
|
||
assign [class="^Chrome"] workspace number 3
|
||
assign [class="^Chrome"] named workspace
|
||
assign [class="^Chrome"] "quoted named workspace"
|
||
assign [class="^Chrome"] → "quoted named workspace"
|
||
EOT
|
||
|
||
$expected = <<'EOT';
|
||
cfg_criteria_add(class, ^Chrome)
|
||
cfg_assign(4, 0)
|
||
cfg_criteria_add(class, ^Chrome)
|
||
cfg_assign(3, 1)
|
||
cfg_criteria_add(class, ^Chrome)
|
||
cfg_assign(named workspace, 0)
|
||
cfg_criteria_add(class, ^Chrome)
|
||
cfg_assign(quoted named workspace, 0)
|
||
cfg_criteria_add(class, ^Chrome)
|
||
cfg_assign(quoted named workspace, 0)
|
||
EOT
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'for_window okay');
|
||
|
||
################################################################################
|
||
# floating_minimum_size / floating_maximum_size
|
||
################################################################################
|
||
|
||
$config = <<'EOT';
|
||
floating_minimum_size 80x55
|
||
floating_minimum_size 80 x 55
|
||
floating_maximum_size 73 x 10
|
||
EOT
|
||
|
||
$expected = <<'EOT';
|
||
cfg_floating_minimum_size(80, 55)
|
||
cfg_floating_minimum_size(80, 55)
|
||
cfg_floating_maximum_size(73, 10)
|
||
EOT
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'floating_minimum_size ok');
|
||
|
||
################################################################################
|
||
# popup_during_fullscreen
|
||
################################################################################
|
||
|
||
$config = <<'EOT';
|
||
popup_during_fullscreen ignore
|
||
popup_during_fullscreen leave_fullscreen
|
||
popup_during_fullscreen SMArt
|
||
EOT
|
||
|
||
$expected = <<'EOT';
|
||
cfg_popup_during_fullscreen(ignore)
|
||
cfg_popup_during_fullscreen(leave_fullscreen)
|
||
cfg_popup_during_fullscreen(smart)
|
||
EOT
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'popup_during_fullscreen ok');
|
||
|
||
|
||
################################################################################
|
||
# floating_modifier
|
||
################################################################################
|
||
|
||
$config = <<'EOT';
|
||
floating_modifier Mod1
|
||
floating_modifier mOd1
|
||
EOT
|
||
|
||
$expected = <<'EOT';
|
||
cfg_floating_modifier(Mod1)
|
||
cfg_floating_modifier(Mod1)
|
||
EOT
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'floating_modifier ok');
|
||
|
||
################################################################################
|
||
# default_orientation
|
||
################################################################################
|
||
|
||
$config = <<'EOT';
|
||
default_orientation horizontal
|
||
default_orientation vertical
|
||
default_orientation auto
|
||
EOT
|
||
|
||
$expected = <<'EOT';
|
||
cfg_default_orientation(horizontal)
|
||
cfg_default_orientation(vertical)
|
||
cfg_default_orientation(auto)
|
||
EOT
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'default_orientation ok');
|
||
|
||
################################################################################
|
||
# workspace_layout
|
||
################################################################################
|
||
|
||
$config = <<'EOT';
|
||
workspace_layout default
|
||
workspace_layout stacked
|
||
workspace_layout stacking
|
||
workspace_layout tabbed
|
||
EOT
|
||
|
||
$expected = <<'EOT';
|
||
cfg_workspace_layout(default)
|
||
cfg_workspace_layout(stacked)
|
||
cfg_workspace_layout(stacking)
|
||
cfg_workspace_layout(tabbed)
|
||
EOT
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'workspace_layout ok');
|
||
|
||
################################################################################
|
||
# workspace assignments, with trailing whitespace (ticket #921)
|
||
################################################################################
|
||
|
||
$config = <<'EOT';
|
||
workspace "3" output DP-1
|
||
workspace "3" output VGA-1
|
||
EOT
|
||
|
||
$expected = <<'EOT';
|
||
cfg_workspace(3, DP-1)
|
||
cfg_workspace(3, VGA-1)
|
||
EOT
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'workspace assignment ok');
|
||
|
||
################################################################################
|
||
# new_window
|
||
################################################################################
|
||
|
||
$config = <<'EOT';
|
||
new_window 1pixel
|
||
new_window normal
|
||
new_window none
|
||
default_border 1pixel
|
||
default_border normal
|
||
default_border none
|
||
new_float 1pixel
|
||
new_float normal
|
||
new_float none
|
||
default_floating_border 1pixel
|
||
default_floating_border normal
|
||
default_floating_border none
|
||
EOT
|
||
|
||
$expected = <<'EOT';
|
||
cfg_default_border(new_window, 1pixel, -1)
|
||
cfg_default_border(new_window, normal, 2)
|
||
cfg_default_border(new_window, none, -1)
|
||
cfg_default_border(default_border, 1pixel, -1)
|
||
cfg_default_border(default_border, normal, 2)
|
||
cfg_default_border(default_border, none, -1)
|
||
cfg_default_border(new_float, 1pixel, -1)
|
||
cfg_default_border(new_float, normal, 2)
|
||
cfg_default_border(new_float, none, -1)
|
||
cfg_default_border(default_floating_border, 1pixel, -1)
|
||
cfg_default_border(default_floating_border, normal, 2)
|
||
cfg_default_border(default_floating_border, none, -1)
|
||
EOT
|
||
|
||
# TODO: are there no tests for "border pixel 1" etc?
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'new_window ok');
|
||
|
||
################################################################################
|
||
# hide_edge_borders
|
||
################################################################################
|
||
|
||
$config = <<'EOT';
|
||
hide_edge_borders none
|
||
hide_edge_borders vertical
|
||
hide_edge_borders horizontal
|
||
hide_edge_borders both
|
||
hide_edge_borders smart
|
||
EOT
|
||
|
||
$expected = <<'EOT';
|
||
cfg_hide_edge_borders(none)
|
||
cfg_hide_edge_borders(vertical)
|
||
cfg_hide_edge_borders(horizontal)
|
||
cfg_hide_edge_borders(both)
|
||
cfg_hide_edge_borders(smart)
|
||
EOT
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'hide_edge_borders ok');
|
||
|
||
################################################################################
|
||
# focus_follows_mouse
|
||
################################################################################
|
||
|
||
$config = <<'EOT';
|
||
focus_follows_mouse yes
|
||
focus_follows_mouse no
|
||
EOT
|
||
|
||
$expected = <<'EOT';
|
||
cfg_focus_follows_mouse(yes)
|
||
cfg_focus_follows_mouse(no)
|
||
EOT
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'focus_follows_mouse ok');
|
||
|
||
################################################################################
|
||
# mouse_warping
|
||
################################################################################
|
||
|
||
$config = <<'EOT';
|
||
mouse_warping output
|
||
mouse_warping none
|
||
EOT
|
||
|
||
$expected = <<'EOT';
|
||
cfg_mouse_warping(output)
|
||
cfg_mouse_warping(none)
|
||
EOT
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'mouse_warping ok');
|
||
|
||
################################################################################
|
||
# force_display_urgency_hint
|
||
################################################################################
|
||
|
||
is(parser_calls('force_display_urgency_hint 300'),
|
||
"cfg_force_display_urgency_hint(300)\n",
|
||
'force_display_urgency_hint ok');
|
||
|
||
is(parser_calls('force_display_urgency_hint 500 ms'),
|
||
"cfg_force_display_urgency_hint(500)\n",
|
||
'force_display_urgency_hint ok');
|
||
|
||
is(parser_calls('force_display_urgency_hint 700ms'),
|
||
"cfg_force_display_urgency_hint(700)\n",
|
||
'force_display_urgency_hint ok');
|
||
|
||
$config = <<'EOT';
|
||
force_display_urgency_hint 300
|
||
force_display_urgency_hint 500 ms
|
||
force_display_urgency_hint 700ms
|
||
force_display_urgency_hint 700
|
||
EOT
|
||
|
||
$expected = <<'EOT';
|
||
cfg_force_display_urgency_hint(300)
|
||
cfg_force_display_urgency_hint(500)
|
||
cfg_force_display_urgency_hint(700)
|
||
cfg_force_display_urgency_hint(700)
|
||
EOT
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'force_display_urgency_hint ok');
|
||
|
||
################################################################################
|
||
# workspace
|
||
################################################################################
|
||
|
||
$config = <<'EOT';
|
||
workspace 3 output VGA-1
|
||
workspace "4: output" output VGA-2
|
||
workspace bleh output LVDS1/I_1
|
||
EOT
|
||
|
||
$expected = <<'EOT';
|
||
cfg_workspace(3, VGA-1)
|
||
cfg_workspace(4: output, VGA-2)
|
||
cfg_workspace(bleh, LVDS1/I_1)
|
||
EOT
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'workspace ok');
|
||
|
||
################################################################################
|
||
# ipc-socket
|
||
################################################################################
|
||
|
||
$config = <<'EOT';
|
||
ipc-socket /tmp/i3.sock
|
||
ipc_socket ~/.i3/i3.sock
|
||
EOT
|
||
|
||
$expected = <<'EOT';
|
||
cfg_ipc_socket(/tmp/i3.sock)
|
||
cfg_ipc_socket(~/.i3/i3.sock)
|
||
EOT
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'ipc-socket ok');
|
||
|
||
################################################################################
|
||
# colors
|
||
################################################################################
|
||
|
||
$config = <<'EOT';
|
||
client.focused #4c7899 #285577 #ffffff #2e9ef4 #b34d4c
|
||
client.focused_inactive #333333 #5f676a #ffffff #484e50
|
||
client.unfocused #333333 #222222 #888888 #292d2e
|
||
client.urgent #2f343a #900000 #ffffff #900000 #c00000
|
||
client.placeholder #000000 #0c0c0c #ffffff #000000
|
||
EOT
|
||
|
||
$expected = <<'EOT';
|
||
cfg_color(client.focused, #4c7899, #285577, #ffffff, #2e9ef4, #b34d4c)
|
||
cfg_color(client.focused_inactive, #333333, #5f676a, #ffffff, #484e50, NULL)
|
||
cfg_color(client.unfocused, #333333, #222222, #888888, #292d2e, NULL)
|
||
cfg_color(client.urgent, #2f343a, #900000, #ffffff, #900000, #c00000)
|
||
cfg_color(client.placeholder, #000000, #0c0c0c, #ffffff, #000000, NULL)
|
||
EOT
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'colors ok');
|
||
|
||
################################################################################
|
||
# Verify that errors don’t harm subsequent valid statements
|
||
################################################################################
|
||
|
||
$config = <<'EOT';
|
||
hide_edge_border both
|
||
client.focused #4c7899 #285577 #ffffff #2e9ef4
|
||
EOT
|
||
|
||
my $expected_all_tokens = "ERROR: CONFIG: Expected one of these tokens: <end>, '#', '" . join("', '", 'set ', 'set ', qw(
|
||
set_from_resource
|
||
bindsym
|
||
bindcode
|
||
bind
|
||
bar
|
||
font
|
||
mode
|
||
floating_minimum_size
|
||
floating_maximum_size
|
||
floating_modifier
|
||
default_orientation
|
||
workspace_layout
|
||
default_border
|
||
new_window
|
||
default_floating_border
|
||
new_float
|
||
hide_edge_borders
|
||
for_window
|
||
assign
|
||
no_focus
|
||
focus_follows_mouse
|
||
mouse_warping
|
||
focus_wrapping
|
||
force_focus_wrapping
|
||
force_xinerama
|
||
force-xinerama
|
||
disable_randr15
|
||
disable-randr15
|
||
workspace_auto_back_and_forth
|
||
fake_outputs
|
||
fake-outputs
|
||
force_display_urgency_hint
|
||
focus_on_window_activation
|
||
show_marks
|
||
workspace
|
||
ipc_socket
|
||
ipc-socket
|
||
ipc_kill_timeout
|
||
restart_state
|
||
popup_during_fullscreen
|
||
exec_always
|
||
exec
|
||
client.background
|
||
client.focused_inactive
|
||
client.focused
|
||
client.unfocused
|
||
client.urgent
|
||
client.placeholder
|
||
)) . "'\n";
|
||
|
||
my $expected_end = <<'EOT';
|
||
ERROR: CONFIG: (in file <stdin>)
|
||
ERROR: CONFIG: Line 1: hide_edge_border both
|
||
ERROR: CONFIG: ^^^^^^^^^^^^^^^^^^^^^
|
||
ERROR: CONFIG: Line 2: client.focused #4c7899 #285577 #ffffff #2e9ef4
|
||
cfg_color(client.focused, #4c7899, #285577, #ffffff, #2e9ef4, NULL)
|
||
EOT
|
||
|
||
$expected = $expected_all_tokens . $expected_end;
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'errors dont harm subsequent statements');
|
||
|
||
$config = <<'EOT';
|
||
hide_edge_borders FOOBAR
|
||
client.focused #4c7899 #285577 #ffffff #2e9ef4
|
||
EOT
|
||
|
||
$expected = <<'EOT';
|
||
ERROR: CONFIG: Expected one of these tokens: 'none', 'vertical', 'horizontal', 'both', 'smart', '1', 'yes', 'true', 'on', 'enable', 'active'
|
||
ERROR: CONFIG: (in file <stdin>)
|
||
ERROR: CONFIG: Line 1: hide_edge_borders FOOBAR
|
||
ERROR: CONFIG: ^^^^^^
|
||
ERROR: CONFIG: Line 2: client.focused #4c7899 #285577 #ffffff #2e9ef4
|
||
cfg_color(client.focused, #4c7899, #285577, #ffffff, #2e9ef4, NULL)
|
||
EOT
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'errors dont harm subsequent statements');
|
||
|
||
################################################################################
|
||
# Regression: semicolons end comments, but shouldn’t
|
||
################################################################################
|
||
|
||
$config = <<'EOT';
|
||
# "foo" client.focused #4c7899 #285577 #ffffff #2e9ef4
|
||
EOT
|
||
|
||
$expected = <<'EOT';
|
||
|
||
EOT
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'semicolon does not end a comment line');
|
||
|
||
################################################################################
|
||
# Error message with 2+2 lines of context
|
||
################################################################################
|
||
|
||
$config = <<'EOT';
|
||
# i3 config file (v4)
|
||
|
||
font foobar
|
||
|
||
unknown qux
|
||
|
||
# yay
|
||
# this should not show up
|
||
EOT
|
||
|
||
my $expected_head = <<'EOT';
|
||
cfg_font(foobar)
|
||
EOT
|
||
|
||
my $expected_tail = <<'EOT';
|
||
ERROR: CONFIG: (in file <stdin>)
|
||
ERROR: CONFIG: Line 3: font foobar
|
||
ERROR: CONFIG: Line 4:
|
||
ERROR: CONFIG: Line 5: unknown qux
|
||
ERROR: CONFIG: ^^^^^^^^^^^
|
||
ERROR: CONFIG: Line 6:
|
||
ERROR: CONFIG: Line 7: # yay
|
||
EOT
|
||
|
||
$expected = $expected_head . $expected_all_tokens . $expected_tail;
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'error message (2+2 context) ok');
|
||
|
||
################################################################################
|
||
# Error message with 0+0 lines of context
|
||
################################################################################
|
||
|
||
$config = <<'EOT';
|
||
unknown qux
|
||
EOT
|
||
|
||
$expected_tail = <<'EOT';
|
||
ERROR: CONFIG: (in file <stdin>)
|
||
ERROR: CONFIG: Line 1: unknown qux
|
||
ERROR: CONFIG: ^^^^^^^^^^^
|
||
EOT
|
||
|
||
$expected = $expected_all_tokens . $expected_tail;
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'error message (0+0 context) ok');
|
||
|
||
################################################################################
|
||
# Error message with 1+0 lines of context
|
||
################################################################################
|
||
|
||
$config = <<'EOT';
|
||
# context before
|
||
unknown qux
|
||
EOT
|
||
|
||
$expected_tail = <<'EOT';
|
||
ERROR: CONFIG: (in file <stdin>)
|
||
ERROR: CONFIG: Line 1: # context before
|
||
ERROR: CONFIG: Line 2: unknown qux
|
||
ERROR: CONFIG: ^^^^^^^^^^^
|
||
EOT
|
||
|
||
$expected = $expected_all_tokens . $expected_tail;
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'error message (1+0 context) ok');
|
||
|
||
################################################################################
|
||
# Error message with 0+1 lines of context
|
||
################################################################################
|
||
|
||
$config = <<'EOT';
|
||
unknown qux
|
||
# context after
|
||
EOT
|
||
|
||
$expected_tail = <<'EOT';
|
||
ERROR: CONFIG: (in file <stdin>)
|
||
ERROR: CONFIG: Line 1: unknown qux
|
||
ERROR: CONFIG: ^^^^^^^^^^^
|
||
ERROR: CONFIG: Line 2: # context after
|
||
EOT
|
||
|
||
$expected = $expected_all_tokens . $expected_tail;
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'error message (0+1 context) ok');
|
||
|
||
################################################################################
|
||
# Error message with 0+2 lines of context
|
||
################################################################################
|
||
|
||
$config = <<'EOT';
|
||
unknown qux
|
||
# context after
|
||
# context 2 after
|
||
EOT
|
||
|
||
$expected_tail = <<'EOT';
|
||
ERROR: CONFIG: (in file <stdin>)
|
||
ERROR: CONFIG: Line 1: unknown qux
|
||
ERROR: CONFIG: ^^^^^^^^^^^
|
||
ERROR: CONFIG: Line 2: # context after
|
||
ERROR: CONFIG: Line 3: # context 2 after
|
||
EOT
|
||
|
||
$expected = $expected_all_tokens . $expected_tail;
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'error message (0+2 context) ok');
|
||
|
||
################################################################################
|
||
# Error message within mode blocks
|
||
################################################################################
|
||
|
||
$config = <<'EOT';
|
||
mode "yo" {
|
||
bindsym x resize shrink left
|
||
unknown qux
|
||
}
|
||
EOT
|
||
|
||
$expected = <<'EOT';
|
||
cfg_enter_mode((null), yo)
|
||
cfg_mode_binding(bindsym, (null), x, (null), (null), (null), (null), resize shrink left)
|
||
ERROR: CONFIG: Expected one of these tokens: <end>, '#', 'set', 'bindsym', 'bindcode', 'bind', '}'
|
||
ERROR: CONFIG: (in file <stdin>)
|
||
ERROR: CONFIG: Line 1: mode "yo" {
|
||
ERROR: CONFIG: Line 2: bindsym x resize shrink left
|
||
ERROR: CONFIG: Line 3: unknown qux
|
||
ERROR: CONFIG: ^^^^^^^^^^^
|
||
ERROR: CONFIG: Line 4: }
|
||
EOT
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'error message (mode block) ok');
|
||
|
||
################################################################################
|
||
# Error message within bar blocks
|
||
################################################################################
|
||
|
||
$config = <<'EOT';
|
||
bar {
|
||
output LVDS-1
|
||
unknown qux
|
||
}
|
||
EOT
|
||
|
||
$expected = <<'EOT';
|
||
cfg_bar_start()
|
||
cfg_bar_output(LVDS-1)
|
||
ERROR: CONFIG: Expected one of these tokens: <end>, '#', 'set', 'i3bar_command', 'status_command', 'socket_path', 'mode', 'hidden_state', 'id', 'modifier', 'wheel_up_cmd', 'wheel_down_cmd', 'bindsym', 'position', 'output', 'tray_output', 'tray_padding', 'font', 'separator_symbol', 'binding_mode_indicator', 'workspace_buttons', 'strip_workspace_numbers', 'strip_workspace_name', 'verbose', 'colors', '}'
|
||
ERROR: CONFIG: (in file <stdin>)
|
||
ERROR: CONFIG: Line 1: bar {
|
||
ERROR: CONFIG: Line 2: output LVDS-1
|
||
ERROR: CONFIG: Line 3: unknown qux
|
||
ERROR: CONFIG: ^^^^^^^^^^^
|
||
ERROR: CONFIG: Line 4: }
|
||
cfg_bar_finish()
|
||
EOT
|
||
|
||
is(parser_calls($config),
|
||
$expected,
|
||
'error message (bar block) ok');
|
||
|
||
done_testing;
|