Mercurial > pub > Impl
comparison lib/IMPL/Test/Plan.pm @ 407:c6e90e02dd17 ref20150831
renamed Lib->lib
author | cin |
---|---|
date | Fri, 04 Sep 2015 19:40:23 +0300 |
parents | |
children | 9335cf010b23 |
comparison
equal
deleted
inserted
replaced
406:f23fcb19d3c1 | 407:c6e90e02dd17 |
---|---|
1 package IMPL::Test::Plan; | |
2 use strict; | |
3 use warnings; | |
4 | |
5 use parent qw(IMPL::Object); | |
6 use IMPL::Class::Property; | |
7 | |
8 use IMPL::Exception; | |
9 use IMPL::Test::Result; | |
10 use IMPL::Test::BadUnit; | |
11 use Error qw(:try); | |
12 | |
13 use IMPL::Serialization; | |
14 use IMPL::Serialization::XmlFormatter; | |
15 | |
16 BEGIN { | |
17 public property Units => prop_all | prop_list; | |
18 public property Results => prop_all | prop_list; | |
19 public property Listeners => prop_all | prop_list; | |
20 private property _Cache => prop_all | prop_list; | |
21 private property _Count => prop_all; | |
22 } | |
23 | |
24 sub CTOR { | |
25 my $this = shift; | |
26 $this->Units(\@_); | |
27 } | |
28 | |
29 sub restore { | |
30 my ($class,$data,$instance) = @_; | |
31 | |
32 $instance ||= $class->surrogate; | |
33 | |
34 $instance->callCTOR(); | |
35 | |
36 my %args = @$data; | |
37 | |
38 $instance->Units($args{Units}); | |
39 $instance->Results($args{Results}) if $args{Results}; | |
40 $instance->Listeners($args{Listeners}) if $args{Listeners}; | |
41 } | |
42 | |
43 sub save { | |
44 my ($this,$ctx) = @_; | |
45 | |
46 $ctx->AddVar(Units => [$this->Units]); | |
47 $ctx->AddVar(Results => [$this->Results]) if $this->Results; | |
48 $ctx->AddVar(Listeners => [$this->Listeners]) if $this->Listeners; | |
49 } | |
50 | |
51 sub AddListener { | |
52 my ($this,$listener) = @_; | |
53 | |
54 $this->Listeners($this->Listeners,$listener); | |
55 } | |
56 | |
57 sub Prepare { | |
58 my ($this) = @_; | |
59 | |
60 my $count = 0; | |
61 my @cache; | |
62 | |
63 foreach my $Unit ($this->Units){ | |
64 my %info; | |
65 | |
66 # preload module | |
67 undef $@; | |
68 | |
69 eval "require $Unit" unless (ref $Unit); | |
70 | |
71 # handle loading errors | |
72 $Unit = new IMPL::Test::BadUnit($Unit,"Failed to load unit",$@) if $@; | |
73 | |
74 $info{Unit} = $Unit; | |
75 try { | |
76 $info{Tests} = [$Unit->List]; | |
77 } otherwise { | |
78 my $err = $@; | |
79 $Unit = $info{Unit} = new IMPL::Test::BadUnit( | |
80 $Unit->can('UnitName') ? | |
81 $Unit->UnitName : | |
82 $Unit, | |
83 "Failed to extract tests", | |
84 $err | |
85 ); | |
86 $info{Tests} = [$Unit->List]; | |
87 }; | |
88 $count += @{$info{Tests}}; | |
89 push @cache, \%info if @{$info{Tests}}; | |
90 } | |
91 | |
92 $this->_Count($count); | |
93 $this->_Cache(\@cache); | |
94 } | |
95 | |
96 sub Count { | |
97 my ($this) = @_; | |
98 return $this->_Count; | |
99 } | |
100 | |
101 sub Run { | |
102 my $this = shift; | |
103 | |
104 die new IMPL::InvalidOperationException("You must call the prepare method before running the plan") unless $this->_Cache; | |
105 | |
106 $this->_Tell(RunPlan => $this); | |
107 | |
108 my @resultsTotal; | |
109 | |
110 foreach my $info ($this->_Cache) { | |
111 $this->_Tell(RunUnit => $info->{Unit}); | |
112 | |
113 my $data; | |
114 undef $@; | |
115 eval { | |
116 $data = $info->{Unit}->StartUnit; | |
117 }; | |
118 | |
119 my @results; | |
120 | |
121 if (not $@) { | |
122 | |
123 foreach my $test (@{$info->{Tests}}) { | |
124 my $name = $test->Name; | |
125 | |
126 #protected creation of the test | |
127 $test = eval { $info->{Unit}->new($test); } || new IMPL::Test::BadUnit( | |
128 $info->{Unit}->can('UnitName') ? | |
129 $info->{Unit}->UnitName : | |
130 $info->{Unit}, | |
131 "Failed to construct the test $name", | |
132 $@ | |
133 ); | |
134 | |
135 # invoke the test | |
136 $this->_Tell(RunTest => $test); | |
137 my $result = $test->Run($data); | |
138 $this->_Tell(EndTest => $test,$result); | |
139 | |
140 push @results,$result; | |
141 } | |
142 } else { | |
143 my $e = $@; | |
144 my $badTest = new IMPL::Test::BadUnit( | |
145 $info->{Unit}->can('UnitName') ? | |
146 $info->{Unit}->UnitName : | |
147 $info->{Unit}, | |
148 "Failed to initialize the unit", | |
149 $@ | |
150 ); | |
151 foreach my $test (@{$info->{Tests}}) { | |
152 | |
153 $this->_Tell(RunTest => $badTest); | |
154 my $result = new IMPL::Test::Result( | |
155 Name => $test->Name, | |
156 State => IMPL::Test::Result::FAIL, | |
157 Exception => $e | |
158 ); | |
159 $this->_Tell(EndTest => $badTest,$result); | |
160 push @results,$result; | |
161 } | |
162 } | |
163 | |
164 eval { | |
165 $info->{Unit}->FinishUnit($data); | |
166 }; | |
167 | |
168 undef $@; | |
169 | |
170 push @resultsTotal, { Unit => $info->{Unit}, Results => \@results}; | |
171 | |
172 $this->_Tell(EndUnit => $info->{Unit},\@results); | |
173 } | |
174 | |
175 $this->Results(\@resultsTotal); | |
176 $this->_Tell(EndPlan => $this); | |
177 } | |
178 | |
179 sub _Tell { | |
180 my ($this,$what,@args) = @_; | |
181 | |
182 $_->$what(@args) foreach $this->Listeners; | |
183 } | |
184 | |
185 sub SaveXML { | |
186 my ($this,$out) = @_; | |
187 | |
188 my $h; | |
189 | |
190 if (ref $out eq 'GLOB') { | |
191 $h = $out; | |
192 } elsif ($out and not ref $out) { | |
193 open $h, ">", $out or die new IMPL::Exception("Failed to open file",$out); | |
194 } else { | |
195 die new IMPL::InvalidOperationException("Invalid output specified"); | |
196 } | |
197 | |
198 my $s = new IMPL::Serializer(Formatter => new IMPL::Serialization::XmlFormatter( IdentOutput => 1, SkipWhitespace => 1) ); | |
199 $s->Serialize($h,$this); | |
200 } | |
201 | |
202 sub LoadXML { | |
203 my ($self,$in) = @_; | |
204 | |
205 my $h; | |
206 | |
207 if (ref $in eq 'GLOB') { | |
208 $h = $in; | |
209 } elsif ($in and not ref $in) { | |
210 open $h, ">", $in or die new IMPL::Exception("Failed to open file",$in); | |
211 } else { | |
212 die new IMPL::InvalidOperationException("Invalid input specified"); | |
213 } | |
214 | |
215 my $s = new IMPL::Serializer(Formatter => new IMPL::Serialization::XmlFormatter( IdentOutput => 1, SkipWhitespace => 1) ); | |
216 return $s->Deserialize($h); | |
217 } | |
218 | |
219 sub xml { | |
220 my $this = shift; | |
221 my $str = ''; | |
222 | |
223 open my $h,'>',\$str or die new IMPL::Exception("Failed to create stream"); | |
224 $this->SaveXML($h); | |
225 undef $h; | |
226 return $str; | |
227 } | |
228 | |
229 sub LoadXMLString { | |
230 my $self = shift; | |
231 my $str = shift; | |
232 | |
233 open my $h,'<',\$str or die new IMPL::Exception("Failed to create stream"); | |
234 return $self->LoadXML($h); | |
235 } | |
236 | |
237 | |
238 1; |