Mercurial > pub > Impl
comparison _test/Test/Web/View.pm @ 188:029c9610528c
Memory leak tests in IMPL::Web::View
| author | cin |
|---|---|
| date | Tue, 03 Apr 2012 20:08:42 +0400 |
| parents | 6c0fee769b0c |
| children | 08015e2803f1 |
comparison
equal
deleted
inserted
replaced
| 187:927653d01f4f | 188:029c9610528c |
|---|---|
| 1 package Test::Web::View; | 1 package Test::Web::View; |
| 2 use IMPL::Profiler::Memory; | |
| 2 use strict; | 3 use strict; |
| 3 use warnings; | 4 use warnings; |
| 4 use utf8; | 5 use utf8; |
| 5 | 6 |
| 6 use parent qw(IMPL::Test::Unit); | 7 use parent qw(IMPL::Test::Unit); |
| 7 __PACKAGE__->PassThroughArgs; | 8 __PACKAGE__->PassThroughArgs; |
| 8 | 9 |
| 9 use File::Slurp; | 10 use File::Slurp; |
| 11 use Scalar::Util qw(weaken); | |
| 10 | 12 |
| 11 use IMPL::Test qw(assert test); | 13 use IMPL::Test qw(assert test GetCallerSourceLine); |
| 12 use IMPL::Web::View::TTLoader(); | 14 use IMPL::Web::View::TTLoader(); |
| 13 | 15 |
| 14 use constant { | 16 use constant { |
| 15 TTLoader => typeof IMPL::Web::View::TTLoader | 17 TTLoader => typeof IMPL::Web::View::TTLoader, |
| 18 MProfiler => 'IMPL::Profiler::Memory' | |
| 16 }; | 19 }; |
| 20 | |
| 21 sub AssertMemoryLeak { | |
| 22 my $code = shift; | |
| 23 my $dump = shift; | |
| 24 | |
| 25 my $data = MProfiler->Monitor($code, sub { $_ =~ m/^IMPL::/} ); | |
| 26 | |
| 27 assert( not($data->isLeak), "Memory leak detected", GetCallerSourceLine() , @{$data->{objects}}, $dump ? $data->Dump : () ); | |
| 28 } | |
| 17 | 29 |
| 18 sub templatesDir { | 30 sub templatesDir { |
| 19 $_[0]->GetResourceDir('Resources','TTView'); | 31 $_[0]->GetResourceDir('Resources','TTView'); |
| 20 } | 32 } |
| 21 | 33 |
| 22 test TTLoaderTests => sub { | 34 sub CreateLoader { |
| 23 my ($this) = @_; | 35 my ($this) = @_; |
| 24 | 36 |
| 25 my $loader = TTLoader->new( | 37 my $loader = TTLoader->new( |
| 26 { | 38 { |
| 27 INCLUDE_PATH => [ | 39 INCLUDE_PATH => [ |
| 28 $this->templatesDir | 40 $this->templatesDir |
| 29 ] | 41 ], |
| 42 INTERPOLATE => 1, | |
| 43 POST_CHOMP => 1, | |
| 44 ENCODING => 'utf-8' | |
| 30 }, | 45 }, |
| 31 ext => '.tt', | 46 ext => '.tt', |
| 32 initializer => 'global.tt' | 47 initializer => 'global.tt' |
| 33 ); | 48 ); |
| 49 } | |
| 50 | |
| 51 test TTLoaderTests => sub { | |
| 52 my ($this) = @_; | |
| 53 | |
| 54 my $loader = $this->CreateLoader(); | |
| 34 | 55 |
| 35 # test the loader to be able to find a desired resource | 56 # test the loader to be able to find a desired resource |
| 36 assert( defined($loader->template('simple') ) ); | 57 assert( defined($loader->template('simple') ) ); |
| 37 | 58 |
| 38 # loader should be initialized on demand | 59 # loader should be initialized on demand |
| 45 assert( $loader->isInitialized ); | 66 assert( $loader->isInitialized ); |
| 46 assert( $loader->context->stash->get('user') eq 'test_user'); | 67 assert( $loader->context->stash->get('user') eq 'test_user'); |
| 47 | 68 |
| 48 # document should inherit loader's context | 69 # document should inherit loader's context |
| 49 assert( $doc->context->stash->get('user') eq 'test_user'); | 70 assert( $doc->context->stash->get('user') eq 'test_user'); |
| 71 | |
| 72 # document should not have 'this' template variable | |
| 73 assert( not $doc->templateVars('this') ); | |
| 74 | |
| 75 assert( $doc->context != $loader->context); # document should have an own context | |
| 50 }; | 76 }; |
| 51 | 77 |
| 52 test TTDocumentTests => sub { | 78 test TTDocumentTests => sub { |
| 53 my ($this) = @_; | 79 my ($this) = @_; |
| 54 my $loader = TTLoader->new( | 80 my $loader = $this->CreateLoader(); |
| 55 { | |
| 56 INCLUDE_PATH => [ | |
| 57 $this->templatesDir | |
| 58 ], | |
| 59 INTERPOLATE => 1, | |
| 60 POST_CHOMP => 1, | |
| 61 ENCODING => 'utf-8' | |
| 62 }, | |
| 63 ext => '.tt', | |
| 64 initializer => 'global.tt' | |
| 65 ); | |
| 66 | 81 |
| 67 my $doc = $loader->document('simple'); | 82 my $doc = $loader->document('simple'); |
| 68 | 83 |
| 69 assert(defined $doc); | 84 assert(defined $doc); |
| 70 | 85 |
| 71 assert($doc->nodeName eq 'document'); | 86 assert($doc->nodeName eq 'document'); |
| 72 assert(not $doc->can('notexists')); # autoloaded property should be ignored | 87 assert(not $doc->can('notexists')); # autoloaded property should be ignored |
| 73 assert($doc->notexists eq ''); # nonexisting property | 88 assert(not defined $doc->notexists); # nonexisting property |
| 74 assert($doc->version == 10); # static metadata | 89 assert($doc->template->version == 10); # static metadata |
| 75 assert($doc->user eq 'test_user'); # global data | 90 assert($doc->templateVars('notexists') eq ''); #nonexisting template variable |
| 76 assert($doc->templateVar eq 'initialized by the constructor'); # defined in CTOR block | 91 assert($doc->templateVars('user') eq 'test_user'); # global data |
| 92 assert($doc->templateVars('templateVar') eq 'initialized by the constructor'); # defined in CTOR block | |
| 77 | 93 |
| 78 my $text = $doc->Render(); | 94 my $text = $doc->Render(); |
| 79 my $expected = read_file($this->GetResourceFile('Resources','TTView.Output','simple.txt'), binmode => ':utf8'); | 95 my $expected = read_file($this->GetResourceFile('Resources','TTView.Output','simple.txt'), binmode => ':utf8'); |
| 80 | 96 |
| 81 assert($text eq $expected, "Bad Render() output","Got: $text", "Expected: $expected"); | 97 assert($text eq $expected, "Bad Render() output","Got: $text", "Expected: $expected"); |
| 83 }; | 99 }; |
| 84 | 100 |
| 85 test TTControlTests => sub { | 101 test TTControlTests => sub { |
| 86 my ($this) = @_; | 102 my ($this) = @_; |
| 87 | 103 |
| 88 my $loader = TTLoader->new( | 104 my $loader = $this->CreateLoader(); |
| 89 { | |
| 90 INCLUDE_PATH => [ | |
| 91 $this->templatesDir | |
| 92 ], | |
| 93 INTERPOLATE => 1, | |
| 94 POST_CHOMP => 1, | |
| 95 ENCODING => 'utf8' | |
| 96 }, | |
| 97 ext => '.tt', | |
| 98 initializer => 'global.tt' | |
| 99 ); | |
| 100 | 105 |
| 101 my $doc = $loader->document('simple'); | 106 my $doc = $loader->document('simple'); |
| 102 | 107 |
| 103 assert(defined $doc); | 108 assert(defined $doc); |
| 104 | 109 |
| 105 my $factory = $doc->require('My/Org/Panel'); | 110 my $factory = $doc->require('My/Org/Panel'); |
| 106 | 111 |
| 107 assert(defined $factory); | 112 assert(defined $factory); |
| 108 | 113 |
| 114 assert(not $loader->context->stash->get('My.Org.Panel')); | |
| 115 | |
| 116 assert($factory->context->stash != $doc->context->stash); | |
| 117 | |
| 109 assert($factory == $doc->require('My/Org/Panel'), "Control should be loaded only once"); | 118 assert($factory == $doc->require('My/Org/Panel'), "Control should be loaded only once"); |
| 110 | 119 |
| 111 my $ctl = $factory->new('information', { visualClass => 'simple' } ); | 120 my $ctl = $factory->new('information', { visualClass => 'simple' } ); |
| 112 | 121 |
| 113 assert(defined $ctl); | 122 assert(defined $ctl); |
| 114 | |
| 115 | 123 |
| 116 assert($ctl->nodeName eq 'information', "Created control should have a name", "Got: ".$ctl->nodeName, "Expected: information"); | 124 assert($ctl->nodeName eq 'information', "Created control should have a name", "Got: ".$ctl->nodeName, "Expected: information"); |
| 117 | 125 |
| 118 assert($ctl->nodeProperty('visualClass') eq 'simple'); | 126 assert($ctl->nodeProperty('visualClass') eq 'simple'); |
| 119 | 127 |
| 120 assert($ctl->controlObject == $ctl); | |
| 121 | |
| 122 assert($factory->instances == 1); | 128 assert($factory->instances == 1); |
| 123 | 129 |
| 124 assert($doc->context->stash->get('My.Org.Panel') == $factory); | 130 assert($doc->templateVars('My.Org.Panel') == $factory); |
| 125 | 131 |
| 126 my $text = $ctl->Render(); | 132 my $text = $ctl->Render(); |
| 127 my $expected = read_file($this->GetResourceFile('Resources', 'TTView.Output', 'Panel.txt'), binmode => ':utf8'); | 133 my $expected = read_file($this->GetResourceFile('Resources', 'TTView.Output', 'Panel.txt'), binmode => ':utf8'); |
| 128 | 134 |
| 129 assert($text eq $expected, '$ctl->Render(): Bad output', "Got: $text", "Expected: $expected"); | 135 assert($text eq $expected, '$ctl->Render(): Bad output', "Got: $text", "Expected: $expected"); |
| 130 | 136 |
| 131 }; | 137 }; |
| 132 | 138 |
| 139 test TestMemoryLeaks => sub { | |
| 140 my ($this) = @_; | |
| 141 | |
| 142 my $loader = $this->CreateLoader(); | |
| 143 $loader->document('simple'); # force loader initialization | |
| 144 | |
| 145 AssertMemoryLeak(sub { | |
| 146 my $doc = $loader->document('simple'); | |
| 147 }); | |
| 148 | |
| 149 AssertMemoryLeak(sub { | |
| 150 my $doc = $loader->document('simple'); | |
| 151 $doc->Render( { self => $doc } ); | |
| 152 }); | |
| 153 | |
| 154 AssertMemoryLeak(sub{ | |
| 155 my $doc = $loader->document('simple'); | |
| 156 my $factory = $doc->require('My/Org/Panel'); | |
| 157 #my $ctl = $doc->AppendChild($factory->new('information', { visualClass => 'complex' }) ); | |
| 158 }); | |
| 159 | |
| 160 }; | |
| 161 | |
| 133 1; | 162 1; |
