]> git.donarmstrong.com Git - liborg-parser-perl.git/blob - t/headline.t
Import original source of Org-Parser 0.23
[liborg-parser-perl.git] / t / headline.t
1 #!perl
2
3 use 5.010;
4 use strict;
5 use warnings;
6
7 use FindBin '$Bin';
8 use lib $Bin, "$Bin/t";
9
10 #use Org::Dump;
11 use Org::Parser;
12 use Test::More 0.96;
13 require "testlib.pl";
14
15 test_parse(
16     name => 'non-headline (missing space)',
17     filter_elements => 'Org::Element::Headline',
18     doc  => <<'_',
19 *h
20 _
21     num => 0,
22 );
23
24 test_parse(
25     name => 'non-headline (not on first column)',
26     filter_elements => 'Org::Element::Headline',
27     doc  => <<'_',
28  * h
29 _
30     num => 0,
31 );
32
33 test_parse(
34     name => 'non-headline (no title)',
35     filter_elements => 'Org::Element::Headline',
36     doc  => <<'_',
37 *
38 _
39     num => 0,
40 );
41
42 test_parse(
43     name => 'headline basic tests',
44     filter_elements => 'Org::Element::Headline',
45     doc  => <<'_',
46 *   h1 1
47 ** h2 1  :tag1:tag2:
48 *** h3 1  :invalid-tag:
49 text
50 *** TODO [#A] h3 2
51     text
52 ** DONE h2 2
53 * h1 2
54 _
55     num => 6,
56     test_after_parse => sub {
57         my (%args) = @_;
58         my $elems = $args{elements};
59         is($elems->[0]->title->as_string, "  h1 1", "0: title not trimmed");
60         is($elems->[0]->level, 1, "0: level");
61
62         is($elems->[1]->title->as_string, "h2 1", "1: title");
63         is($elems->[1]->level, 2, "1: level");
64         is_deeply($elems->[1]->tags, ['tag1', 'tag2'], "1: tags");
65
66         is($elems->[2]->title->as_string, "h3 1  :invalid-tag:", "2: title");
67         is($elems->[2]->level, 3, "2: level");
68
69         is( $elems->[3]->title->as_string, "h3 2", "3: title");
70         is( $elems->[3]->level, 3, "3: level");
71         is( $elems->[3]->is_todo, 1, "3: is_todo");
72         ok(!$elems->[3]->is_done, "3: is_done");
73         is( $elems->[3]->todo_state, "TODO", "3: todo_state");
74         is( $elems->[3]->todo_priority, "A", "3: todo_priority");
75
76         is($elems->[4]->title->as_string, "h2 2", "4: title");
77         is($elems->[4]->level, 2, "4: level");
78         is($elems->[4]->is_todo, 1, "4: is_todo");
79         is($elems->[4]->is_done, 1, "4: is_done");
80         is($elems->[4]->todo_state, "DONE", "4: todo_state");
81         # XXX default priority
82
83         is($elems->[5]->title->as_string, "h1 2", "5: title");
84         is($elems->[5]->level, 1, "5: level");
85     },
86 );
87
88 test_parse(
89     name => 'headline levels',
90     filter_elements => 'Org::Element::Headline',
91     doc  => <<'_',
92 * h1
93 ** h2
94 *** h3
95 **** h4
96 ***** h5
97 * h1b
98 *** h3b
99 _
100     num => 7,
101     test_after_parse => sub {
102         my (%args) = @_;
103         my $elems = $args{elements};
104         is($elems->[1]->parent->title->as_string, "h1", "parent of h2=h1");
105         is($elems->[2]->parent->title->as_string, "h2", "parent of h3=h2");
106         is($elems->[3]->parent->title->as_string, "h3", "parent of h4=h3");
107         is($elems->[4]->parent->title->as_string, "h4", "parent of h5=h4");
108         is($elems->[6]->parent->title->as_string, "h1b", "parent of h3b=h1b");
109     },
110 );
111
112 test_parse(
113     name => 'todo keyword is case sensitive',
114     filter_elements => sub { $_[0]->isa('Org::Element::Headline') &&
115                                  $_[0]->is_todo },
116     doc  => <<'_',
117 * TODO 1
118 * Todo 2
119 * todo 3
120 * toDO 4
121 _
122     num => 1,
123 );
124
125 test_parse(
126     name => 'todo keyword can be separated by other \W aside from \s',
127     filter_elements => sub { $_[0]->isa('Org::Element::Headline') &&
128                                  $_[0]->is_todo },
129     doc  => <<"_",
130 * TODO   1
131 * TODO\t2
132 * TODO+3a
133 * TODO+  3b
134 * TODO/4a
135 * TODO//4b
136
137 * TODO5a
138 * TODO_5b
139 _
140     num => 6,
141     test_after_parse => sub {
142         my (%args) = @_;
143         my $elems = $args{elements};
144         is($elems->[0]->title->as_string, "1", "title 1");
145         is($elems->[1]->title->as_string, "2", "title 2");
146         is($elems->[2]->title->as_string, "+3a", "title 3");
147         is($elems->[3]->title->as_string, "+  3b", "title 4");
148         is($elems->[4]->title->as_string, "/4a", "title 5");
149         is($elems->[5]->title->as_string, "//4b", "title 6");
150     },
151 );
152
153 test_parse(
154     name => 'inline elements in headline title',
155     filter_elements => 'Org::Element::Headline',
156     doc  => <<'_',
157 * this headline contains timestamp <2011-03-17 > as well as text
158 _
159     num => 1,
160     test_after_parse => sub {
161         my (%args) = @_;
162         my $elems = $args{elements};
163         my $hl    = $elems->[0];
164         my $title = $hl->title;
165         isa_ok($title->children->[0], "Org::Element::Text");
166         isa_ok($title->children->[1], "Org::Element::Timestamp");
167         isa_ok($title->children->[2], "Org::Element::Text");
168     },
169 );
170
171 test_parse(
172     name => 'get_tags()',
173     filter_elements => 'Org::Element::Headline',
174     doc  => <<'_',
175 #+FILETAGS: :t1:t2:
176 * a      :t3:
177 ** b     :t4:
178 * c
179 _
180     num => 3,
181     test_after_parse => sub {
182         my (%args) = @_;
183         my $elems = $args{elements};
184         my $tags;
185         $tags = [$elems->[0]->get_tags];
186         is_deeply($tags, [qw/t3 t1 t2/], "get_tags 0") or diag explain $tags;
187         $tags = [$elems->[1]->get_tags];
188         is_deeply($tags, [qw/t4 t3 t1 t2/], "get_tags 1") or diag explain $tags;
189         $tags = [$elems->[2]->get_tags];
190         is_deeply($tags, [qw/t1 t2/], "get_tags 2") or diag explain $tags;
191     },
192 );
193
194 test_parse(
195     name => 'get_active_timestamp()',
196     filter_elements => 'Org::Element::Headline',
197     doc  => <<'_',
198 * TODO <2011-06-06 > t0
199 * TODO t1 <2011-06-06 >
200 * TODO t2
201   DEADLINE: <2011-06-06 >
202   DEADLINE: <2011-06-07 >
203 * TODO [2011-06-06 ] t3
204 * TODO t4
205 _
206     num => 5,
207     test_after_parse => sub {
208         my (%args) = @_;
209         my $elems = $args{elements};
210         ok( $elems->[0]->get_active_timestamp, "t0 has active timestamp");
211         ok( $elems->[1]->get_active_timestamp, "t1 has active timestamp");
212         ok( $elems->[2]->get_active_timestamp, "t2 has active timestamp");
213         # XXX check only the first timestamp is returned
214         ok(!$elems->[3]->get_active_timestamp,
215            "t3 doesn't have active timestamp");
216         ok(!$elems->[4]->get_active_timestamp,
217            "t4 doesn't have active timestamp");
218     },
219 );
220
221 test_parse(
222     name => 'is_leaf()',
223     filter_elements => 'Org::Element::Headline',
224     doc  => <<'_',
225 * a
226 ** b
227 *** c
228 * d
229 _
230     num => 4,
231     test_after_parse => sub {
232         my (%args) = @_;
233         my $elems = $args{elements};
234         ok(!$elems->[0]->is_leaf, "a is not leaf");
235         ok(!$elems->[1]->is_leaf, "b is not leaf");
236         ok( $elems->[2]->is_leaf, "c is leaf");
237         ok( $elems->[3]->is_leaf, "d is leaf");
238     },
239 );
240
241 test_parse(
242     name => 'promote_node() 1',
243     filter_elements => 'Org::Element::Headline',
244     doc  => <<'_',
245 * h1
246 ** h2
247 * h3
248 _
249     num => 3,
250     test_after_parse => sub {
251         my (%args) = @_;
252         my $doc    = $args{result};
253         my $elems  = $args{elements};
254         my ($h1, $h2, $h3) = @$elems;
255
256         $h1->promote_node;
257         is($h1->level, 1, "level 1 won't be promoted further");
258
259         $h2->promote_node;
260         is($h2->level, 1, "level 2 becomes level 1 after being promoted");
261         is($h2->as_string, "* h2\n", "_str reset after being promoted");
262         is($h2->prev_sibling, $h1, "parent becomes sibling (1)");
263         is($h2->next_sibling, $h3, "parent becomes sibling (2)");
264     },
265 );
266 test_parse(
267     name => 'promote_node() 2',
268     filter_elements => 'Org::Element::Headline',
269     doc  => <<'_',
270 ** h1
271 ** h2
272 ** h3
273 _
274     num => 3,
275     test_after_parse => sub {
276         my (%args) = @_;
277         my $elems = $args{elements};
278         my ($h1, $h2, $h3) = @$elems;
279
280         $h2->promote_node;
281         ok(!$h2->next_sibling, "no more sibling after promote (2)")
282             or diag explain $h2->next_sibling->as_string;
283         is($h2->children->[0], $h3, "sibling becomes child");
284     },
285 );
286 test_parse(
287     name => 'promote_node() 3',
288     filter_elements => 'Org::Element::Headline',
289     doc  => <<'_',
290 *** h1
291 _
292     num => 1,
293     test_after_parse => sub {
294         my (%args) = @_;
295         my $elems = $args{elements};
296         my ($h1) = @$elems;
297
298         $h1->promote_node(2);
299         is($h1->level, 1, "promote with argument, level 3 -> 1");
300     },
301 );
302
303 test_parse(
304     name => 'demote_node() 1',
305     filter_elements => 'Org::Element::Headline',
306     doc  => <<'_',
307 * h1
308 * h2
309 * h3
310 _
311     num => 3,
312     test_after_parse => sub {
313         my (%args) = @_;
314         my $doc    = $args{result};
315         my $elems  = $args{elements};
316         my ($h1, $h2, $h3) = @$elems;
317
318         $h2->demote_node;
319         is($h2->level, 2, "level 1 becomes level 2");
320         is($h2->parent, $h1, "prev_sibling becomes parent");
321         is($h1->next_sibling, $h3, "h1's next_sibling becomes h3");
322         is($h3->prev_sibling, $h1, "h3's prev_sibling becomes h1");
323     },
324 );
325 test_parse(
326     name => 'demote_node() 2',
327     filter_elements => 'Org::Element::Headline',
328     doc  => <<'_',
329 * h1
330 _
331     num => 1,
332     test_after_parse => sub {
333         my (%args) = @_;
334         my $elems = $args{elements};
335         my ($h1) = @$elems;
336
337         $h1->demote_node(3);
338         is($h1->level, 4, "demote 3 means level 1 becomes 4");
339     },
340 );
341
342 test_parse(
343     name => 'promote_branch()',
344     filter_elements => 'Org::Element::Headline',
345     doc  => <<'_',
346 ** h1
347 *** h2
348 **** h3
349 *** h4
350 ** h5
351 _
352     num => 5,
353     test_after_parse => sub {
354         my (%args) = @_;
355         my $doc    = $args{result};
356         my $elems  = $args{elements};
357         my ($h1, $h2, $h3, $h4, $h5) = @$elems;
358
359         $h1->promote_branch;
360         is($h1->level, 1, "h1 becomes level 1");
361         is($h2->level, 2, "h2 becomes level 2");
362         is($h3->level, 3, "h3 becomes level 3");
363         is($h4->level, 2, "h4 becomes level 2");
364         is($h5->level, 2, "h5 stays at level 2");
365     },
366 );
367
368 test_parse(
369     name => 'demote_branch()',
370     filter_elements => 'Org::Element::Headline',
371     doc  => <<'_',
372 ** h1
373 *** h2
374 **** h3
375 *** h4
376 ** h5
377 _
378     num => 5,
379     test_after_parse => sub {
380         my (%args) = @_;
381         my $doc    = $args{result};
382         my $elems  = $args{elements};
383         my ($h1, $h2, $h3, $h4, $h5) = @$elems;
384
385         $h1->demote_branch;
386         is($h1->level, 3, "h1 becomes level 3");
387         is($h2->level, 4, "h2 becomes level 4");
388         is($h3->level, 5, "h3 becomes level 5");
389         is($h4->level, 4, "h4 becomes level 4");
390         is($h5->level, 2, "h5 stays at level 2");
391     },
392 );
393
394 done_testing();