Mercurial > pub > Impl
annotate _test/Test/Web/View.pm @ 288:3a9cfea098dd
*TTView refactoring: removed RequireControl method, etc.
author | sergey |
---|---|
date | Tue, 19 Feb 2013 19:58:27 +0400 |
parents | 2d253e6e4a88 |
children | 85572f512abc |
rev | line source |
---|---|
183 | 1 package Test::Web::View; |
188 | 2 use IMPL::Profiler::Memory; |
183 | 3 use strict; |
4 use warnings; | |
185 | 5 use utf8; |
183 | 6 |
7 use parent qw(IMPL::Test::Unit); | |
8 __PACKAGE__->PassThroughArgs; | |
9 | |
185 | 10 use File::Slurp; |
188 | 11 use Scalar::Util qw(weaken); |
288
3a9cfea098dd
*TTView refactoring: removed RequireControl method, etc.
sergey
parents:
287
diff
changeset
|
12 use Data::Dumper; |
280 | 13 use IMPL::lang; |
286 | 14 use IMPL::Test qw(assert assertarray test GetCallerSourceLine); |
183 | 15 use IMPL::Web::View::TTLoader(); |
16 | |
17 use constant { | |
280 | 18 TTLoader => 'IMPL::Web::View::TTLoader', |
194 | 19 MProfiler => 'IMPL::Profiler::Memory' |
183 | 20 }; |
21 | |
188 | 22 sub AssertMemoryLeak { |
194 | 23 my $code = shift; |
24 my $dump = shift; | |
25 | |
26 my $data = MProfiler->Monitor($code); | |
27 | |
28 if ($data->isLeak and $dump) { | |
29 write_file("dump.out", { binmode => ':utf8' }, $data->Dump() ); | |
30 } | |
31 | |
32 assert( not($data->isLeak), "Memory leak detected", GetCallerSourceLine() , @{$data->{objects}} ); | |
188 | 33 } |
34 | |
185 | 35 sub templatesDir { |
194 | 36 $_[0]->GetResourceDir('Resources','TTView'); |
185 | 37 } |
38 | |
188 | 39 sub CreateLoader { |
194 | 40 my ($this) = @_; |
41 | |
42 my $loader = TTLoader->new( | |
43 { | |
44 INCLUDE_PATH => [ | |
45 $this->templatesDir | |
46 ], | |
47 INTERPOLATE => 1, | |
48 POST_CHOMP => 1, | |
49 ENCODING => 'utf-8' | |
50 }, | |
51 ext => '.tt', | |
52 initializer => 'global.tt', | |
53 globals => { | |
54 site => { | |
55 name => 'Test Site' | |
56 }, | |
57 date => { | |
58 now => sub { localtime(time); } | |
59 }, | |
195
7a920771fd8e
IMPL::Web::View changed document layout handling, docs, examples
cin
parents:
194
diff
changeset
|
60 dynamic => sub { 'this is a dynamic value' }, |
7a920771fd8e
IMPL::Web::View changed document layout handling, docs, examples
cin
parents:
194
diff
changeset
|
61 view => { |
7a920771fd8e
IMPL::Web::View changed document layout handling, docs, examples
cin
parents:
194
diff
changeset
|
62 } |
7a920771fd8e
IMPL::Web::View changed document layout handling, docs, examples
cin
parents:
194
diff
changeset
|
63 }, |
7a920771fd8e
IMPL::Web::View changed document layout handling, docs, examples
cin
parents:
194
diff
changeset
|
64 layoutBase => 'Layout' |
194 | 65 ); |
188 | 66 } |
67 | |
68 test TTLoaderTests => sub { | |
194 | 69 my ($this) = @_; |
70 | |
71 my $loader = $this->CreateLoader(); | |
72 | |
73 # test the loader to be able to find a desired resource | |
74 assert( defined($loader->template('simple') ) ); | |
75 | |
76 # loader should be initialized on demand | |
77 assert( not $loader->isInitialized ); | |
78 | |
79 # loader should be able to load a document | |
80 my $doc = $loader->document('simple'); | |
81 assert(defined $doc); | |
82 | |
83 assert( $loader->isInitialized ); | |
84 assert( $loader->context->stash->get('user') eq 'test_user'); | |
85 | |
86 # document should inherit loader's context | |
87 assert( $doc->context->stash->get('user') eq 'test_user'); | |
88 | |
89 # document should not have 'this' template variable | |
90 assert( not $doc->templateVars('this') ); | |
91 | |
92 assert( $doc->context != $loader->context); # document should have an own context | |
183 | 93 }; |
94 | |
185 | 95 test TTDocumentTests => sub { |
194 | 96 my ($this) = @_; |
97 my $loader = $this->CreateLoader(); | |
98 | |
99 my $doc = $loader->document('simple'); | |
100 | |
101 assert(defined $doc); | |
287 | 102 |
194 | 103 $doc->title('test document'); |
104 | |
238 | 105 assert($doc->name eq 'document'); |
194 | 106 assert($doc->title eq 'test document'); |
107 | |
108 assert(not $doc->can('notexists')); # autoloaded property should be ignored | |
109 assert(not defined $doc->notexists); # nonexisting property | |
110 assert($doc->template->version == 10); # static metadata | |
111 assert($doc->templateVars('notexists') eq ''); #nonexisting template variable | |
112 assert($doc->templateVars('user') eq 'test_user'); # global data | |
113 assert($doc->templateVars('templateVar') eq ''); # defined in CTOR block, should be local | |
114 assert($doc->templateVars('dynamic') eq 'this is a dynamic value'); | |
288
3a9cfea098dd
*TTView refactoring: removed RequireControl method, etc.
sergey
parents:
287
diff
changeset
|
115 assert($doc->context->stash->get('user') eq 'test_user' ); # runtime context should be derived from documentContext |
3a9cfea098dd
*TTView refactoring: removed RequireControl method, etc.
sergey
parents:
287
diff
changeset
|
116 $doc->context->stash->set('user', 'nobody'); |
3a9cfea098dd
*TTView refactoring: removed RequireControl method, etc.
sergey
parents:
287
diff
changeset
|
117 assert($doc->templateVars('user') eq 'test_user'); # isolated |
3a9cfea098dd
*TTView refactoring: removed RequireControl method, etc.
sergey
parents:
287
diff
changeset
|
118 $doc->context->stash->set('user', 'test_user'); |
194 | 119 |
120 my $text = $doc->Render(); | |
121 my $expected = read_file($this->GetResourceFile('Resources','TTView.Output','simple.txt'), binmode => ':utf8'); | |
122 | |
123 assert($text eq $expected, "Bad Render() output","Got: $text", "Expected: $expected"); | |
124 | |
185 | 125 }; |
126 | |
186 | 127 test TTControlTests => sub { |
194 | 128 my ($this) = @_; |
129 | |
130 my $loader = $this->CreateLoader(); | |
131 | |
132 my $doc = $loader->document('simple'); | |
133 | |
134 assert(defined $doc); | |
135 | |
238 | 136 my $factory = $doc->RequireControl('My/Org/Panel'); |
194 | 137 |
138 assert(defined $factory); | |
139 | |
263 | 140 # control factory shares document scope to perform an initialization on demand |
141 assert($factory->context->stash == $doc->context->stash); | |
194 | 142 |
238 | 143 assert($factory == $doc->RequireControl('My/Org/Panel'), "Control should be loaded only once"); |
194 | 144 |
145 my $ctl = $factory->new('information', { visualClass => 'simple', data => ['one','two','hello world'] } ); | |
146 | |
147 assert(defined $ctl); | |
148 | |
238 | 149 assert($ctl->name eq 'information', "Created control should have a name", "Got: ".$ctl->name, "Expected: information"); |
194 | 150 |
238 | 151 assert($ctl->GetAttribute('visualClass') eq 'simple'); |
194 | 152 |
153 assert($factory->instances == 1); | |
154 | |
238 | 155 $doc->childNodes([$ctl]); |
194 | 156 |
157 assert($doc->templateVars('dojo.require')); | |
158 assert(ref $doc->templateVars('dojo.require') eq 'ARRAY'); | |
159 assert($doc->templateVars('dojo.require')->[0] eq 'dijit.form.Input' ); | |
160 | |
161 my $text = $ctl->Render(); | |
162 | |
163 my $expected = read_file($this->GetResourceFile('Resources', 'TTView.Output', 'Panel.txt'), binmode => ':utf8'); | |
164 assert($text eq $expected, '$ctl->Render(): Bad output', "Got: $text", "Expected: $expected"); | |
165 | |
166 | |
288
3a9cfea098dd
*TTView refactoring: removed RequireControl method, etc.
sergey
parents:
287
diff
changeset
|
167 my $doc2 = $loader->document('simple'); |
3a9cfea098dd
*TTView refactoring: removed RequireControl method, etc.
sergey
parents:
287
diff
changeset
|
168 |
3a9cfea098dd
*TTView refactoring: removed RequireControl method, etc.
sergey
parents:
287
diff
changeset
|
169 assert( $doc2->documentContext->stash->get( ['require',['My/Org/Panel'] ] ) ); |
3a9cfea098dd
*TTView refactoring: removed RequireControl method, etc.
sergey
parents:
287
diff
changeset
|
170 print Dumper($doc2->context->stash); |
3a9cfea098dd
*TTView refactoring: removed RequireControl method, etc.
sergey
parents:
287
diff
changeset
|
171 assert( $doc2->context->stash->get( ['require',['My/Org/Panel'] ] ) ); |
3a9cfea098dd
*TTView refactoring: removed RequireControl method, etc.
sergey
parents:
287
diff
changeset
|
172 |
194 | 173 |
191 | 174 }; |
175 | |
176 test TestDocumentLayout => sub { | |
194 | 177 my ($this) = @_; |
178 | |
179 my $loader = $this->CreateLoader(); | |
180 | |
181 my $doc = $loader->document( | |
182 'complex', | |
183 { | |
184 data => [qw(one two three)], | |
185 site => { | |
186 name => 'Test Site' | |
187 } | |
188 } | |
189 ); | |
190 | |
195
7a920771fd8e
IMPL::Web::View changed document layout handling, docs, examples
cin
parents:
194
diff
changeset
|
191 assert($doc->layout eq 'default'); |
194 | 192 |
193 my $text = $doc->Render(); | |
194 my $expected = read_file($this->GetResourceFile('Resources', 'TTView.Output', 'complex.default.txt'), binmode => ':utf8' ); | |
287 | 195 my ($text_raw,$expected_raw) = ($text, $expected); |
196 $text_raw =~ s/\s+//g; | |
197 $expected_raw =~ s/\s+//g; | |
198 assert($text_raw eq $expected_raw, '$doc->Render(): Bad output', "Got: $text", "Expected: $expected"); | |
186 | 199 }; |
200 | |
286 | 201 test TestDocumentsIsolation => sub { |
202 my $this = shift; | |
203 | |
204 my $loader = $this->CreateLoader(); | |
205 | |
206 my $doc = $loader->document('simple'); | |
207 | |
208 assert(ref $loader->context->stash->get([ 'dojo', 0, 'require', 0]) eq 'ARRAY'); | |
209 assertarray($loader->context->stash->get([ 'dojo', 0, 'require', 0]),[]); | |
288
3a9cfea098dd
*TTView refactoring: removed RequireControl method, etc.
sergey
parents:
287
diff
changeset
|
210 assert($loader->context->stash != $doc->context->stash); |
3a9cfea098dd
*TTView refactoring: removed RequireControl method, etc.
sergey
parents:
287
diff
changeset
|
211 assert($loader->context->stash != $doc->documentContext->stash); |
3a9cfea098dd
*TTView refactoring: removed RequireControl method, etc.
sergey
parents:
287
diff
changeset
|
212 assert($doc->context->stash != $doc->documentContext->stash); |
286 | 213 |
214 assert(defined $doc); | |
215 | |
216 # only root stash variables can be localized, to avoid modifying dojo we | |
217 # need to replace it completely | |
218 $doc->context->process(\q{ | |
219 [% SET dojo = { require => [] } %] | |
220 [% dojo.require.push('dijit/form/TextBox') %] | |
221 [% SET user = 'dummy guy' %] | |
222 }); | |
223 | |
224 assert($doc->context->stash->get('user') eq 'dummy guy'); | |
225 assert($loader->context->stash->get('user') eq 'test_user'); | |
226 assertarray($doc->context->stash->get([ 'dojo', 0, 'require', 0]),['dijit/form/TextBox']); | |
227 assertarray($loader->context->stash->get([ 'dojo', 0, 'require', 0]),[]); | |
228 | |
229 my $text = $doc->Render(); | |
230 | |
287 | 231 my $doc2 = $loader->document('complex'); |
286 | 232 |
233 assertarray($doc2->context->stash->get([ 'dojo', 0, 'require', 0]),[]); | |
287 | 234 |
235 # This document has a layout ehich will replace 'dojo' global variable. | |
236 # The layout contains INIT block which runs first in the context of the | |
237 # document, then RenderContent is called and then the layout is applied | |
238 $doc2->Render(); | |
239 | |
240 assertarray($loader->context->stash->get([ 'dojo', 0, 'require', 0]),[]); | |
241 | |
242 # TODO: to be able to rendered multiple times, Render shouldn't affect the context of the document | |
243 #assertarray($doc2->context->stash->get([ 'dojo', 0, 'require', 0]),[]); | |
286 | 244 }; |
245 | |
188 | 246 test TestMemoryLeaks => sub { |
194 | 247 my ($this) = @_; |
248 | |
249 my $loader = $this->CreateLoader(); | |
250 $loader->document('simple'); # force loader initialization | |
251 | |
252 AssertMemoryLeak(sub { | |
253 my $doc = $loader->document('simple'); | |
254 }); | |
255 | |
256 AssertMemoryLeak(sub { | |
257 my $doc = $loader->document('simple'); | |
258 $doc->Render( { self => $doc } ); | |
259 }); | |
260 | |
261 $loader->template('Layout/default'); | |
262 $loader->template('My/Org/Panel'); | |
263 $loader->template('My/Org/TextPreview'); | |
264 AssertMemoryLeak(sub { | |
265 my $doc = $loader->document('simple'); | |
238 | 266 my $factory = $doc->RequireControl('My/Org/Panel'); |
267 my $ctl = $doc->childNodes($factory->new('information', { visualClass => 'complex' }) ); | |
263 | 268 },'dump'); |
194 | 269 |
270 $loader->template('complex'); | |
271 AssertMemoryLeak(sub { | |
272 my $doc = $loader->document('complex'); | |
273 $doc->Render(); | |
274 },'dump'); | |
275 | |
188 | 276 }; |
277 | |
183 | 278 1; |