aboutsummaryrefslogtreecommitdiff
path: root/testcases/t/313-include.t
blob: dc89eb5c7c21dcb7aa0a2317b00c41fb41171f57 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
#!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)
#
# • https://i3wm.org/downloads/modern_perl_a4.pdf
#   (unless you are already familiar with Perl)
#
# Verifies the include directive.

use File::Temp qw(tempfile tempdir);
use File::Basename qw(basename);
use i3test i3_autostart => 0;

# starts i3 with the given config, opens a window, returns its border style
sub launch_get_border {
    my ($config) = @_;

    my $pid = launch_with_config($config);

    my $i3 = i3(get_socket_path(0));
    my $tmp = fresh_workspace;

    my $window = open_window(name => 'special title');

    my @content = @{get_ws_content($tmp)};
    cmp_ok(@content, '==', 1, 'one node on this workspace now');
    my $border = $content[0]->{border};

    exit_gracefully($pid);

    return $border;
}

#####################################################################
# test thet windows get the default border
#####################################################################

my $config = <<EOT;
# i3 config file (v4)
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
EOT

is(launch_get_border($config), 'normal', 'normal border');

#####################################################################
# now use a variable and for_window
#####################################################################

my ($fh, $filename) = tempfile(UNLINK => 1);
my $varconfig = <<'EOT';
set $vartest special title
for_window [title="$vartest"] border none
EOT
print $fh $varconfig;
$fh->flush;

$config = <<EOT;
# i3 config file (v4)
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1

include $filename
EOT

is(launch_get_border($config), 'none', 'no border');

################################################################################
# nested includes
################################################################################

my ($indirectfh, $indirectfilename) = tempfile(UNLINK => 1);
print $indirectfh <<EOT;
include $filename
EOT
$indirectfh->flush;

$config = <<EOT;
# i3 config file (v4)
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1

include $indirectfilename
EOT

is(launch_get_border($config), 'none', 'no border');

################################################################################
# nested includes with relative paths
################################################################################

my $relative = basename($filename);
my ($indirectfh2, $indirectfilename2) = tempfile(UNLINK => 1);
print $indirectfh2 <<EOT;
include $relative
EOT
$indirectfh2->flush;

$config = <<EOT;
# i3 config file (v4)
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1

include $indirectfilename2
EOT

is(launch_get_border($config), 'none', 'no border');

################################################################################
# command substitution
################################################################################

$config = <<EOT;
# i3 config file (v4)
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1

include `echo $filename`
EOT

is(launch_get_border($config), 'none', 'no border');

################################################################################
# failing command substitution
################################################################################

$config = <<'EOT';
# i3 config file (v4)
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1

include i3-`false`.conf

set $vartest special title
for_window [title="$vartest"] border none
EOT

is(launch_get_border($config), 'none', 'no border');

################################################################################
# permission denied
################################################################################

my ($permissiondeniedfh, $permissiondenied) = tempfile(UNLINK => 1);
$permissiondeniedfh->flush;
my $mode = 0055;
chmod($mode, $permissiondenied);

$config = <<EOT;
# i3 config file (v4)
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1

include $permissiondenied
include $filename
EOT

is(launch_get_border($config), 'none', 'no border');

################################################################################
# dangling symlink
################################################################################

my ($danglingfh, $dangling) = tempfile(UNLINK => 1);
unlink($dangling);
symlink("/dangling", $dangling);

$config = <<EOT;
# i3 config file (v4)
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1

include $dangling
set \$vartest special title
for_window [title="\$vartest"] border none
EOT

is(launch_get_border($config), 'none', 'no border');

################################################################################
# variables defined in the main file and used in the included file
################################################################################

my ($varfh, $var) = tempfile(UNLINK => 1);
print $varfh <<'EOT';
for_window [title="$vartest"] border none

EOT
$varfh->flush;

$config = <<EOT;
# i3 config file (v4)
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1

set \$vartest special title
include $var
EOT

is(launch_get_border($config), 'none', 'no border');

