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;