close Warning: Can't use blame annotator:
svn blame failed on trunk/server/www/vendors/simpletest/mock_objects.php: ("Can't find a temporary directory: Internal error", 20014)

source: trunk/server/www/vendors/simpletest/mock_objects.php @ 6

Last change on this file since 6 was 6, checked in by sander, 12 years ago

Added SimpleTest? test framework

File size: 56.3 KB
RevLine 
1<?php
2/**
3 *  base include file for SimpleTest
4 *  @package    SimpleTest
5 *  @subpackage MockObjects
6 *  @version    $Id: mock_objects.php 1672 2008-03-02 04:47:34Z edwardzyang $
7 */
8
9/**#@+
10 * include SimpleTest files
11 */
12require_once(dirname(__FILE__) . '/expectation.php');
13require_once(dirname(__FILE__) . '/simpletest.php');
14require_once(dirname(__FILE__) . '/dumper.php');
15if (version_compare(phpversion(), '5') >= 0) {
16    require_once(dirname(__FILE__) . '/reflection_php5.php');
17} else {
18    require_once(dirname(__FILE__) . '/reflection_php4.php');
19}
20/**#@-*/
21
22/**
23 * Default character simpletest will substitute for any value
24 */
25if (! defined('MOCK_ANYTHING')) {
26    define('MOCK_ANYTHING', '*');
27}
28
29/**
30 *    Parameter comparison assertion.
31 *    @package SimpleTest
32 *    @subpackage MockObjects
33 */
34class ParametersExpectation extends SimpleExpectation {
35    var $_expected;
36
37    /**
38     *    Sets the expected parameter list.
39     *    @param array $parameters  Array of parameters including
40     *                              those that are wildcarded.
41     *                              If the value is not an array
42     *                              then it is considered to match any.
43     *    @param string $message    Customised message on failure.
44     *    @access public
45     */
46    function ParametersExpectation($expected = false, $message = '%s') {
47        $this->SimpleExpectation($message);
48        $this->_expected = $expected;
49    }
50
51    /**
52     *    Tests the assertion. True if correct.
53     *    @param array $parameters     Comparison values.
54     *    @return boolean              True if correct.
55     *    @access public
56     */
57    function test($parameters) {
58        if (! is_array($this->_expected)) {
59            return true;
60        }
61        if (count($this->_expected) != count($parameters)) {
62            return false;
63        }
64        for ($i = 0; $i < count($this->_expected); $i++) {
65            if (! $this->_testParameter($parameters[$i], $this->_expected[$i])) {
66                return false;
67            }
68        }
69        return true;
70    }
71
72    /**
73     *    Tests an individual parameter.
74     *    @param mixed $parameter    Value to test.
75     *    @param mixed $expected     Comparison value.
76     *    @return boolean            True if expectation
77     *                               fulfilled.
78     *    @access private
79     */
80    function _testParameter($parameter, $expected) {
81        $comparison = $this->_coerceToExpectation($expected);
82        return $comparison->test($parameter);
83    }
84
85    /**
86     *    Returns a human readable test message.
87     *    @param array $comparison   Incoming parameter list.
88     *    @return string             Description of success
89     *                               or failure.
90     *    @access public
91     */
92    function testMessage($parameters) {
93        if ($this->test($parameters)) {
94            return "Expectation of " . count($this->_expected) .
95                    " arguments of [" . $this->_renderArguments($this->_expected) .
96                    "] is correct";
97        } else {
98            return $this->_describeDifference($this->_expected, $parameters);
99        }
100    }
101
102    /**
103     *    Message to display if expectation differs from
104     *    the parameters actually received.
105     *    @param array $expected      Expected parameters as list.
106     *    @param array $parameters    Actual parameters received.
107     *    @return string              Description of difference.
108     *    @access private
109     */
110    function _describeDifference($expected, $parameters) {
111        if (count($expected) != count($parameters)) {
112            return "Expected " . count($expected) .
113                    " arguments of [" . $this->_renderArguments($expected) .
114                    "] but got " . count($parameters) .
115                    " arguments of [" . $this->_renderArguments($parameters) . "]";
116        }
117        $messages = array();
118        for ($i = 0; $i < count($expected); $i++) {
119            $comparison = $this->_coerceToExpectation($expected[$i]);
120            if (! $comparison->test($parameters[$i])) {
121                $messages[] = "parameter " . ($i + 1) . " with [" .
122                        $comparison->overlayMessage($parameters[$i], $this->_getDumper()) . "]";
123            }
124        }
125        return "Parameter expectation differs at " . implode(" and ", $messages);
126    }
127
128    /**
129     *    Creates an identical expectation if the
130     *    object/value is not already some type
131     *    of expectation.
132     *    @param mixed $expected      Expected value.
133     *    @return SimpleExpectation   Expectation object.
134     *    @access private
135     */
136    function _coerceToExpectation($expected) {
137        if (SimpleExpectation::isExpectation($expected)) {
138            return $expected;
139        }
140        return new IdenticalExpectation($expected);
141    }
142
143    /**
144     *    Renders the argument list as a string for
145     *    messages.
146     *    @param array $args    Incoming arguments.
147     *    @return string        Simple description of type and value.
148     *    @access private
149     */
150    function _renderArguments($args) {
151        $descriptions = array();
152        if (is_array($args)) {
153            foreach ($args as $arg) {
154                $dumper = &new SimpleDumper();
155                $descriptions[] = $dumper->describeValue($arg);
156            }
157        }
158        return implode(', ', $descriptions);
159    }
160}
161
162/**
163 *    Confirms that the number of calls on a method is as expected.
164 *  @package    SimpleTest
165 *  @subpackage MockObjects
166 */
167class CallCountExpectation extends SimpleExpectation {
168    var $_method;
169    var $_count;
170
171    /**
172     *    Stashes the method and expected count for later
173     *    reporting.
174     *    @param string $method    Name of method to confirm against.
175     *    @param integer $count    Expected number of calls.
176     *    @param string $message   Custom error message.
177     */
178    function CallCountExpectation($method, $count, $message = '%s') {
179        $this->_method = $method;
180        $this->_count = $count;
181        $this->SimpleExpectation($message);
182    }
183
184    /**
185     *    Tests the assertion. True if correct.
186     *    @param integer $compare     Measured call count.
187     *    @return boolean             True if expected.
188     *    @access public
189     */
190    function test($compare) {
191        return ($this->_count == $compare);
192    }
193
194    /**
195     *    Reports the comparison.
196     *    @param integer $compare     Measured call count.
197     *    @return string              Message to show.
198     *    @access public
199     */
200    function testMessage($compare) {
201        return 'Expected call count for [' . $this->_method .
202                '] was [' . $this->_count .
203                '] got [' . $compare . ']';
204    }
205}
206
207/**
208 *    Confirms that the number of calls on a method is as expected.
209 *  @package    SimpleTest
210 *  @subpackage MockObjects
211 */
212class MinimumCallCountExpectation extends SimpleExpectation {
213    var $_method;
214    var $_count;
215
216    /**
217     *    Stashes the method and expected count for later
218     *    reporting.
219     *    @param string $method    Name of method to confirm against.
220     *    @param integer $count    Minimum number of calls.
221     *    @param string $message   Custom error message.
222     */
223    function MinimumCallCountExpectation($method, $count, $message = '%s') {
224        $this->_method = $method;
225        $this->_count = $count;
226        $this->SimpleExpectation($message);
227    }
228
229    /**
230     *    Tests the assertion. True if correct.
231     *    @param integer $compare     Measured call count.
232     *    @return boolean             True if enough.
233     *    @access public
234     */
235    function test($compare) {
236        return ($this->_count <= $compare);
237    }
238
239    /**
240     *    Reports the comparison.
241     *    @param integer $compare     Measured call count.
242     *    @return string              Message to show.
243     *    @access public
244     */
245    function testMessage($compare) {
246        return 'Minimum call count for [' . $this->_method .
247                '] was [' . $this->_count .
248                '] got [' . $compare . ']';
249    }
250}
251
252/**
253 *    Confirms that the number of calls on a method is as expected.
254 *    @package      SimpleTest
255 *    @subpackage   MockObjects
256 */
257class MaximumCallCountExpectation extends SimpleExpectation {
258    var $_method;
259    var $_count;
260
261    /**
262     *    Stashes the method and expected count for later
263     *    reporting.
264     *    @param string $method    Name of method to confirm against.
265     *    @param integer $count    Minimum number of calls.
266     *    @param string $message   Custom error message.
267     */
268    function MaximumCallCountExpectation($method, $count, $message = '%s') {
269        $this->_method = $method;
270        $this->_count = $count;
271        $this->SimpleExpectation($message);
272    }
273
274    /**
275     *    Tests the assertion. True if correct.
276     *    @param integer $compare     Measured call count.
277     *    @return boolean             True if not over.
278     *    @access public
279     */
280    function test($compare) {
281        return ($this->_count >= $compare);
282    }
283
284    /**
285     *    Reports the comparison.
286     *    @param integer $compare     Measured call count.
287     *    @return string              Message to show.
288     *    @access public
289     */
290    function testMessage($compare) {
291        return 'Maximum call count for [' . $this->_method .
292                '] was [' . $this->_count .
293                '] got [' . $compare . ']';
294    }
295}
296
297/**
298 *    Retrieves method actions by searching the
299 *    parameter lists until an expected match is found.
300 *    @package SimpleTest
301 *    @subpackage MockObjects
302 */
303class SimpleSignatureMap {
304    var $_map;
305
306    /**
307     *    Creates an empty call map.
308     *    @access public
309     */
310    function SimpleSignatureMap() {
311        $this->_map = array();
312    }
313
314    /**
315     *    Stashes a reference against a method call.
316     *    @param array $parameters    Array of arguments (including wildcards).
317     *    @param mixed $action        Reference placed in the map.
318     *    @access public
319     */
320    function add($parameters, &$action) {
321        $place = count($this->_map);
322        $this->_map[$place] = array();
323        $this->_map[$place]['params'] = new ParametersExpectation($parameters);
324        $this->_map[$place]['content'] = &$action;
325    }
326
327    /**
328     *    Searches the call list for a matching parameter
329     *    set. Returned by reference.
330     *    @param array $parameters    Parameters to search by
331     *                                without wildcards.
332     *    @return object              Object held in the first matching
333     *                                slot, otherwise null.
334     *    @access public
335     */
336    function &findFirstAction($parameters) {
337        $slot = $this->_findFirstSlot($parameters);
338        if (isset($slot) && isset($slot['content'])) {
339            return $slot['content'];
340        }
341        $null = null;
342        return $null;
343    }
344
345    /**
346     *    Searches the call list for a matching parameter
347     *    set. True if successful.
348     *    @param array $parameters    Parameters to search by
349     *                                without wildcards.
350     *    @return boolean             True if a match is present.
351     *    @access public
352     */
353    function isMatch($parameters) {
354        return ($this->_findFirstSlot($parameters) != null);
355    }
356   
357    /**
358     *    Compares the incoming parameters with the
359     *    internal expectation. Uses the incoming $test
360     *    to dispatch the test message.
361     *    @param SimpleTestCase $test   Test to dispatch to.
362     *    @param array $parameters      The actual calling arguments.
363     *    @param string $message        The message to overlay.
364     *    @access public
365     */
366    function test(&$test, $parameters, $message) {
367    }
368
369    /**
370     *    Searches the map for a matching item.
371     *    @param array $parameters    Parameters to search by
372     *                                without wildcards.
373     *    @return array               Reference to slot or null.
374     *    @access private
375     */
376    function &_findFirstSlot($parameters) {
377        $count = count($this->_map);
378        for ($i = 0; $i < $count; $i++) {
379            if ($this->_map[$i]["params"]->test($parameters)) {
380                return $this->_map[$i];
381            }
382        }
383        $null = null;
384        return $null;
385    }
386}
387
388/**
389 *    Allows setting of actions against call signatures either
390 *    at a specific time, or always. Specific time settings
391 *    trump lasting ones, otherwise the most recently added
392 *    will mask an earlier match.
393 *    @package SimpleTest
394 *    @subpackage MockObjects
395 */
396class SimpleCallSchedule {
397    var $_wildcard = MOCK_ANYTHING;
398    var $_always;
399    var $_at;
400   
401    /**
402     *    Sets up an empty response schedule.
403     *    Creates an empty call map.
404     */
405    function SimpleCallSchedule() {
406        $this->_always = array();
407        $this->_at = array();
408    }
409   
410    /**
411     *    Stores an action against a signature that
412     *    will always fire unless masked by a time
413     *    specific one.
414     *    @param string $method        Method name.
415     *    @param array $args           Calling parameters.
416     *    @param SimpleAction $action  Actually simpleByValue, etc.
417     *    @access public
418     */
419    function register($method, $args, &$action) {
420        $args = $this->_replaceWildcards($args);
421        $method = strtolower($method);
422        if (! isset($this->_always[$method])) {
423            $this->_always[$method] = new SimpleSignatureMap();
424        }
425        $this->_always[$method]->add($args, $action);
426    }
427   
428    /**
429     *    Stores an action against a signature that
430     *    will fire at a specific time in the future.
431     *    @param integer $step         delay of calls to this method,
432     *                                 0 is next.
433     *    @param string $method        Method name.
434     *    @param array $args           Calling parameters.
435     *    @param SimpleAction $action  Actually SimpleByValue, etc.
436     *    @access public
437     */
438    function registerAt($step, $method, $args, &$action) {
439        $args = $this->_replaceWildcards($args);
440        $method = strtolower($method);
441        if (! isset($this->_at[$method])) {
442            $this->_at[$method] = array();
443        }
444        if (! isset($this->_at[$method][$step])) {
445            $this->_at[$method][$step] = new SimpleSignatureMap();
446        }
447        $this->_at[$method][$step]->add($args, $action);
448    }
449   
450    function expectArguments($method, $args, $message) {
451        $args = $this->_replaceWildcards($args);
452        $message .= Mock::getExpectationLine();
453        $this->_expected_args[strtolower($method)] =
454                new ParametersExpectation($args, $message);
455
456    }
457   
458    /**
459     *    Actually carry out the action stored previously,
460     *    if the parameters match.
461     *    @param integer $step      Time of call.
462     *    @param string $method     Method name.
463     *    @param array $args        The parameters making up the
464     *                              rest of the call.
465     *    @return mixed             The result of the action.
466     *    @access public.
467     */
468    function &respond($step, $method, $args) {
469        $method = strtolower($method);
470        if (isset($this->_at[$method][$step])) {
471            if ($this->_at[$method][$step]->isMatch($args)) {
472                $action = &$this->_at[$method][$step]->findFirstAction($args);
473                if (isset($action)) {
474                    return $action->act();
475                }
476            }
477        }
478        if (isset($this->_always[$method])) {
479            $action = &$this->_always[$method]->findFirstAction($args);
480            if (isset($action)) {
481                return $action->act();
482            }
483        }
484        $null = null;
485        return $null;
486    }
487   
488    /**
489     *    Replaces wildcard matches with wildcard
490     *    expectations in the argument list.
491     *    @param array $args      Raw argument list.
492     *    @return array           Argument list with
493     *                            expectations.
494     *    @access private
495     */
496    function _replaceWildcards($args) {
497        if ($args === false) {
498            return false;
499        }
500        for ($i = 0; $i < count($args); $i++) {
501            if ($args[$i] === $this->_wildcard) {
502                $args[$i] = new AnythingExpectation();
503            }
504        }
505        return $args;
506    }
507}
508
509/**
510 *    A type of SimpleMethodAction.
511 *    Stashes a reference for returning later.
512 *    @package SimpleTest
513 *    @subpackage MockObjects
514 */
515class SimpleByReference {
516    var $_reference;
517   
518    /**
519     *    Stashes it for later.
520     *    @param mixed $reference     Actual PHP4 style reference.
521     *    @access public
522     */
523    function SimpleByReference(&$reference) {
524        $this->_reference = &$reference;
525    }
526   
527    /**
528     *    Returns the reference stored earlier.
529     *    @return mixed    Whatever was stashed.
530     *    @access public
531     */
532    function &act() {
533        return $this->_reference;
534    }
535}
536
537/**
538 *    A type of SimpleMethodAction.
539 *    Stashes a value for returning later.
540 *    @package SimpleTest
541 *    @subpackage MockObjects
542 */
543class SimpleByValue {
544    var $_value;
545   
546    /**
547     *    Stashes it for later.
548     *    @param mixed $value     You need to clone objects
549     *                            if you want copy semantics
550     *                            for these.
551     *    @access public
552     */
553    function SimpleByValue($value) {
554        $this->_value = $value;
555    }
556   
557    /**
558     *    Returns the value stored earlier.
559     *    @return mixed    Whatever was stashed.
560     *    @access public
561     */
562    function &act() {
563        $dummy = $this->_value;
564        return $dummy;
565    }
566}
567
568/**
569 *    A type of SimpleMethodAction.
570 *    Stashes an exception for throwing later.
571 *    @package SimpleTest
572 *    @subpackage MockObjects
573 */
574class SimpleThrower {
575    var $_exception;
576   
577    /**
578     *    Stashes it for later.
579     *    @param Exception $exception    The exception object to throw.
580     *    @access public
581     */
582    function SimpleThrower($exception) {
583        $this->_exception = $exception;
584    }
585   
586    /**
587     *    Throws the exceptins stashed earlier.
588     *    @access public
589     */
590    function act() {
591        eval('throw $this->_exception;');
592    }
593}
594
595/**
596 *    A type of SimpleMethodAction.
597 *    Stashes an error for emitting later.
598 *    @package SimpleTest
599 *    @subpackage MockObjects
600 */
601class SimpleErrorThrower {
602    var $_error;
603    var $_severity;
604   
605    /**
606     *    Stashes an error to throw later.
607     *    @param string $error      Error message.
608     *    @param integer $severity  PHP error constant, e.g E_USER_ERROR.
609     *    @access public
610     */
611    function SimpleErrorThrower($error, $severity) {
612        $this->_error = $error;
613        $this->_severity = $severity;
614    }
615   
616    /**
617     *    Triggers the stashed error.
618     *    @return null        The usual PHP4.4 shenanigans are needed here.
619     *    @access public
620     */
621    function &act() {
622        trigger_error($this->_error, $this->_severity);
623        $null = null;
624        return $null;
625    }
626}
627
628/**
629 *    A base class or delegate that extends an
630 *    empty collection of methods that can have their
631 *    return values set and expectations made of the
632 *    calls upon them. The mock will assert the
633 *    expectations against it's attached test case in
634 *    addition to the server stub behaviour or returning
635 *    preprogrammed responses.
636 *    @package SimpleTest
637 *    @subpackage MockObjects
638 */
639class SimpleMock {
640    var $_actions;
641    var $_wildcard = MOCK_ANYTHING;
642    var $_is_strict = true;
643    var $_call_counts;
644    var $_expected_counts;
645    var $_max_counts;
646    var $_expected_args;
647    var $_expected_args_at;
648
649    /**
650     *    Creates an empty action list and expectation list.
651     *    All call counts are set to zero.
652     *    @access public
653     */
654    function SimpleMock() {
655        $this->_actions = &new SimpleCallSchedule();
656        $this->_expectations = &new SimpleCallSchedule();
657        $this->_call_counts = array();
658        $this->_expected_counts = array();
659        $this->_max_counts = array();
660        $this->_expected_args = array();
661        $this->_expected_args_at = array();
662        $test = &$this->_getCurrentTestCase();
663        $test->tell($this);
664    }
665   
666    /**
667     *    Disables a name check when setting expectations.
668     *    This hack is needed for the partial mocks.
669     *    @access public
670     */
671    function disableExpectationNameChecks() {
672        $this->_is_strict = false;
673    }
674
675    /**
676     *    Finds currently running test.
677     *    @return SimpeTestCase    Current test case.
678     *    @access protected
679     */
680    function &_getCurrentTestCase() {
681        $context = &SimpleTest::getContext();
682        return $context->getTest();
683    }
684
685    /**
686     *    Die if bad arguments array is passed.
687     *    @param mixed $args     The arguments value to be checked.
688     *    @param string $task    Description of task attempt.
689     *    @return boolean        Valid arguments
690     *    @access private
691     */
692    function _checkArgumentsIsArray($args, $task) {
693        if (! is_array($args)) {
694            trigger_error(
695                "Cannot $task as \$args parameter is not an array",
696                E_USER_ERROR);
697        }
698    }
699
700    /**
701     *    Triggers a PHP error if the method is not part
702     *    of this object.
703     *    @param string $method        Name of method.
704     *    @param string $task          Description of task attempt.
705     *    @access protected
706     */
707    function _dieOnNoMethod($method, $task) {
708        if ($this->_is_strict && ! method_exists($this, $method)) {
709            trigger_error(
710                    "Cannot $task as no ${method}() in class " . get_class($this),
711                    E_USER_ERROR);
712        }
713    }
714
715    /**
716     *    Replaces wildcard matches with wildcard
717     *    expectations in the argument list.
718     *    @param array $args      Raw argument list.
719     *    @return array           Argument list with
720     *                            expectations.
721     *    @access private
722     */
723    function _replaceWildcards($args) {
724        if ($args === false) {
725            return false;
726        }
727        for ($i = 0; $i < count($args); $i++) {
728            if ($args[$i] === $this->_wildcard) {
729                $args[$i] = new AnythingExpectation();
730            }
731        }
732        return $args;
733    }
734
735    /**
736     *    Adds one to the call count of a method.
737     *    @param string $method        Method called.
738     *    @param array $args           Arguments as an array.
739     *    @access protected
740     */
741    function _addCall($method, $args) {
742        if (! isset($this->_call_counts[$method])) {
743            $this->_call_counts[$method] = 0;
744        }
745        $this->_call_counts[$method]++;
746    }
747
748    /**
749     *    Fetches the call count of a method so far.
750     *    @param string $method        Method name called.
751     *    @return integer              Number of calls so far.
752     *    @access public
753     */
754    function getCallCount($method) {
755        $this->_dieOnNoMethod($method, "get call count");
756        $method = strtolower($method);
757        if (! isset($this->_call_counts[$method])) {
758            return 0;
759        }
760        return $this->_call_counts[$method];
761    }
762
763    /**
764     *    Sets a return for a parameter list that will
765     *    be passed by value for all calls to this method.
766     *    @param string $method       Method name.
767     *    @param mixed $value         Result of call passed by value.
768     *    @param array $args          List of parameters to match
769     *                                including wildcards.
770     *    @access public
771     */
772    function setReturnValue($method, $value, $args = false) {
773        $this->_dieOnNoMethod($method, "set return value");
774        $this->_actions->register($method, $args, new SimpleByValue($value));
775    }
776
777    /**
778     *    Sets a return for a parameter list that will
779     *    be passed by value only when the required call count
780     *    is reached.
781     *    @param integer $timing   Number of calls in the future
782     *                             to which the result applies. If
783     *                             not set then all calls will return
784     *                             the value.
785     *    @param string $method    Method name.
786     *    @param mixed $value      Result of call passed by value.
787     *    @param array $args       List of parameters to match
788     *                             including wildcards.
789     *    @access public
790     */
791    function setReturnValueAt($timing, $method, $value, $args = false) {
792        $this->_dieOnNoMethod($method, "set return value sequence");
793        $this->_actions->registerAt($timing, $method, $args, new SimpleByValue($value));
794    }
795
796    /**
797     *    Sets a return for a parameter list that will
798     *    be passed by reference for all calls.
799     *    @param string $method       Method name.
800     *    @param mixed $reference     Result of the call will be this object.
801     *    @param array $args          List of parameters to match
802     *                                including wildcards.
803     *    @access public
804     */
805    function setReturnReference($method, &$reference, $args = false) {
806        $this->_dieOnNoMethod($method, "set return reference");
807        $this->_actions->register($method, $args, new SimpleByReference($reference));
808    }
809
810    /**
811     *    Sets a return for a parameter list that will
812     *    be passed by value only when the required call count
813     *    is reached.
814     *    @param integer $timing    Number of calls in the future
815     *                              to which the result applies. If
816     *                              not set then all calls will return
817     *                              the value.
818     *    @param string $method     Method name.
819     *    @param mixed $reference   Result of the call will be this object.
820     *    @param array $args        List of parameters to match
821     *                              including wildcards.
822     *    @access public
823     */
824    function setReturnReferenceAt($timing, $method, &$reference, $args = false) {
825        $this->_dieOnNoMethod($method, "set return reference sequence");
826        $this->_actions->registerAt($timing, $method, $args, new SimpleByReference($reference));
827    }
828
829    /**
830     *    Sets up an expected call with a set of
831     *    expected parameters in that call. All
832     *    calls will be compared to these expectations
833     *    regardless of when the call is made.
834     *    @param string $method        Method call to test.
835     *    @param array $args           Expected parameters for the call
836     *                                 including wildcards.
837     *    @param string $message       Overridden message.
838     *    @access public
839     */
840    function expect($method, $args, $message = '%s') {
841        $this->_dieOnNoMethod($method, 'set expected arguments');
842        $this->_checkArgumentsIsArray($args, 'set expected arguments');
843        $this->_expectations->expectArguments($method, $args, $message);
844        $args = $this->_replaceWildcards($args);
845        $message .= Mock::getExpectationLine();
846        $this->_expected_args[strtolower($method)] =
847                new ParametersExpectation($args, $message);
848    }
849
850    /**
851     *    @deprecated
852     */
853    function expectArguments($method, $args, $message = '%s') {
854        return $this->expect($method, $args, $message);
855    }
856
857    /**
858     *    Sets up an expected call with a set of
859     *    expected parameters in that call. The
860     *    expected call count will be adjusted if it
861     *    is set too low to reach this call.
862     *    @param integer $timing    Number of calls in the future at
863     *                              which to test. Next call is 0.
864     *    @param string $method     Method call to test.
865     *    @param array $args        Expected parameters for the call
866     *                              including wildcards.
867     *    @param string $message    Overridden message.
868     *    @access public
869     */
870    function expectAt($timing, $method, $args, $message = '%s') {
871        $this->_dieOnNoMethod($method, 'set expected arguments at time');
872        $this->_checkArgumentsIsArray($args, 'set expected arguments at time');
873        $args = $this->_replaceWildcards($args);
874        if (! isset($this->_expected_args_at[$timing])) {
875            $this->_expected_args_at[$timing] = array();
876        }
877        $method = strtolower($method);
878        $message .= Mock::getExpectationLine();
879        $this->_expected_args_at[$timing][$method] =
880                new ParametersExpectation($args, $message);
881    }
882
883    /**
884     *    @deprecated
885     */
886    function expectArgumentsAt($timing, $method, $args, $message = '%s') {
887        return $this->expectAt($timing, $method, $args, $message);
888    }
889
890    /**
891     *    Sets an expectation for the number of times
892     *    a method will be called. The tally method
893     *    is used to check this.
894     *    @param string $method        Method call to test.
895     *    @param integer $count        Number of times it should
896     *                                 have been called at tally.
897     *    @param string $message       Overridden message.
898     *    @access public
899     */
900    function expectCallCount($method, $count, $message = '%s') {
901        $this->_dieOnNoMethod($method, 'set expected call count');
902        $message .= Mock::getExpectationLine();
903        $this->_expected_counts[strtolower($method)] =
904                new CallCountExpectation($method, $count, $message);
905    }
906
907    /**
908     *    Sets the number of times a method may be called
909     *    before a test failure is triggered.
910     *    @param string $method        Method call to test.
911     *    @param integer $count        Most number of times it should
912     *                                 have been called.
913     *    @param string $message       Overridden message.
914     *    @access public
915     */
916    function expectMaximumCallCount($method, $count, $message = '%s') {
917        $this->_dieOnNoMethod($method, 'set maximum call count');
918        $message .= Mock::getExpectationLine();
919        $this->_max_counts[strtolower($method)] =
920                new MaximumCallCountExpectation($method, $count, $message);
921    }
922
923    /**
924     *    Sets the number of times to call a method to prevent
925     *    a failure on the tally.
926     *    @param string $method      Method call to test.
927     *    @param integer $count      Least number of times it should
928     *                               have been called.
929     *    @param string $message     Overridden message.
930     *    @access public
931     */
932    function expectMinimumCallCount($method, $count, $message = '%s') {
933        $this->_dieOnNoMethod($method, 'set minimum call count');
934        $message .= Mock::getExpectationLine();
935        $this->_expected_counts[strtolower($method)] =
936                new MinimumCallCountExpectation($method, $count, $message);
937    }
938
939    /**
940     *    Convenience method for barring a method
941     *    call.
942     *    @param string $method        Method call to ban.
943     *    @param string $message       Overridden message.
944     *    @access public
945     */
946    function expectNever($method, $message = '%s') {
947        $this->expectMaximumCallCount($method, 0, $message);
948    }
949
950    /**
951     *    Convenience method for a single method
952     *    call.
953     *    @param string $method     Method call to track.
954     *    @param array $args        Expected argument list or
955     *                              false for any arguments.
956     *    @param string $message    Overridden message.
957     *    @access public
958     */
959    function expectOnce($method, $args = false, $message = '%s') {
960        $this->expectCallCount($method, 1, $message);
961        if ($args !== false) {
962            $this->expect($method, $args, $message);
963        }
964    }
965
966    /**
967     *    Convenience method for requiring a method
968     *    call.
969     *    @param string $method       Method call to track.
970     *    @param array $args          Expected argument list or
971     *                                false for any arguments.
972     *    @param string $message      Overridden message.
973     *    @access public
974     */
975    function expectAtLeastOnce($method, $args = false, $message = '%s') {
976        $this->expectMinimumCallCount($method, 1, $message);
977        if ($args !== false) {
978            $this->expect($method, $args, $message);
979        }
980    }
981   
982    /**
983     *    Sets up a trigger to throw an exception upon the
984     *    method call.
985     *    @param string $method     Method name to throw on.
986     */
987    function throwOn($method, $exception = false, $args = false) {
988        $this->_dieOnNoMethod($method, "throw on");
989        $this->_actions->register($method, $args,
990                new SimpleThrower($exception ? $exception : new Exception()));
991    }
992   
993    /**
994     *    Sets up a trigger to throw an exception upon the
995     *    method call.
996     */
997    function throwAt($timing, $method, $exception = false, $args = false) {
998        $this->_dieOnNoMethod($method, "throw at");
999        $this->_actions->registerAt($timing, $method, $args,
1000                new SimpleThrower($exception ? $exception : new Exception()));
1001    }
1002   
1003    /**
1004     *    Sets up a trigger to throw an error upon the
1005     *    method call.
1006     */
1007    function errorOn($method, $error = 'A mock error', $args = false, $severity = E_USER_ERROR) {
1008        $this->_dieOnNoMethod($method, "error on");
1009        $this->_actions->register($method, $args, new SimpleErrorThrower($error, $severity));
1010    }
1011   
1012    /**
1013     *    Sets up a trigger to throw an error upon the
1014     *    method call.
1015     */
1016    function errorAt($timing, $method, $error = 'A mock error', $args = false, $severity = E_USER_ERROR) {
1017        $this->_dieOnNoMethod($method, "error at");
1018        $this->_actions->registerAt($timing, $method, $args, new SimpleErrorThrower($error, $severity));
1019    }
1020
1021    /**
1022     *    @deprecated
1023     */
1024    function tally() {
1025    }
1026
1027    /**
1028     *    Receives event from unit test that the current
1029     *    test method has finished. Totals up the call
1030     *    counts and triggers a test assertion if a test
1031     *    is present for expected call counts.
1032     *    @param string $test_method      Current method name.
1033     *    @param SimpleTestCase $test     Test to send message to.
1034     *    @access public
1035     */
1036    function atTestEnd($test_method, &$test) {
1037        foreach ($this->_expected_counts as $method => $expectation) {
1038            $test->assert($expectation, $this->getCallCount($method));
1039        }
1040        foreach ($this->_max_counts as $method => $expectation) {
1041            if ($expectation->test($this->getCallCount($method))) {
1042                $test->assert($expectation, $this->getCallCount($method));
1043            }
1044        }
1045    }
1046
1047    /**
1048     *    Returns the expected value for the method name
1049     *    and checks expectations. Will generate any
1050     *    test assertions as a result of expectations
1051     *    if there is a test present.
1052     *    @param string $method       Name of method to simulate.
1053     *    @param array $args          Arguments as an array.
1054     *    @return mixed               Stored return.
1055     *    @access private
1056     */
1057    function &_invoke($method, $args) {
1058        $method = strtolower($method);
1059        $step = $this->getCallCount($method);
1060        $this->_addCall($method, $args);
1061        $this->_checkExpectations($method, $args, $step);
1062        $result = &$this->_emulateCall($method, $args, $step);
1063        return $result;
1064    }
1065   
1066    /**
1067     *    Finds the return value matching the incoming
1068     *    arguments. If there is no matching value found
1069     *    then an error is triggered.
1070     *    @param string $method      Method name.
1071     *    @param array $args         Calling arguments.
1072     *    @param integer $step       Current position in the
1073     *                               call history.
1074     *    @return mixed              Stored return or other action.
1075     *    @access protected
1076     */
1077    function &_emulateCall($method, $args, $step) {
1078        return $this->_actions->respond($step, $method, $args);
1079    }
1080
1081    /**
1082     *    Tests the arguments against expectations.
1083     *    @param string $method        Method to check.
1084     *    @param array $args           Argument list to match.
1085     *    @param integer $timing       The position of this call
1086     *                                 in the call history.
1087     *    @access private
1088     */
1089    function _checkExpectations($method, $args, $timing) {
1090        $test = &$this->_getCurrentTestCase();
1091        if (isset($this->_max_counts[$method])) {
1092            if (! $this->_max_counts[$method]->test($timing + 1)) {
1093                $test->assert($this->_max_counts[$method], $timing + 1);
1094            }
1095        }
1096        if (isset($this->_expected_args_at[$timing][$method])) {
1097            $test->assert(
1098                    $this->_expected_args_at[$timing][$method],
1099                    $args,
1100                    "Mock method [$method] at [$timing] -> %s");
1101        } elseif (isset($this->_expected_args[$method])) {
1102            $test->assert(
1103                    $this->_expected_args[$method],
1104                    $args,
1105                    "Mock method [$method] -> %s");
1106        }
1107    }
1108}
1109
1110/**
1111 *    Static methods only service class for code generation of
1112 *    mock objects.
1113 *    @package SimpleTest
1114 *    @subpackage MockObjects
1115 */
1116class Mock {
1117
1118    /**
1119     *    Factory for mock object classes.
1120     *    @access public
1121     */
1122    function Mock() {
1123        trigger_error('Mock factory methods are static.');
1124    }
1125
1126    /**
1127     *    Clones a class' interface and creates a mock version
1128     *    that can have return values and expectations set.
1129     *    @param string $class         Class to clone.
1130     *    @param string $mock_class    New class name. Default is
1131     *                                 the old name with "Mock"
1132     *                                 prepended.
1133     *    @param array $methods        Additional methods to add beyond
1134     *                                 those in the cloned class. Use this
1135     *                                 to emulate the dynamic addition of
1136     *                                 methods in the cloned class or when
1137     *                                 the class hasn't been written yet.
1138     *    @static
1139     *    @access public
1140     */
1141    function generate($class, $mock_class = false, $methods = false) {
1142        $generator = new MockGenerator($class, $mock_class);
1143        return $generator->generateSubclass($methods);
1144    }
1145
1146    /**
1147     *    Generates a version of a class with selected
1148     *    methods mocked only. Inherits the old class
1149     *    and chains the mock methods of an aggregated
1150     *    mock object.
1151     *    @param string $class            Class to clone.
1152     *    @param string $mock_class       New class name.
1153     *    @param array $methods           Methods to be overridden
1154     *                                    with mock versions.
1155     *    @static
1156     *    @access public
1157     */
1158    function generatePartial($class, $mock_class, $methods) {
1159        $generator = new MockGenerator($class, $mock_class);
1160        return $generator->generatePartial($methods);
1161    }
1162
1163    /**
1164     *    Uses a stack trace to find the line of an assertion.
1165     *    @access public
1166     *    @static
1167     */
1168    function getExpectationLine() {
1169        $trace = new SimpleStackTrace(array('expect'));
1170        return $trace->traceMethod();
1171    }
1172}
1173
1174/**
1175 *    @package  SimpleTest
1176 *    @subpackage   MockObjects
1177 *    @deprecated
1178 */
1179class Stub extends Mock {
1180}
1181
1182/**
1183 *    Service class for code generation of mock objects.
1184 *    @package SimpleTest
1185 *    @subpackage MockObjects
1186 */
1187class MockGenerator {
1188    var $_class;
1189    var $_mock_class;
1190    var $_mock_base;
1191    var $_reflection;
1192
1193    /**
1194     *    Builds initial reflection object.
1195     *    @param string $class        Class to be mocked.
1196     *    @param string $mock_class   New class with identical interface,
1197     *                                but no behaviour.
1198     */
1199    function MockGenerator($class, $mock_class) {
1200        $this->_class = $class;
1201        $this->_mock_class = $mock_class;
1202        if (! $this->_mock_class) {
1203            $this->_mock_class = 'Mock' . $this->_class;
1204        }
1205        $this->_mock_base = SimpleTest::getMockBaseClass();
1206        $this->_reflection = new SimpleReflection($this->_class);
1207    }
1208
1209    /**
1210     *    Clones a class' interface and creates a mock version
1211     *    that can have return values and expectations set.
1212     *    @param array $methods        Additional methods to add beyond
1213     *                                 those in th cloned class. Use this
1214     *                                 to emulate the dynamic addition of
1215     *                                 methods in the cloned class or when
1216     *                                 the class hasn't been written yet.
1217     *    @access public
1218     */
1219    function generate($methods) {
1220        if (! $this->_reflection->classOrInterfaceExists()) {
1221            return false;
1222        }
1223        $mock_reflection = new SimpleReflection($this->_mock_class);
1224        if ($mock_reflection->classExistsSansAutoload()) {
1225            return false;
1226        }
1227        $code = $this->_createClassCode($methods ? $methods : array());
1228        return eval("$code return \$code;");
1229    }
1230   
1231    /**
1232     *    Subclasses a class and overrides every method with a mock one
1233     *    that can have return values and expectations set. Chains
1234     *    to an aggregated SimpleMock.
1235     *    @param array $methods        Additional methods to add beyond
1236     *                                 those in the cloned class. Use this
1237     *                                 to emulate the dynamic addition of
1238     *                                 methods in the cloned class or when
1239     *                                 the class hasn't been written yet.
1240     *    @access public
1241     */
1242    function generateSubclass($methods) {
1243        if (! $this->_reflection->classOrInterfaceExists()) {
1244            return false;
1245        }
1246        $mock_reflection = new SimpleReflection($this->_mock_class);
1247        if ($mock_reflection->classExistsSansAutoload()) {
1248            return false;
1249        }
1250        if ($this->_reflection->isInterface() || $this->_reflection->hasFinal()) {
1251            $code = $this->_createClassCode($methods ? $methods : array());
1252            return eval("$code return \$code;");
1253        } else {
1254            $code = $this->_createSubclassCode($methods ? $methods : array());
1255            return eval("$code return \$code;");
1256        }
1257    }
1258
1259    /**
1260     *    Generates a version of a class with selected
1261     *    methods mocked only. Inherits the old class
1262     *    and chains the mock methods of an aggregated
1263     *    mock object.
1264     *    @param array $methods           Methods to be overridden
1265     *                                    with mock versions.
1266     *    @access public
1267     */
1268    function generatePartial($methods) {
1269        if (! $this->_reflection->classExists($this->_class)) {
1270            return false;
1271        }
1272        $mock_reflection = new SimpleReflection($this->_mock_class);
1273        if ($mock_reflection->classExistsSansAutoload()) {
1274            trigger_error('Partial mock class [' . $this->_mock_class . '] already exists');
1275            return false;
1276        }
1277        $code = $this->_extendClassCode($methods);
1278        return eval("$code return \$code;");
1279    }
1280
1281    /**
1282     *    The new mock class code as a string.
1283     *    @param array $methods          Additional methods.
1284     *    @return string                 Code for new mock class.
1285     *    @access private
1286     */
1287    function _createClassCode($methods) {
1288        $implements = '';
1289        $interfaces = $this->_reflection->getInterfaces();
1290        if (function_exists('spl_classes')) {
1291            $interfaces = array_diff($interfaces, array('Traversable'));
1292        }
1293        if (count($interfaces) > 0) {
1294            $implements = 'implements ' . implode(', ', $interfaces);
1295        }
1296        $code = "class " . $this->_mock_class . " extends " . $this->_mock_base . " $implements {\n";
1297        $code .= "    function " . $this->_mock_class . "() {\n";
1298        $code .= "        \$this->" . $this->_mock_base . "();\n";
1299        $code .= "    }\n";
1300        if (in_array('__construct', $this->_reflection->getMethods())) {
1301            $code .= "    " . $this->_reflection->getSignature('__construct') . " {\n";
1302            $code .= "        \$this->" . $this->_mock_base . "();\n";
1303            $code .= "    }\n";
1304        }
1305        $code .= $this->_createHandlerCode($methods);
1306        $code .= "}\n";
1307        return $code;
1308    }
1309
1310    /**
1311     *    The new mock class code as a string. The mock will
1312     *    be a subclass of the original mocked class.
1313     *    @param array $methods          Additional methods.
1314     *    @return string                 Code for new mock class.
1315     *    @access private
1316     */
1317    function _createSubclassCode($methods) {
1318        $code  = "class " . $this->_mock_class . " extends " . $this->_class . " {\n";
1319        $code .= "    var \$_mock;\n";
1320        $code .= $this->_addMethodList(array_merge($methods, $this->_reflection->getMethods()));
1321        $code .= "\n";
1322        $code .= "    function " . $this->_mock_class . "() {\n";
1323        $code .= "        \$this->_mock = &new " . $this->_mock_base . "();\n";
1324        $code .= "        \$this->_mock->disableExpectationNameChecks();\n";
1325        $code .= "    }\n";
1326        $code .= $this->_chainMockReturns();
1327        $code .= $this->_chainMockExpectations();
1328        $code .= $this->_chainThrowMethods();
1329        $code .= $this->_overrideMethods($this->_reflection->getMethods());
1330        $code .= $this->_createNewMethodCode($methods);
1331        $code .= "}\n";
1332        return $code;
1333    }
1334
1335    /**
1336     *    The extension class code as a string. The class
1337     *    composites a mock object and chains mocked methods
1338     *    to it.
1339     *    @param array  $methods       Mocked methods.
1340     *    @return string               Code for a new class.
1341     *    @access private
1342     */
1343    function _extendClassCode($methods) {
1344        $code  = "class " . $this->_mock_class . " extends " . $this->_class . " {\n";
1345        $code .= "    var \$_mock;\n";
1346        $code .= $this->_addMethodList($methods);
1347        $code .= "\n";
1348        $code .= "    function " . $this->_mock_class . "() {\n";
1349        $code .= "        \$this->_mock = &new " . $this->_mock_base . "();\n";
1350        $code .= "        \$this->_mock->disableExpectationNameChecks();\n";
1351        $code .= "    }\n";
1352        $code .= $this->_chainMockReturns();
1353        $code .= $this->_chainMockExpectations();
1354        $code .= $this->_chainThrowMethods();
1355        $code .= $this->_overrideMethods($methods);
1356        $code .= "}\n";
1357        return $code;
1358    }
1359
1360    /**
1361     *    Creates code within a class to generate replaced
1362     *    methods. All methods call the _invoke() handler
1363     *    with the method name and the arguments in an
1364     *    array.
1365     *    @param array $methods    Additional methods.
1366     *    @access private
1367     */
1368    function _createHandlerCode($methods) {
1369        $code = '';
1370        $methods = array_merge($methods, $this->_reflection->getMethods());
1371        foreach ($methods as $method) {
1372            if ($this->_isConstructor($method)) {
1373                continue;
1374            }
1375            $mock_reflection = new SimpleReflection($this->_mock_base);
1376            if (in_array($method, $mock_reflection->getMethods())) {
1377                continue;
1378            }
1379            $code .= "    " . $this->_reflection->getSignature($method) . " {\n";
1380            $code .= "        \$args = func_get_args();\n";
1381            $code .= "        \$result = &\$this->_invoke(\"$method\", \$args);\n";
1382            $code .= "        return \$result;\n";
1383            $code .= "    }\n";
1384        }
1385        return $code;
1386    }
1387
1388    /**
1389     *    Creates code within a class to generate a new
1390     *    methods. All methods call the _invoke() handler
1391     *    on the internal mock with the method name and
1392     *    the arguments in an array.
1393     *    @param array $methods    Additional methods.
1394     *    @access private
1395     */
1396    function _createNewMethodCode($methods) {
1397        $code = '';
1398        foreach ($methods as $method) {
1399            if ($this->_isConstructor($method)) {
1400                continue;
1401            }
1402            $mock_reflection = new SimpleReflection($this->_mock_base);
1403            if (in_array($method, $mock_reflection->getMethods())) {
1404                continue;
1405            }
1406            $code .= "    " . $this->_reflection->getSignature($method) . " {\n";
1407            $code .= "        \$args = func_get_args();\n";
1408            $code .= "        \$result = &\$this->_mock->_invoke(\"$method\", \$args);\n";
1409            $code .= "        return \$result;\n";
1410            $code .= "    }\n";
1411        }
1412        return $code;
1413    }
1414
1415    /**
1416     *    Tests to see if a special PHP method is about to
1417     *    be stubbed by mistake.
1418     *    @param string $method    Method name.
1419     *    @return boolean          True if special.
1420     *    @access private
1421     */
1422    function _isConstructor($method) {
1423        return in_array(
1424                strtolower($method),
1425                array('__construct', '__destruct'));
1426    }
1427
1428    /**
1429     *    Creates a list of mocked methods for error checking.
1430     *    @param array $methods       Mocked methods.
1431     *    @return string              Code for a method list.
1432     *    @access private
1433     */
1434    function _addMethodList($methods) {
1435        return "    var \$_mocked_methods = array('" .
1436                implode("', '", array_map('strtolower', $methods)) .
1437                "');\n";
1438    }
1439
1440    /**
1441     *    Creates code to abandon the expectation if not mocked.
1442     *    @param string $alias       Parameter name of method name.
1443     *    @return string             Code for bail out.
1444     *    @access private
1445     */
1446    function _bailOutIfNotMocked($alias) {
1447        $code  = "        if (! in_array(strtolower($alias), \$this->_mocked_methods)) {\n";
1448        $code .= "            trigger_error(\"Method [$alias] is not mocked\");\n";
1449        $code .= "            \$null = null;\n";
1450        $code .= "            return \$null;\n";
1451        $code .= "        }\n";
1452        return $code;
1453    }
1454
1455    /**
1456     *    Creates source code for chaining to the composited
1457     *    mock object.
1458     *    @return string           Code for mock set up.
1459     *    @access private
1460     */
1461    function _chainMockReturns() {
1462        $code  = "    function setReturnValue(\$method, \$value, \$args = false) {\n";
1463        $code .= $this->_bailOutIfNotMocked("\$method");
1464        $code .= "        \$this->_mock->setReturnValue(\$method, \$value, \$args);\n";
1465        $code .= "    }\n";
1466        $code .= "    function setReturnValueAt(\$timing, \$method, \$value, \$args = false) {\n";
1467        $code .= $this->_bailOutIfNotMocked("\$method");
1468        $code .= "        \$this->_mock->setReturnValueAt(\$timing, \$method, \$value, \$args);\n";
1469        $code .= "    }\n";
1470        $code .= "    function setReturnReference(\$method, &\$ref, \$args = false) {\n";
1471        $code .= $this->_bailOutIfNotMocked("\$method");
1472        $code .= "        \$this->_mock->setReturnReference(\$method, \$ref, \$args);\n";
1473        $code .= "    }\n";
1474        $code .= "    function setReturnReferenceAt(\$timing, \$method, &\$ref, \$args = false) {\n";
1475        $code .= $this->_bailOutIfNotMocked("\$method");
1476        $code .= "        \$this->_mock->setReturnReferenceAt(\$timing, \$method, \$ref, \$args);\n";
1477        $code .= "    }\n";
1478        return $code;
1479    }
1480
1481    /**
1482     *    Creates source code for chaining to an aggregated
1483     *    mock object.
1484     *    @return string                 Code for expectations.
1485     *    @access private
1486     */
1487    function _chainMockExpectations() {
1488        $code  = "    function expect(\$method, \$args = false, \$msg = '%s') {\n";
1489        $code .= $this->_bailOutIfNotMocked("\$method");
1490        $code .= "        \$this->_mock->expect(\$method, \$args, \$msg);\n";
1491        $code .= "    }\n";
1492        $code .= "    function expectArguments(\$method, \$args = false, \$msg = '%s') {\n";
1493        $code .= $this->_bailOutIfNotMocked("\$method");
1494        $code .= "        \$this->_mock->expectArguments(\$method, \$args, \$msg);\n";
1495        $code .= "    }\n";
1496        $code .= "    function expectAt(\$timing, \$method, \$args = false, \$msg = '%s') {\n";
1497        $code .= $this->_bailOutIfNotMocked("\$method");
1498        $code .= "        \$this->_mock->expectArgumentsAt(\$timing, \$method, \$args, \$msg);\n";
1499        $code .= "    }\n";
1500        $code .= "    function expectArgumentsAt(\$timing, \$method, \$args = false, \$msg = '%s') {\n";
1501        $code .= $this->_bailOutIfNotMocked("\$method");
1502        $code .= "        \$this->_mock->expectArgumentsAt(\$timing, \$method, \$args, \$msg);\n";
1503        $code .= "    }\n";
1504        $code .= "    function expectCallCount(\$method, \$count) {\n";
1505        $code .= $this->_bailOutIfNotMocked("\$method");
1506        $code .= "        \$this->_mock->expectCallCount(\$method, \$count, \$msg = '%s');\n";
1507        $code .= "    }\n";
1508        $code .= "    function expectMaximumCallCount(\$method, \$count, \$msg = '%s') {\n";
1509        $code .= $this->_bailOutIfNotMocked("\$method");
1510        $code .= "        \$this->_mock->expectMaximumCallCount(\$method, \$count, \$msg = '%s');\n";
1511        $code .= "    }\n";
1512        $code .= "    function expectMinimumCallCount(\$method, \$count, \$msg = '%s') {\n";
1513        $code .= $this->_bailOutIfNotMocked("\$method");
1514        $code .= "        \$this->_mock->expectMinimumCallCount(\$method, \$count, \$msg = '%s');\n";
1515        $code .= "    }\n";
1516        $code .= "    function expectNever(\$method) {\n";
1517        $code .= $this->_bailOutIfNotMocked("\$method");
1518        $code .= "        \$this->_mock->expectNever(\$method);\n";
1519        $code .= "    }\n";
1520        $code .= "    function expectOnce(\$method, \$args = false, \$msg = '%s') {\n";
1521        $code .= $this->_bailOutIfNotMocked("\$method");
1522        $code .= "        \$this->_mock->expectOnce(\$method, \$args, \$msg);\n";
1523        $code .= "    }\n";
1524        $code .= "    function expectAtLeastOnce(\$method, \$args = false, \$msg = '%s') {\n";
1525        $code .= $this->_bailOutIfNotMocked("\$method");
1526        $code .= "        \$this->_mock->expectAtLeastOnce(\$method, \$args, \$msg);\n";
1527        $code .= "    }\n";
1528        $code .= "    function tally() {\n";
1529        $code .= "    }\n";
1530        return $code;
1531    }
1532   
1533    /**
1534     *    Adds code for chaining the throw methods.
1535     *    @return string           Code for chains.
1536     *    @access private
1537     */
1538    function _chainThrowMethods() {
1539        $code  = "    function throwOn(\$method, \$exception = false, \$args = false) {\n";
1540        $code .= $this->_bailOutIfNotMocked("\$method");
1541        $code .= "        \$this->_mock->throwOn(\$method, \$exception, \$args);\n";
1542        $code .= "    }\n";
1543        $code .= "    function throwAt(\$timing, \$method, \$exception = false, \$args = false) {\n";
1544        $code .= $this->_bailOutIfNotMocked("\$method");
1545        $code .= "        \$this->_mock->throwAt(\$timing, \$method, \$exception, \$args);\n";
1546        $code .= "    }\n";
1547        $code .= "    function errorOn(\$method, \$error = 'A mock error', \$args = false, \$severity = E_USER_ERROR) {\n";
1548        $code .= $this->_bailOutIfNotMocked("\$method");
1549        $code .= "        \$this->_mock->errorOn(\$method, \$error, \$args, \$severity);\n";
1550        $code .= "    }\n";
1551        $code .= "    function errorAt(\$timing, \$method, \$error = 'A mock error', \$args = false, \$severity = E_USER_ERROR) {\n";
1552        $code .= $this->_bailOutIfNotMocked("\$method");
1553        $code .= "        \$this->_mock->errorAt(\$timing, \$method, \$error, \$args, \$severity);\n";
1554        $code .= "    }\n";
1555        return $code;
1556    }
1557
1558    /**
1559     *    Creates source code to override a list of methods
1560     *    with mock versions.
1561     *    @param array $methods    Methods to be overridden
1562     *                             with mock versions.
1563     *    @return string           Code for overridden chains.
1564     *    @access private
1565     */
1566    function _overrideMethods($methods) {
1567        $code = "";
1568        foreach ($methods as $method) {
1569            if ($this->_isConstructor($method)) {
1570                continue;
1571            }
1572            $code .= "    " . $this->_reflection->getSignature($method) . " {\n";
1573            $code .= "        \$args = func_get_args();\n";
1574            $code .= "        \$result = &\$this->_mock->_invoke(\"$method\", \$args);\n";
1575            $code .= "        return \$result;\n";
1576            $code .= "    }\n";
1577        }
1578        return $code;
1579    }
1580}
1581?>
Note: See TracBrowser for help on using the repository browser.