2 # vim:ts=4:sw=4:expandtab
4 # Please read the following documents before working on tests:
5 # • http://build.i3wm.org/docs/testsuite.html
8 # • http://build.i3wm.org/docs/lib-i3test.html
9 # (alternatively: perldoc ./testcases/lib/i3test.pm)
11 # • http://build.i3wm.org/docs/ipc.html
14 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
15 # (unless you are already familiar with Perl)
17 # Tests the standalone parser binary to see if it calls the right code when
18 # confronted with various commands, if it prints proper error messages for
19 # wrong commands and if it terminates in every case.
21 use i3test i3_autostart => 0;
26 # TODO: use a timeout, so that we can error out if it doesn’t terminate
27 # TODO: better way of passing arguments
28 my $stdout = qx(../test.commands_parser '$command' 2>&1 >&-);
30 # Filter out all debugging output.
31 my @lines = split("\n", $stdout);
32 @lines = grep { not /^# / } @lines;
34 # The criteria management calls are irrelevant and not what we want to test
36 @lines = grep { !(/cmd_criteria_init()/ || /cmd_criteria_match_windows/) } @lines;
37 return join("\n", @lines);
40 ################################################################################
41 # 1: First that the parser properly recognizes commands which are ok.
42 ################################################################################
44 # The first call has only a single command, the following ones are consolidated
46 is(parser_calls('move workspace 3'),
47 'cmd_move_con_to_workspace_name(3)',
48 'single number (move workspace 3) ok');
51 'move to workspace 3; ' .
52 'move window to workspace 3; ' .
53 'move container to workspace 3; ' .
54 'move workspace foobar; ' .
55 'move workspace torrent; ' .
56 'move workspace to output LVDS1; ' .
57 'move workspace 3: foobar; ' .
58 'move workspace "3: foobar"; ' .
59 'move workspace "3: foobar, baz"; '),
60 "cmd_move_con_to_workspace_name(3)\n" .
61 "cmd_move_con_to_workspace_name(3)\n" .
62 "cmd_move_con_to_workspace_name(3)\n" .
63 "cmd_move_con_to_workspace_name(foobar)\n" .
64 "cmd_move_con_to_workspace_name(torrent)\n" .
65 "cmd_move_workspace_to_output(LVDS1)\n" .
66 "cmd_move_con_to_workspace_name(3: foobar)\n" .
67 "cmd_move_con_to_workspace_name(3: foobar)\n" .
68 "cmd_move_con_to_workspace_name(3: foobar, baz)",
71 is(parser_calls('move workspace 3: foobar, nop foo'),
72 "cmd_move_con_to_workspace_name(3: foobar)\n" .
74 'multiple ops (move workspace 3: foobar, nop foo) ok');
77 'exec i3-sensible-terminal; ' .
78 'exec --no-startup-id i3-sensible-terminal'),
79 "cmd_exec((null), i3-sensible-terminal)\n" .
80 "cmd_exec(--no-startup-id, i3-sensible-terminal)",
84 'resize shrink left; ' .
85 'resize shrink left 25 px; ' .
86 'resize shrink left 25 px or 33 ppt; ' .
87 'resize shrink left 25'),
88 "cmd_resize(shrink, left, 10, 10)\n" .
89 "cmd_resize(shrink, left, 25, 10)\n" .
90 "cmd_resize(shrink, left, 25, 33)\n" .
91 "cmd_resize(shrink, left, 25, 10)",
94 is(parser_calls('resize shrink left 25 px or 33 ppt,'),
95 'cmd_resize(shrink, left, 25, 33)',
96 'trailing comma resize ok');
98 is(parser_calls('resize shrink left 25 px or 33 ppt;'),
99 'cmd_resize(shrink, left, 25, 33)',
100 'trailing semicolon resize ok');
102 is(parser_calls('[con_mark=yay] focus'),
103 "cmd_criteria_add(con_mark, yay)\n" .
105 'criteria focus ok');
107 is(parser_calls("[con_mark=yay con_mark=bar] focus"),
108 "cmd_criteria_add(con_mark, yay)\n" .
109 "cmd_criteria_add(con_mark, bar)\n" .
111 'criteria focus ok');
113 is(parser_calls("[con_mark=yay\tcon_mark=bar] focus"),
114 "cmd_criteria_add(con_mark, yay)\n" .
115 "cmd_criteria_add(con_mark, bar)\n" .
117 'criteria focus ok');
119 is(parser_calls("[con_mark=yay\tcon_mark=bar]\tfocus"),
120 "cmd_criteria_add(con_mark, yay)\n" .
121 "cmd_criteria_add(con_mark, bar)\n" .
123 'criteria focus ok');
125 is(parser_calls('[con_mark="yay"] focus'),
126 "cmd_criteria_add(con_mark, yay)\n" .
128 'quoted criteria focus ok');
130 # Make sure trailing whitespace is stripped off: While this is not an issue for
131 # commands being parsed due to the configuration, people might send IPC
132 # commands with leading or trailing newlines.
133 is(parser_calls("workspace test\n"),
134 'cmd_workspace_name(test)',
135 'trailing whitespace stripped off ok');
137 is(parser_calls("\nworkspace test"),
138 'cmd_workspace_name(test)',
139 'trailing whitespace stripped off ok');
141 ################################################################################
142 # 2: Verify that the parser spits out the right error message on commands which
144 ################################################################################
146 is(parser_calls('unknown_literal'),
147 "ERROR: Expected one of these tokens: <end>, '[', 'move', 'exec', 'exit', 'restart', 'reload', 'shmlog', 'debuglog', 'border', 'layout', 'append_layout', 'workspace', 'focus', 'kill', 'open', 'fullscreen', 'split', 'floating', 'mark', 'unmark', 'resize', 'rename', 'nop', 'scratchpad', 'mode', 'bar'\n" .
148 "ERROR: Your command: unknown_literal\n" .
149 "ERROR: ^^^^^^^^^^^^^^^",
150 'error for unknown literal ok');
152 is(parser_calls('move something to somewhere'),
153 "ERROR: Expected one of these tokens: 'window', 'container', 'to', 'workspace', 'output', 'mark', 'scratchpad', 'left', 'right', 'up', 'down', 'position', 'absolute'\n" .
154 "ERROR: Your command: move something to somewhere\n" .
155 "ERROR: ^^^^^^^^^^^^^^^^^^^^^^",
156 'error for unknown literal ok');
158 ################################################################################
159 # 3: Verify that escaping works correctly
160 ################################################################################
162 is(parser_calls('workspace "foo"'),
163 'cmd_workspace_name(foo)',
164 'Command with simple double quotes ok');
166 is(parser_calls('workspace "foo'),
167 'cmd_workspace_name(foo)',
168 'Command without ending double quotes ok');
170 is(parser_calls('workspace "foo \"bar"'),
171 'cmd_workspace_name(foo "bar)',
172 'Command with escaped double quotes ok');
174 is(parser_calls('workspace "foo \\'),
175 'cmd_workspace_name(foo \\)',
176 'Command with single backslash in the end ok');
178 is(parser_calls('workspace "foo\\\\bar"'),
179 'cmd_workspace_name(foo\\bar)',
180 'Command with escaped backslashes ok');
182 is(parser_calls('workspace "foo\\\\\\"bar"'),
183 'cmd_workspace_name(foo\\"bar)',
184 'Command with escaped double quotes after escaped backslashes ok');
186 ################################################################################
187 # 4: Verify that resize commands with a "px or ppt"-construction are parsed
189 ################################################################################
191 is(parser_calls("resize shrink width 10 px or"),
192 "ERROR: Expected one of these tokens: <word>\n" .
193 "ERROR: Your command: resize shrink width 10 px or\n" .
195 "error for resize command with incomplete 'or'-construction ok");
197 is(parser_calls("resize grow left 10 px or 20 ppt"),
198 "cmd_resize(grow, left, 10, 20)",
199 "resize command with 'or'-construction ok");