@@ -11,6 +11,16 @@ class UnitTestCase
1111
1212 protected static $ _lastRunsPassesAndFails = array ('passes ' => array (), 'fails ' => array ());
1313
14+ /**
15+ * @var string
16+ */
17+ private $ _expectedExceptionClass ;
18+
19+ /**
20+ * @var string
21+ */
22+ private $ _currentMethod ;
23+
1424 public function setUp ()
1525 {
1626 }
@@ -19,6 +29,11 @@ public function tearDown()
1929 {
2030 }
2131
32+ protected function expectException ($ class )
33+ {
34+ $ this ->_expectedExceptionClass = $ class ;
35+ }
36+
2237 public function init ()
2338 {
2439 $ tmpFileName = $ this ->getPassesAndFailsCachePath ();
@@ -70,6 +85,15 @@ public function assertIdentical($value, $value2)
7085 }
7186 }
7287
88+ public function assertNotIdentical ($ value , $ value2 )
89+ {
90+ if ($ value !== $ value2 ) {
91+ $ this ->pass ();
92+ } else {
93+ $ this ->_fail ();
94+ }
95+ }
96+
7397 public function assertNotEqual ($ value , $ value2 )
7498 {
7599 if ($ value != $ value2 ) {
@@ -126,41 +150,75 @@ public function pass()
126150
127151 public function fail ($ message = "" )
128152 {
129- $ this ->_fail ($ message );
153+ $ this ->_fail ($ message );
130154 }
131155
132156 public function _fail ($ message = "" )
157+ {
158+ $ stack = $ this ->findTestMethodStack ();
159+
160+ $ this ->appendMessage ($ stack ['class ' ], $ stack ['method ' ], $ stack ['line ' ], $ message );
161+
162+ $ this ->_failed ++;
163+
164+ $ class = get_class ($ this );
165+
166+ if (isset (self ::$ _passesAndFails ['passes ' ][$ class ])) {
167+ unset(self ::$ _passesAndFails ['passes ' ][$ class ]);
168+ }
169+
170+ self ::$ _passesAndFails ['fails ' ][$ class ] = $ class ;
171+ }
172+
173+ private function findTestMethodStack ()
133174 {
134175 $ trace = debug_backtrace ();
135176 array_shift ($ trace );
136177
137-
138178 foreach ($ trace as $ stack ) {
139- if (substr ($ stack ['function ' ], 0 , 4 ) === ' test ' ) {
179+ if ($ this -> isTestMethod ($ stack ['function ' ]) ) {
140180 $ class = new ReflectionClass ($ stack ['class ' ]);
141181
142182 if ( ! isset ($ line )) {
143183 $ line = $ stack ['line ' ];
144184 }
145185
146- $ errorMessage = $ class ->getName () . ' : method ' . $ stack ['function ' ] . ' failed on line ' . $ line ;
147- $ this ->_messages [] = $ errorMessage . " " . $ message ;
148- break ;
186+ return array (
187+ 'class ' => $ class ->getName (),
188+ 'method ' => $ stack ['function ' ],
189+ 'line ' => $ line ,
190+ );
149191 }
192+
150193 $ line = $ stack ['line ' ];
151194 }
152- $ this ->_failed ++;
153- $ class = get_class ($ this );
154- if (isset (self ::$ _passesAndFails ['passes ' ][$ class ])) {
155- unset(self ::$ _passesAndFails ['passes ' ][$ class ]);
195+
196+ return array (
197+ 'class ' => get_class ($ this ),
198+ 'method ' => $ this ->_currentMethod ,
199+ 'line ' => null ,
200+ );
201+ }
202+
203+ private function appendMessage ($ testCase , $ testFuntion , $ line = null , $ message = "" )
204+ {
205+ $ lineMessage = '' ;
206+
207+ if (null !== $ line ) {
208+ $ lineMessage = 'on line ' .$ line ;
156209 }
157- self ::$ _passesAndFails ['fails ' ][$ class ] = $ class ;
210+
211+ $ errorMessage = $ testCase . ' : method ' . $ testFuntion . ' failed ' .$ lineMessage ;
212+
213+ $ this ->_messages [] = $ errorMessage . " " . $ message ;
158214 }
159215
160216 public function run (DoctrineTest_Reporter $ reporter = null , $ filter = null )
161217 {
162218 foreach (get_class_methods ($ this ) as $ method ) {
163219 if ($ this ->isTestMethod ($ method )) {
220+ $ this ->_currentMethod = $ method ;
221+
164222 $ this ->runTest ($ method );
165223 }
166224 }
@@ -294,8 +352,49 @@ private function tryFinally(Closure $try, Closure $finally)
294352
295353 $ finally ();
296354
355+ if (null !== $ this ->_expectedExceptionClass ) {
356+ $ this ->assertThrownException ($ thrownException );
357+
358+ return ;
359+ }
360+
297361 if (null !== $ thrownException ) {
298362 throw $ thrownException ;
299363 }
300364 }
365+
366+ private function assertThrownException ($ thrownException )
367+ {
368+ $ expectedExceptionClass = $ this ->_expectedExceptionClass ;
369+
370+ $ this ->_expectedExceptionClass = null ;
371+
372+ if (null === $ thrownException ) {
373+ $ message = sprintf ('Assert that exception "%s" is thrown. ' ,
374+ $ expectedExceptionClass
375+ );
376+
377+ $ this ->fail ($ message );
378+
379+ return ;
380+ }
381+
382+ $ thrownExceptionClass = get_class ($ thrownException );
383+
384+ if (
385+ $ expectedExceptionClass === $ thrownExceptionClass
386+ || is_subclass_of ($ thrownExceptionClass , $ expectedExceptionClass )
387+ ) {
388+ $ this ->pass ();
389+
390+ return ;
391+ }
392+
393+ $ message = sprintf ('Assert that exception "%s" is thrown, but was "%s". ' ,
394+ $ expectedExceptionClass ,
395+ $ thrownExceptionClass
396+ );
397+
398+ $ this ->fail ($ message );
399+ }
301400}
0 commit comments