Mercurial > pub > Impl
view _test/Test/Web/View.pm @ 301:aeeb57a12046
*IMPL::Web::View: templates inheritance support
author | cin |
---|---|
date | Mon, 25 Mar 2013 02:04:18 +0400 |
parents | 85572f512abc |
children | 608e74bc309f |
line wrap: on
line source
package Test::Web::View; use IMPL::Profiler::Memory; use strict; use warnings; use utf8; use parent qw(IMPL::Test::Unit); __PACKAGE__->PassThroughArgs; use File::Slurp; use Scalar::Util qw(weaken); use Data::Dumper; use IMPL::lang; use IMPL::Test qw(assert assertarray test GetCallerSourceLine); use IMPL::Web::View::TTLoader(); use constant { TTLoader => 'IMPL::Web::View::TTLoader', MProfiler => 'IMPL::Profiler::Memory' }; sub AssertMemoryLeak { my $code = shift; my $dump = shift; my $data = MProfiler->Monitor($code); if ($data->isLeak and $dump) { write_file("dump.out", { binmode => ':utf8' }, $data->Dump() ); } assert( not($data->isLeak), "Memory leak detected", GetCallerSourceLine() , @{$data->{objects}} ); } sub templatesDir { $_[0]->GetResourceDir('Resources','TTView'); } sub CreateLoader { my ($this) = @_; my $loader = TTLoader->new( { INCLUDE_PATH => [ $this->templatesDir ], INTERPOLATE => 1, POST_CHOMP => 1, ENCODING => 'utf-8' }, ext => '.tt', initializer => 'global.tt', globals => { site => { name => 'Test Site' }, date => { now => sub { localtime(time); } }, dynamic => sub { 'this is a dynamic value' }, view => { } }, layoutBase => 'Layout' ); } test TTLoaderTests => sub { my ($this) = @_; my $loader = $this->CreateLoader(); # test the loader to be able to find a desired resource assert( defined($loader->template('simple') ) ); # loader should be initialized on demand assert( not $loader->isInitialized ); # loader should be able to load a document my $doc = $loader->document('simple'); assert(defined $doc); assert( $loader->isInitialized ); assert( $loader->context->stash->get('user') eq 'test_user'); # document should inherit loader's context assert( $doc->context->stash->get('user') eq 'test_user'); # document should not have 'this' template variable assert( $doc->context != $loader->context); # document should have an own context }; test TTDocumentTests => sub { my ($this) = @_; my $loader = $this->CreateLoader(); my $doc = $loader->document('simple'); assert(defined $doc); $doc->title('test document'); $doc->name('document'); assert($doc->name eq 'document'); assert($doc->title eq 'test document'); assert(not $doc->can('notexists')); # autoloaded property should be ignored assert(not defined $doc->notexists); # nonexisting property assert($doc->template->version == 10); # static metadata assert($doc->context->stash->get('user') eq 'test_user' ); # runtime context should be derived from documentContext my $text = $doc->Render(); my $expected = read_file($this->GetResourceFile('Resources','TTView.Output','simple.txt'), binmode => ':utf8'); assert($text eq $expected, "Bad Render() output","Got: $text", "Expected: $expected"); }; test TestDocumentLayout => sub { my ($this) = @_; my $loader = $this->CreateLoader(); my $doc = $loader->document( 'complex', { data => [qw(one two three)], site => { name => 'Test Site' } } ); assert($doc->layout eq 'default'); my $text = $doc->Render(); my $expected = read_file($this->GetResourceFile('Resources', 'TTView.Output', 'complex.default.txt'), binmode => ':utf8' ); my ($text_raw,$expected_raw) = ($text, $expected); $text_raw =~ s/\s+//g; $expected_raw =~ s/\s+//g; assert($text_raw eq $expected_raw, '$doc->Render(): Bad output', "Got: $text", "Expected: $expected"); }; test TestControlInheritance => sub { my ($this) = @_; my $loader = $this->CreateLoader(); my $doc = $loader->document('derived'); my $text = $doc->Render(); my $expected = read_file($this->GetResourceFile('Resources', 'TTView.Output', 'derived.txt'), binmode => ':utf8' ); my ($text_raw,$expected_raw) = ($text, $expected); $text_raw =~ s/\s+//g; $expected_raw =~ s/\s+//g; assert($text_raw eq $expected_raw, '$doc->Render(): Bad output', "Got: $text", "Expected: $expected"); }; test TestDocumentsIsolation => sub { my $this = shift; my $loader = $this->CreateLoader(); my $doc = $loader->document('simple'); assert(ref $loader->context->stash->get([ 'dojo', 0, 'require', 0]) eq 'ARRAY'); assertarray($loader->context->stash->get([ 'dojo', 0, 'require', 0]),[]); assert($loader->context->stash != $doc->context->stash); assert(defined $doc); # only root stash variables can be localized, to avoid modifying dojo we # need to replace it completely $doc->context->process(\q{ [% SET dojo = { require => [] } %] [% dojo.require.push('dijit/form/TextBox') %] [% SET user = 'dummy guy' %] }); assert($doc->context->stash->get('user') eq 'dummy guy'); assert($loader->context->stash->get('user') eq 'test_user'); assertarray($doc->context->stash->get([ 'dojo', 0, 'require', 0]),['dijit/form/TextBox']); assertarray($loader->context->stash->get([ 'dojo', 0, 'require', 0]),[]); my $text = $doc->Render(); my $doc2 = $loader->document('complex'); assertarray($doc2->context->stash->get([ 'dojo', 0, 'require', 0]),[]); # This document has a layout ehich will replace 'dojo' global variable. # The layout contains INIT block which runs first in the context of the # document, then RenderContent is called and then the layout is applied $doc2->Render(); assertarray($loader->context->stash->get([ 'dojo', 0, 'require', 0]),[]); # TODO: to be able to rendered multiple times, Render shouldn't affect the context of the document #assertarray($doc2->context->stash->get([ 'dojo', 0, 'require', 0]),[]); }; test TestMemoryLeaks => sub { my ($this) = @_; my $loader = $this->CreateLoader(); $loader->document('simple'); # force loader initialization AssertMemoryLeak(sub { my $doc = $loader->document('simple'); },'dump'); AssertMemoryLeak(sub { my $doc = $loader->document('simple'); $doc->Render( { self => $doc } ); },'dump'); $loader->template('Layout/default'); $loader->template('My/Org/Panel'); $loader->template('My/Org/TextPreview'); $loader->template('complex'); AssertMemoryLeak(sub { my $doc = $loader->document('complex'); $doc->Render(); },'dump'); }; 1;