1<?php
2/*
3 * This file is part of the PHPUnit_MockObject package.
4 *
5 * (c) Sebastian Bergmann <sebastian@phpunit.de>
6 *
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
9 */
10
11/**
12 * Invocation matcher which checks if a method has been invoked a certain amount
13 * of times.
14 * If the number of invocations exceeds the value it will immediately throw an
15 * exception,
16 * If the number is less it will later be checked in verify() and also throw an
17 * exception.
18 *
19 * @since Class available since Release 1.0.0
20 */
21class PHPUnit_Framework_MockObject_Matcher_InvokedCount extends PHPUnit_Framework_MockObject_Matcher_InvokedRecorder
22{
23    /**
24     * @var int
25     */
26    protected $expectedCount;
27
28    /**
29     * @param int $expectedCount
30     */
31    public function __construct($expectedCount)
32    {
33        $this->expectedCount = $expectedCount;
34    }
35
36    /**
37     * @return bool
38     */
39    public function isNever()
40    {
41        return $this->expectedCount == 0;
42    }
43
44    /**
45     * @return string
46     */
47    public function toString()
48    {
49        return 'invoked ' . $this->expectedCount . ' time(s)';
50    }
51
52    /**
53     * @param PHPUnit_Framework_MockObject_Invocation $invocation
54     *
55     * @throws PHPUnit_Framework_ExpectationFailedException
56     */
57    public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation)
58    {
59        parent::invoked($invocation);
60
61        $count = $this->getInvocationCount();
62
63        if ($count > $this->expectedCount) {
64            $message = $invocation->toString() . ' ';
65
66            switch ($this->expectedCount) {
67                case 0: {
68                    $message .= 'was not expected to be called.';
69                }
70                break;
71
72                case 1: {
73                    $message .= 'was not expected to be called more than once.';
74                }
75                break;
76
77                default: {
78                    $message .= sprintf(
79                        'was not expected to be called more than %d times.',
80                        $this->expectedCount
81                    );
82                    }
83            }
84
85            throw new PHPUnit_Framework_ExpectationFailedException($message);
86        }
87    }
88
89    /**
90     * Verifies that the current expectation is valid. If everything is OK the
91     * code should just return, if not it must throw an exception.
92     *
93     * @throws PHPUnit_Framework_ExpectationFailedException
94     */
95    public function verify()
96    {
97        $count = $this->getInvocationCount();
98
99        if ($count !== $this->expectedCount) {
100            throw new PHPUnit_Framework_ExpectationFailedException(
101                sprintf(
102                    'Method was expected to be called %d times, ' .
103                    'actually called %d times.',
104                    $this->expectedCount,
105                    $count
106                )
107            );
108        }
109    }
110}
111