root/trunk/t/07-builder.t

Revision 4196, 14.8 kB (checked in by takayama, 3 months ago)

* Set svn keywords

  • Property svn:mime-type set to text/plain
Line 
1#!/usr/bin/perl
2# $Id: 07-builder.t 3022 2008-09-03 20:16:30Z bchoate $
3
4use strict;
5use lib qw( t t/lib lib extlib );
6use Data::Dumper;
7
8use MT::Test;
9
10use Test::More tests => 142;
11
12use MT;
13
14my $mt = MT->new;
15
16my($tokens, $out);
17
18use MT::Builder;
19my $builder = MT::Builder->new;
20ok($builder, "Builder constructed okay");
21
22my $ctx = My::Context->new;
23ok($ctx, "Context constructed okay");
24
25diag("Testing compilation of an empty template");
26$tokens = $builder->compile($ctx, '');
27diag("Error: " . $builder->errstr) unless $tokens;
28ok($tokens, "Compiled empty template");
29ok(ref($tokens) eq 'ARRAY', "Empty template produced token list");
30ok(!@$tokens, "Token list is empty, which is okay");
31is($builder->build($ctx, $tokens), '', "Builds to an empty string");
32
33diag("Testing compilation of a pure-text template (no tags)");
34$tokens = $builder->compile($ctx, 'justified and ancient');
35diag("Error: " . $builder->errstr) unless $tokens;
36ok($tokens && ref($tokens) eq 'ARRAY', "Compiles and yields tokens");
37ok(@$tokens == 1, "Created one token");
38ok($tokens->[0][0] eq 'TEXT', "Token is textual");
39ok($tokens->[0][1] eq 'justified and ancient', "Token text is what we expect");
40is($builder->build($ctx, $tokens), 'justified and ancient', "Builds to what we expect");
41
42diag("Testing compilation of simple function tag");
43$tokens = $builder->compile($ctx, '<$MTFoo$>');
44diag("Error: " . $builder->errstr) unless $tokens;
45ok($tokens && ref($tokens) eq 'ARRAY', "Compiles and yields tokens");
46ok(@$tokens == 1, "Created one token");
47ok($tokens->[0][0] eq 'Foo', "Token is a tag token");
48ok(@{ $tokens->[0] } == 7, "Length of token object is 7 elements");
49ok(ref($tokens->[0][1]) eq 'HASH', "Element 1 of token object is a hashref");
50is(scalar keys %{ $tokens->[0][1] }, 0, "Has no attributes");
51is($builder->build($ctx, $tokens), 'foo', "Building produces expected result");
52
53diag("Testing compilation of function tag with an attribute");
54$tokens = $builder->compile($ctx, '<$MTFoo no="1"$>');
55diag("Error: " . $builder->errstr) unless $tokens;
56ok($tokens && ref($tokens) eq 'ARRAY', "Compiles and yields tokens");
57ok(@$tokens == 1, "Created one token");
58ok(@{ $tokens->[0] } == 7, "Length of token object is 7 elements");
59ok($tokens->[0][0] eq 'Foo', "Token is a tag token");
60ok(ref($tokens->[0][1]) eq 'HASH', "Element 1 of token object is a hashref");
61is($tokens->[0][1]{no}, 1, "Attribute 'no' is equal to 1");
62is($builder->build($ctx, $tokens), 'no foo', "Building produces expected result");
63
64diag("Testing compilation of function tag with multiple attributes");
65$tokens = $builder->compile($ctx, '<$MTFoo no="1" yes="foo bar"$>');
66diag("Error: " . $builder->errstr) unless $tokens;
67ok($tokens && ref($tokens) eq 'ARRAY', "Compiles and yields tokens");
68ok(@$tokens == 1, "Created one token");
69ok(@{ $tokens->[0] } == 7, "Length of token object is 7 elements");
70ok($tokens->[0][0] eq 'Foo', "Token is a tag token");
71ok(ref($tokens->[0][1]) eq 'HASH', "Element 1 of token object is a hashref");
72is($tokens->[0][1]{no}, 1, "Attribute 'no' is equal to 1");
73is($tokens->[0][1]{yes}, 'foo bar', "Attribute 'yes' is equal to 'foo bar'");
74is($builder->build($ctx, $tokens), 'no foo', "Building produces expected result");
75
76diag("Testing compilation of function tag with attribute an inner single quote");
77$tokens = $builder->compile($ctx, '<$MTFoo yes="foo\'s bar"$>');
78diag("Error: " . $builder->errstr) unless $tokens;
79ok($tokens && ref($tokens) eq 'ARRAY', "Compiles and yields tokens");
80ok(@$tokens == 1, "Created one token");
81ok(@{ $tokens->[0] } == 7, "Length of token object is 7 elements");
82ok($tokens->[0][0] eq 'Foo', "Token is a tag token");
83ok(ref($tokens->[0][1]) eq 'HASH', "Element 1 of token object is a hashref");
84is($tokens->[0][1]{yes}, 'foo\'s bar', "Attribute 'yes' is equal to \"foo's bar\"");
85
86diag("Testing compilation of text + function tag");
87$tokens = $builder->compile($ctx, <<'TEXT');
88time to kick out the jams, motherfuckers
89<$MTFoo$>
90TEXT
91diag("Error: " . $builder->errstr) unless $tokens;
92ok($tokens && ref($tokens) eq 'ARRAY', "Compiles and yields tokens");
93ok(@$tokens == 3, "Created 3 tokens");
94ok($tokens->[0][0] eq 'TEXT', "Token 1 is a text token");
95ok($tokens->[0][1] eq "time to kick out the jams, motherfuckers\n", "Text is expected value");
96ok($tokens->[1][0] eq 'Foo', "Token 2 is a tag token");
97ok($tokens->[2][0] eq 'TEXT', "Token 3 is a text token");
98ok($tokens->[2][1] eq "\n", "Text is expected value");
99is($builder->build($ctx, $tokens),
100    "time to kick out the jams, motherfuckers\nfoo\n", "Building produces expected result");
101is($builder->build($ctx, $tokens, { Foo => 0 }),
102    "time to kick out the jams, motherfuckers\n\n", "Building produces expected result, with conditional");
103
104diag("Testing compilation failure for a block tag (no closing tag)");
105$tokens = $builder->compile($ctx, '<MTBars>');
106diag("Error: " . $builder->errstr) unless $tokens;
107ok(!$tokens, "Compiling failed, as expected");
108ok($builder->errstr eq "<MTBars> with no </MTBars> on line 1.\n", "Compilation yielded proper error message");
109
110# diag("Testing compilation failure for a nested block tag");
111# $tokens = $builder->compile($ctx, <<EOT);
112# <MTBars>
113#
114#
115#
116#
117# <MTBars>
118#
119# </MTBars>
120#
121# <MTBars> # ERROR IS HERE, LINE 10
122#
123# <MTBars>
124#
125# </MTBars>
126# EOT
127# diag("Error: " . $builder->errstr) unless $tokens;
128# ok(!$tokens, "Compiling failed, as expected");
129# ok($builder->errstr eq "<MTBars> with no </MTBars> on line 10.\n", "Compilation yielded proper error message");
130
131diag("Testing compilation of a block tag with nothing in it");
132$tokens = $builder->compile($ctx, '<MTBars></MTBars>');
133diag("Error: " . $builder->errstr) unless $tokens;
134ok($tokens && ref($tokens) eq 'ARRAY', "Compiles and yields tokens");
135ok(@$tokens == 1, "Created 1 token");
136ok($tokens->[0][0] eq 'Bars', "Token is a tag token");
137ok(ref($tokens->[0][2]) eq 'ARRAY', "Token has child token array");
138ok(@{ $tokens->[0][2] } == 0, "Child token length is 0");
139is($builder->build($ctx, $tokens), 'Called without tokens!', "Building produces expected result");
140
141diag("Testing compilation of a block tag wrapping plaintext");
142$tokens = $builder->compile($ctx, '<MTBars>foo</MTBars>');
143diag("Error: " . $builder->errstr) unless $tokens;
144ok($tokens && ref($tokens) eq 'ARRAY', "Compiles and yields tokens");
145ok(@$tokens == 1, "Created 1 token");
146ok($tokens->[0][0] eq 'Bars', "Token is a tag token");
147ok(ref($tokens->[0][2]) eq 'ARRAY', "Token has child token array");
148ok(@{ $tokens->[0][2] } == 1, "Child token length is 1");
149ok($tokens->[0][2][0][0] eq 'TEXT', "Child token is textual");
150ok($tokens->[0][2][0][1] eq 'foo', "Child token value is 'foo'");
151is($builder->build($ctx, $tokens), 'foofoo', "Building produces expected result");
152
153diag("Testing compilation of a block tag wrapping plaintext + function tag");
154$tokens = $builder->compile($ctx, <<'TEXT');
155<MTBars>
156foo:<$MTBarBaz$>
157</MTBars>
158TEXT
159diag("Error: " . $builder->errstr) unless $tokens;
160ok($tokens && ref($tokens) eq 'ARRAY', "Compiles and yields tokens");
161ok(@$tokens == 2, "Created 2 tokens");
162ok($tokens->[0][0] eq 'Bars', "Token 1 is a tag token");
163ok(ref($tokens->[0][2]) eq 'ARRAY', "Token has child token array");
164ok(@{ $tokens->[0][2] } == 3, "Child token array length is 3");
165ok($tokens->[0][2][0][0] eq 'TEXT', "First child token is textual");
166ok($tokens->[0][2][0][1] eq "\nfoo:", "First child token text matches");
167ok($tokens->[0][2][1][0] eq 'BarBaz', "Second child token is a tag");
168ok($tokens->[0][2][2][0] eq 'TEXT', "Third child token is textual");
169ok($tokens->[0][2][2][1] eq "\n", "Third child token text matches");
170ok($tokens->[1][0] eq 'TEXT', "Second token is textual");
171ok($tokens->[1][1] eq "\n", "Second token text matches");
172is($builder->build($ctx, $tokens), "\nfoo:baz1\n\nfoo:baz2\n\n", "Building produces expected result");
173
174$tokens = $builder->compile($ctx,
175q[<$MTFoo regex="s/(\d+)/$1==0?'None':$1==1?'1 reply':$1.'replies'/e"$>]);
176diag("Error: " . $builder->errstr) unless $tokens;
177ok($tokens && ref($tokens) eq 'ARRAY', "Compiles and yields tokens");
178ok(@$tokens == 1, "Created 1 token");
179ok(@{ $tokens->[0] } == 7, "Length of token object is 7 elements");
180ok($tokens->[0][0] eq 'Foo', "Token 1 is a tag token");
181ok(ref($tokens->[0][1]) eq 'HASH', "Token has an attribute hashref");
182is($tokens->[0][1]{regex}, q[s/(\d+)/$1==0?'None':$1==1?'1 reply':$1.'replies'/e], "'regex' attribute is set properly");
183
184diag("Testing compilation of nesting a block tag");
185$tokens = $builder->compile($ctx, <<'TEXT');
186<MTBars>
187Bars:
188<MTBars>bar</MTBars>
189</MTBars>
190TEXT
191diag("Error: " . $builder->errstr) unless $tokens;
192ok($tokens && ref($tokens) eq 'ARRAY', "Compiles and yields tokens");
193ok(@$tokens == 2, "Created 2 tokens");
194ok($tokens->[0][0] eq 'Bars', "Token 1 is a tag token");
195ok(ref($tokens->[0][2]) eq 'ARRAY', "Token 1 has subtokens");
196ok(@{ $tokens->[0][2] } == 3, "Subtoken length is 3");
197ok($tokens->[0][2][0][0] eq 'TEXT', "Subtoken 1 is textual");
198ok($tokens->[0][2][0][1] eq "\nBars:\n", "Subtoken 1 is expected value");
199ok($tokens->[0][2][1][0] eq 'Bars', "Subtoken 2 is a tag token");
200ok(ref($tokens->[0][2][1][2]) eq 'ARRAY', "Subtoken 2 contains subtokens");
201ok(@{ $tokens->[0][2][1][2] } == 1, "Subtoken 2 has 1 child token");
202ok($tokens->[0][2][1][2][0][0] eq 'TEXT', "Subtoken 2's child node is textual");
203ok($tokens->[0][2][1][2][0][1] eq 'bar', "Subtoken 2's child node is expected value");
204ok($tokens->[0][2][2][0] eq 'TEXT', "Subtoken 3 is textual");
205ok($tokens->[0][2][2][1] eq "\n", "Subtoken 3 is expected value");
206ok($tokens->[1][0] eq 'TEXT', "Token 2 is textual");
207ok($tokens->[1][1] eq "\n", "Token 2 is expected value");
208is($builder->build($ctx, $tokens), "\nBars:\nbarbar\n\nBars:\nbarbar\n\n", "Building produces expected result");
209
210diag("Testing compilation of an empty block tag (singlet syntax)");
211$tokens = $builder->compile($ctx, "<MTBars/>");
212diag("Error: " . $builder->errstr) unless $tokens;
213ok($tokens && ref($tokens) eq 'ARRAY', "Compiles and yields tokens");
214ok(@$tokens == 1, "Created 1 token");
215ok($tokens->[0][0] eq 'Bars', "Token is a tag token");
216ok(!@{ $tokens->[0][2] || [] }, "Subtoken list is empty");
217is($builder->build($ctx, $tokens), 'Called without tokens!', "Building produces expected result");
218
219diag("Testing compilation with an attribute that has a newline");
220$tokens = $builder->compile($ctx, '<$MTFoo no="1
221"$>');
222diag("Error: " . $builder->errstr) unless $tokens;
223ok($tokens && ref($tokens) eq 'ARRAY', "Compiles and yields tokens");
224ok(@$tokens == 1, "Created 1 token");
225ok(@{ $tokens->[0] } == 7, "Length of token object is 7 elements");
226ok($tokens->[0][0] eq 'Foo', "Token 1 is a tag token");
227ok(ref($tokens->[0][1]) eq 'HASH', "Token 1 has an attribute hashref");
228is($tokens->[0][1]{no}, "1\n", "Value of 'no' attribute is set properly");
229is($builder->build($ctx, $tokens), 'no foo', "Building produces expected result");
230
231diag("Testing conditional tag");
232$tokens = $builder->compile($ctx, '<MTIfBaz>yes</MTIfBaz>');
233diag("Error: " . $builder->errstr) unless $tokens;
234ok($tokens && ref($tokens) eq 'ARRAY', "Compiles and yields token");
235is($builder->build($ctx, $tokens, { IfBaz => 1 }), 'yes', "Building with conditional set produces expected result");
236is($builder->build($ctx, $tokens, { IfBaz => 0 }), '', "Building with conditional unset produces expected result");
237
238diag("Testing conditional tags with Else tag");
239$tokens = $builder->compile($ctx, '<MTIfBaz>yes<MTElse>no</MTElse></MTIfBaz>');
240diag("Error: " . $builder->errstr) unless $tokens;
241ok($tokens && ref($tokens) eq 'ARRAY', "Compiles and yields token");
242is($builder->build($ctx, $tokens, { IfBaz => 1 }), 'yes', "Building with conditional set produces expected result");
243is($builder->build($ctx, $tokens, { IfBaz => 0 }), 'no', "Building with conditional unset produces expected result");
244
245diag("Testing conditional tags with Else (but no closing Else) tag");
246$tokens = $builder->compile($ctx, '<MTIfBaz>yes<MTElse>no</MTIfBaz>');
247diag("Error: " . $builder->errstr) unless $tokens;
248ok($tokens && ref($tokens) eq 'ARRAY', "Compiles and yields token");
249is($builder->build($ctx, $tokens, { IfBaz => 1 }), 'yes', "Building with conditional set produces expected result");
250is($builder->build($ctx, $tokens, { IfBaz => 0 }), 'no', "Building with conditional unset produces expected result");
251
252diag("Testing case-insensitivity for MT templates");
253$tokens = $builder->compile($ctx, '<$MtFoO$>');
254diag("Error: " . $builder->errstr) unless $tokens;
255ok($tokens && ref($tokens) eq 'ARRAY', "Compiles and yields tokens");
256ok(@$tokens == 1, "Created one token");
257ok($tokens->[0][0] eq 'FoO', "Token is a tag token");
258ok(@{ $tokens->[0] } == 7, "Length of token object is 7 elements");
259ok(ref($tokens->[0][1]) eq 'HASH', "Element 1 of token object is a hashref");
260is(scalar keys %{ $tokens->[0][1] }, 0, "Has no attributes");
261is($builder->build($ctx, $tokens), 'foo', "Building produces expected result");
262
263diag("Testing optional '$' syntax for function tags");
264$tokens = $builder->compile($ctx, '<mtfoo>');
265diag("Error: " . $builder->errstr) unless $tokens;
266ok($tokens && ref($tokens) eq 'ARRAY', "Compiles and yields tokens");
267ok(@$tokens == 1, "Created one token");
268ok($tokens->[0][0] eq 'foo', "Token is a tag token");
269ok(@{ $tokens->[0] } == 7, "Length of token object is 7 elements");
270ok(ref($tokens->[0][1]) eq 'HASH', "Element 1 of token object is a hashref");
271is(scalar keys %{ $tokens->[0][1] }, 0, "Has no attributes");
272is($builder->build($ctx, $tokens), 'foo', "Building produces expected result");
273
274diag("Testing optional namespace ':' syntax for function tags");
275$tokens = $builder->compile($ctx, '<mt:foo>');
276diag("Error: " . $builder->errstr) unless $tokens;
277ok($tokens && ref($tokens) eq 'ARRAY', "Compiles and yields tokens");
278ok(@$tokens == 1, "Created one token");
279ok($tokens->[0][0] eq 'foo', "Token is a tag token");
280ok(@{ $tokens->[0] } == 7, "Length of token object is 7 elements");
281ok(ref($tokens->[0][1]) eq 'HASH', "Element 1 of token object is a hashref");
282is(scalar keys %{ $tokens->[0][1] }, 0, "Has no attributes");
283is($builder->build($ctx, $tokens), 'foo', "Building produces expected result");
284
285
286package My::Context;
287
288use strict;
289use base qw( MT::Template::Context );
290
291sub new {
292    my $class = shift;
293    my $ctx = $class->SUPER::new(@_);
294    $ctx->{__handlers}{foo} = \&_hdlr_foo;
295    $ctx->{__handlers}{bars} = [ \&_hdlr_bars, 1 ];
296    $ctx->{__handlers}{barbaz} = \&_hdlr_bar_baz;
297    $ctx->{__handlers}{ifbaz} = [ \&MT::Template::Context::_hdlr_pass_tokens, 1 ];
298    return $ctx;
299}
300
301sub _hdlr_foo {
302    my $args = $_[1];
303    $args && $args->{no} ? 'no foo' : 'foo'
304}
305
306sub _hdlr_bars {
307    my($ctx) = @_;
308    my $tokens = $ctx->stash('tokens');
309    return 'Called without tokens!' if !$tokens || !@$tokens;
310    my $builder = $ctx->stash('builder');
311    my $html = '';
312    for (1..2) {
313        my $bar = { baz => 'baz' . $_ };
314        $ctx->stash('bar', $bar);
315        my $out = $builder->build($ctx, $tokens);
316        return $ctx->error( $builder->errstr ) unless defined $out;
317        $html .= $out;
318    }
319    $html;
320}
321
322sub _hdlr_bar_baz {
323    my $bar = $_[0]->stash('bar');
324    $bar->{baz};
325}
Note: See TracBrowser for help on using the browser.