source: t/completion.t @ 09065ed

release-1.10release-1.6release-1.7release-1.8release-1.9
Last change on this file since 09065ed was 3001c11, checked in by David Benjamin <davidben@mit.edu>, 15 years ago
Add a test case for deleted syntax
  • Property mode set to 100644
File size: 10.1 KB
RevLine 
[8eac1a5]1#!/usr/bin/env perl
2use strict;
3use warnings;
4
5use Test::More qw(no_plan);
6
7use File::Basename;
8BEGIN {require (dirname($0) . "/mock.pl");};
9
[1167bf1]10use BarnOwl::Complete::Filter qw(complete_filter_expr);
11
[8eac1a5]12=head1 DESCRIPTION
13
14Basic tests for tab-completion functionality.
15
16=cut
17
18sub test_tokenize {
19    local $Test::Builder::Level = $Test::Builder::Level + 1;
20
21    my $before_point = shift;
22    my $after_point = shift;
23   
[e97c5d05]24    my $ctx = BarnOwl::Completion::Context->new($before_point,
25                                                $after_point);
26    is($ctx->line, $before_point . $after_point);
27    is($ctx->point, length $before_point);
28
29    test_ctx($ctx, @_);
30}
31
32sub test_ctx {
33    local $Test::Builder::Level = $Test::Builder::Level + 1;
34
35    my $ctx = shift;
36
[8eac1a5]37    my $words = shift;
38    my $word = shift;
39    my $word_point = shift;
40
[13614e7]41    my $word_start = shift;
42    my $word_end   = shift;
43
[8eac1a5]44    is_deeply($ctx->words, $words);
45    if (defined($word)) {
46        is($ctx->word, $word, "Correct current word.");
47        is($ctx->word_point, $word_point, "Correct point within word.");
[13614e7]48        is($ctx->word_start, $word_start, "Correct start of word");
49        is($ctx->word_end,   $word_end, "Correct end of word");
[8eac1a5]50    }
51}
52
[e97c5d05]53sub test_shift {
54    local $Test::Builder::Level = $Test::Builder::Level + 1;
55
56    my $before_point = shift;
57    my $after_point = shift;
58    my $shift = shift;
59   
60    my $ctx = BarnOwl::Completion::Context->new($before_point,
61                                                $after_point);
62    $ctx = $ctx->shift_words($shift);
63
64    test_ctx($ctx, @_);
65}
66
[8eac1a5]67
[14acbbd]68isa_ok(BarnOwl::Completion::Context->new('Hello, W', 'orld'), 'BarnOwl::Completion::Context');
[8eac1a5]69
70no warnings 'qw';
71test_tokenize('Hello, W', 'orld',
[13614e7]72              [qw(Hello, World)], 1, 1, 7, 12);
[8eac1a5]73
74test_tokenize('Hello, World', '',
[13614e7]75              [qw(Hello, World)], 1, 5, 7, 12);
[8eac1a5]76
[ccafe64]77test_tokenize(" \t Hello, World", '',
78              [qw(Hello, World)], 1, 5, 10, 15);
79
[8eac1a5]80test_tokenize('', '',
[ccafe64]81              [''], 0, 0, 0, 0);
82
83test_tokenize('   ', '',
84              [''], 0, 0, 3, 3);
[8eac1a5]85
86test_tokenize('Hello', 'World',
[13614e7]87              [qw(HelloWorld)], 0, 5, 0, 10);
[8eac1a5]88
[ccafe64]89test_tokenize(' Hello', 'World',
90              [qw(HelloWorld)], 0, 5, 1, 11);
91
[8eac1a5]92test_tokenize('lorem ipsum dolor ', 'sit amet',
[13614e7]93              [qw(lorem ipsum dolor sit amet)],
94              3, 0, 18, 21);
[8eac1a5]95
96test_tokenize(q{error "ls -l failed"}, q{},
[13614e7]97              ['error', 'ls -l failed'],
98              1, 12, 6, 20);
[8eac1a5]99
100test_tokenize(q{"a long"' word'}, q{},
101              ['a long word']);
102
[13614e7]103test_tokenize(q{"'"}, q{}, [q{'}], 0, 1, 0, 3);
[8eac1a5]104
105test_tokenize(q{"Hello, }, q{World"},
[13614e7]106              [q{Hello, World}],
107              0, 7, 0, 14);
[8eac1a5]108
109test_tokenize(q{But 'Hello, }, q{World'},
[13614e7]110              ['But', q{Hello, World}],
111              1, 7, 4, 18);
[8eac1a5]112
113test_tokenize(q{But "Hello, }, q{World"''''''""},
[13614e7]114              ['But', q{Hello, World}],
115              1, 7, 4, 26);
[8eac1a5]116
117test_tokenize(q{}, q{''Hello},
[13614e7]118              ['Hello'],
119              0, 0, 0, 7);
[8eac1a5]120
121test_tokenize(q{"Hello, }, q{World},
[13614e7]122              [q{Hello, World}],
123              0, 7, 0, 13);
[8eac1a5]124
125test_tokenize(q{Hello    }, q{World},
[13614e7]126              [qw{Hello World}],
127              1, 0, 9, 14);
[8eac1a5]128
129test_tokenize(q{Hello '' ""}, q{ World},
[13614e7]130              ["Hello", '', '', 'World'],
131              2, 0, 9, 11);
[8eac1a5]132
[7be5d8b]133test_tokenize(q{zwrite -c }, q{},
134              [qw(zwrite -c), ''],
135              2, 0, 10, 10);
136
[8eac1a5]137# It's not entirely clear what we should do here. Make a test for the
138# current behavior, so we'll notice if it changes.
139test_tokenize(q{Hello }, q{ World},
[13614e7]140              [qw(Hello World)],
141              1, -1, 7, 12);
[8eac1a5]142
[e97c5d05]143## Test Context::shift
[e4f4287]144test_shift('lorem ipsum dolor ', 'sit amet', 0,
145           [qw(lorem ipsum dolor sit amet)],
146           3, 0, 18, 21);
[e97c5d05]147
[e4f4287]148test_shift('lorem ipsum dolor ', 'sit amet', 1,
149           [qw(ipsum dolor sit amet)],
150           2, 0, 12, 15);
[6e48560]151
[e4f4287]152test_shift('lorem ipsum dolor ', 'sit amet', 2,
153           [qw(dolor sit amet)],
154           1, 0, 6, 9);
[e97c5d05]155
[e4f4287]156test_shift('lorem ipsum dolor ', 'sit amet', 3,
157           [qw(sit amet)],
158           0, 0, 0, 3);
159
160eval {
161    my $before_point = 'lorem ipsum dolor';
162    my $after_point = 'sit amet';
163    my $shift = 4;
164
165    my $ctx = BarnOwl::Completion::Context->new($before_point,
166                                                $after_point);
167    $ctx = $ctx->shift_words($shift);
168};
169like($@, qr/^Context::shift: Unable to shift /, "Correctly die when shifting away the point");
[e97c5d05]170
[6e48560]171## Test common_prefix
172
173is(BarnOwl::Completion::common_prefix(qw(a b)), '');
174is(BarnOwl::Completion::common_prefix(qw(a aa)), 'a');
175
176is(BarnOwl::Completion::common_prefix(qw(aa)), 'aa');
177
178is(BarnOwl::Completion::common_prefix(qw(a ab abc)), 'a');
179
180is(BarnOwl::Completion::common_prefix(qw(abc abcd)), 'abc');
181
182is(BarnOwl::Completion::common_prefix(qw(abc abc)), 'abc');
183
[c4efb46]184is(BarnOwl::Completion::common_prefix('a', ''), '');
185
[82a6e8b]186## Test complete_flags
187
188use BarnOwl::Completion::Util qw(complete_flags);
189
190# dummy complete_zwrite
191sub complete_zwrite {
192    my $ctx = shift;
193    return complete_flags($ctx,
194                          [qw(-n -C -m)],
195                          {
196                              "-c" => sub {qw(nelhage nethack sipb help)},
197                              "-i" => sub {qw()},
198                              "-r" => sub {qw(ATHENA.MIT.EDU ZONE.MIT.EDU ANDREW.CMU.EDU)},
199                              "-O" => sub {qw()},
200                          },
201                          sub {qw(nelhage asedeno geofft)});
202}
203
204sub test_complete {
205    my $before = shift;
206    my $after = shift;
207    my $words = shift;
[4fbc7f5]208    my $complete = shift || \&complete_zwrite;
[82a6e8b]209   
210    my $ctx = BarnOwl::Completion::Context->new($before, $after);
211
212    local $Test::Builder::Level = $Test::Builder::Level + 1;
213
[4fbc7f5]214    my @got = $complete->($ctx);
[82a6e8b]215    is_deeply([sort @got], [sort @$words]);
216}
217
218test_complete('zwrite -c ', '', [qw(nelhage nethack sipb help)]);
219
220test_complete('zwrite -c nelhage', '', [qw(nelhage nethack sipb help)]);
221
222test_complete('zwrite -c nelhage -i ', '', [qw()]);
223
224test_complete('zwrite -c nelhage ', '',
[69c27e6]225              [qw(-n -C -m -i -r -O nelhage asedeno geofft)]);
[82a6e8b]226
227test_complete('zwrite -c nelhage ', '-',
[69c27e6]228              [qw(-n -C -m -i -r -O nelhage asedeno geofft)]);
[82a6e8b]229
[e711ca7]230test_complete('zwrite -c nelhage -- ', '',
231              [qw(nelhage asedeno geofft)]);
232
[4fbc7f5]233sub complete_word {
234    my $ctx = shift;
235    return complete_flags($ctx,
236                          [qw(-a -b -c)],
237                          {
238                              "-d" => sub {qw(some words for completing)},
239                          },
[69c27e6]240                          sub {$_[1]},
241                          repeat_flags => 1);
[4fbc7f5]242}
243
244test_complete('cmd -a -d foo -c hello ','',
245              [qw(-a -b -c -d 1)], \&complete_word);
246
247test_complete('cmd -a -d foo -c ','',
248              [qw(-a -b -c -d 0)], \&complete_word);
249
[b017b03]250# Test that words after -- are counted properly.
251test_complete('cmd -- hi there ','',
252              [qw(2)], \&complete_word);
253
254test_complete('cmd --','',
255              [qw(-a -b -c -d 0)], \&complete_word);
256
257test_complete('cmd -- ','',
258              [qw(0)], \&complete_word);
259
260test_complete('cmd foo -- ','',
261              [qw(1)], \&complete_word);
262
263test_complete('cmd foo -- bar ','',
264              [qw(2)], \&complete_word);
265
[1167bf1]266
267# Test the filter expression completer
[6dba228]268
269sub toplevel_filter_expect {
270    return [sort(keys %BarnOwl::Complete::Filter::filter_cmds, qw[( not true false])];
271}
272
[1167bf1]273test_complete('', '',
[6dba228]274              toplevel_filter_expect(),
[1167bf1]275              \&complete_filter_expr);
276
277test_complete('not ', '',
[6dba228]278              toplevel_filter_expect(),
[1167bf1]279              \&complete_filter_expr);
280
281test_complete('true ', '',
282              [qw[and or]],
283              \&complete_filter_expr);
284
285test_complete('( true ', '',
286              [qw[and or )]],
287              \&complete_filter_expr);
288
289test_complete('( body static and body analysis and not false and class davidben and ( instance python or instance hotd ', '',
290              [qw[and or )]],
291              \&complete_filter_expr);
292
293test_complete('type ', '',
294              [qw[admin aim zephyr]],
295              \&complete_filter_expr);
296
297test_complete('direction ', '',
298              [qw[in out none]],
299              \&complete_filter_expr);
300
301test_complete('login ', '',
302              [qw[login logout none]],
303              \&complete_filter_expr);
304
[3001c11]305test_complete('deleted ', '',
306              [qw[true false]],
307              \&complete_filter_expr);
308
[e6cec01]309# Test complete_files
310use BarnOwl::Completion::Util qw(complete_file);
311use File::Temp;
312use File::Path qw(mkpath);
313
314my $tmpdir = File::Temp::tempdir(CLEANUP => 1);
315
316# Make sure $tmpdir does not have a trailing /
317$tmpdir =~ s{/$}{};
318$ENV{HOME} = $tmpdir;
319
320sub touch {
321    my $path = shift;
322    system("touch", "$path");
323}
324
325mkpath("$tmpdir/.owl/",
326       "$tmpdir/.owl/modules/",
327       "$tmpdir/Public/",
328       "$tmpdir/Private/",
329       "$tmpdir/.ours",
[366558f]330       "$tmpdir/www",
331     {mode => 0700});
[e6cec01]332touch("$tmpdir/.zephyr.subs");
333touch("$tmpdir/wheee");
334touch("$tmpdir/.owl/startup");
335
336sub completion_value {
337    my $c = shift;
338    return $c unless ref($c) eq 'ARRAY';
339    return $c->[1];
340}
341
342sub test_file {
343    my $spec  = shift;
344    my $pfx   = shift;
345    my $dirs  = shift;
346    my $files = shift;
347
348    my $expect = [ sort {$a->[1] cmp $b->[1]}
349        ((map {["$_/", defined($pfx)?"$pfx/$_/":"$_/", 0]} @$dirs),
350         (map {["$_",  defined($pfx)?"$pfx/$_" :$_   , 1]} @$files))
351       ];
352
353    local $Test::Builder::Level = $Test::Builder::Level + 1;
354
355    my @got = complete_file($spec);
356
357    @got = grep {completion_value($_) =~ m{^\Q$spec\E}} @got;
358    @got = sort {completion_value($a) cmp completion_value($b)} @got;
359
360    use Data::Dumper;
361    is_deeply(\@got, $expect);
362}
363
364is_deeply([complete_file("~")], [["~/", "~/", 0]]);
365
[0f8efe0]366END { chdir("/"); }
[e6cec01]367chdir($tmpdir);
368test_file("$tmpdir/", $tmpdir,
369          [qw(Public Private www)],
370          [qw(wheee)]);
371
372test_file("./", ".",
373          [qw(Public Private www)],
374          [qw(wheee)]);
375
376test_file("", undef, [qw(Public Private www)], [qw(wheee)]);
377
378test_file("./.owl/", "./.owl",
379          [qw(modules)],
380          [qw(startup)]);
381
382test_file("~/", "~",
383          [qw(Public Private www)],
384          [qw(wheee)]);
385
386test_file("P", undef, [qw(Public Private)], []);
387
388test_file("$tmpdir/.", $tmpdir,
389          [qw(. .. .owl .ours)],
390          [qw(.zephyr.subs)]);
[8eac1a5]3911;
[82a6e8b]392
Note: See TracBrowser for help on using the repository browser.