SKIP: {
    skip "not implemented";

################################################################################
# variables defined in the included file and used in the main file
################################################################################

($varfh, $var) = tempfile(UNLINK => 1);
print $varfh <<'EOT';
set $vartest special title
EOT
$varfh->flush;

$config = <<EOT;
# i3 config file (v4)
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1

include $var
for_window [title="\$vartest"] border none
EOT

is(launch_get_border($config), 'none', 'no border');
}

################################################################################
# workspace names are loaded in the correct order (before reorder_bindings)
################################################################################

# The included config can be empty, the issue lies with calling parse_file
# multiple times.
my ($wsfh, $ws) = tempfile(UNLINK => 1);
$wsfh->flush;

$config = <<EOT;
# i3 config file (v4)
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1

bindsym 1 workspace 1: eggs
bindsym Mod4+Shift+1 workspace 11: tomatoes

include $var
EOT

# starts i3 with the given config, opens a window, returns its border style
sub launch_get_workspace_name {
    my ($config) = @_;

    my $pid = launch_with_config($config);

    my $i3 = i3(get_socket_path(0));
    my $name = $i3->get_workspaces->recv->[0]->{name};

    exit_gracefully($pid);

    return $name;
}

is(launch_get_workspace_name($config), '1: eggs', 'workspace name');

################################################################################
# loop prevention
################################################################################

my ($loopfh1, $loopname1) = tempfile(UNLINK => 1);
my ($loopfh2, $loopname2) = tempfile(UNLINK => 1);

print $loopfh1 <<EOT;
include $loopname2
EOT
$loopfh1->flush;

print $loopfh2 <<EOT;
include $loopname1
EOT
$loopfh2->flush;

$config = <<EOT;
# i3 config file (v4)
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1

# loop
include $loopname1

set \$vartest special title
for_window [title="\$vartest"] border none
EOT

is(launch_get_border($config), 'none', 'no border');

################################################################################
# Verify the GET_VERSION IPC reply contains all included files
################################################################################

$config = <<EOT;
# i3 config file (v4)
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1

include $indirectfilename2
EOT

my $pid = launch_with_config($config);

my $i3 = i3(get_socket_path(0));
my $version = $i3->get_version()->recv;
my $included = $version->{included_config_file_names};

is_deeply($included, [ $indirectfilename2, $filename ], 'included config file names correct');

exit_gracefully($pid);

################################################################################
# Verify the GET_CONFIG IPC reply returns the top-level config
################################################################################

my $tmpdir = tempdir(CLEANUP => 1);
my $socketpath = $tmpdir . "/config.sock";
ok(! -e $socketpath, "$socketpath does not exist yet");

my ($indirectfh3, $indirectfilename3) = tempfile(UNLINK => 1);
my $indirectconfig = <<EOT;
for_window [title="\$vartest"] border none
include $relative
EOT
print $indirectfh3 $indirectconfig;
$indirectfh3->flush;

$config = <<EOT;
# i3 config file (v4)
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1

set \$vartest special title

include $indirectfilename3

ipc-socket $socketpath
EOT

my $pid = launch_with_config($config, dont_add_socket_path => 1, dont_create_temp_dir => 1);

my $i3 = i3(get_socket_path(0));
my $config_reply = $i3->get_config()->recv;

is($config_reply->{config}, $config, 'GET_CONFIG returns the top-level config file');

my $included = $config_reply->{included_configs};
is(scalar @{$included}, 3, 'included_configs contains all 3 files');
is($included->[0]->{raw_contents}, $config, 'included_configs->[0]->{raw_contents} contains top-level config');
is($included->[1]->{raw_contents}, $indirectconfig, 'included_configs->[1]->{raw_contents} contains indirect config');
is($included->[2]->{raw_contents}, $varconfig, 'included_configs->[2]->{raw_contents} contains variable config');

my $indirect_replaced_config = <<EOT;
for_window [title="special title"] border none
include $relative
EOT
is($included->[1]->{variable_replaced_contents}, $indirect_replaced_config, 'included_configs->[1]->{variable_replaced_contents} contains config with variables replaced');

exit_gracefully($pid);


done_testing;