Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php declare(strict_types=1);
2
/*
3
 * This file is part of PHPUnit.
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
namespace PHPUnit\Framework\Constraint;
11
 
12
use function count;
13
use function is_array;
14
use function iterator_count;
15
use function sprintf;
16
use Countable;
17
use EmptyIterator;
18
use Generator;
19
use Iterator;
20
use IteratorAggregate;
21
use PHPUnit\Framework\Exception;
22
use Traversable;
23
 
24
/**
25
 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
26
 */
27
class Count extends Constraint
28
{
29
    /**
30
     * @var int
31
     */
32
    private $expectedCount;
33
 
34
    public function __construct(int $expected)
35
    {
36
        $this->expectedCount = $expected;
37
    }
38
 
39
    public function toString(): string
40
    {
41
        return sprintf(
42
            'count matches %d',
43
            $this->expectedCount
44
        );
45
    }
46
 
47
    /**
48
     * Evaluates the constraint for parameter $other. Returns true if the
49
     * constraint is met, false otherwise.
50
     *
51
     * @throws Exception
52
     */
53
    protected function matches($other): bool
54
    {
55
        return $this->expectedCount === $this->getCountOf($other);
56
    }
57
 
58
    /**
59
     * @throws Exception
60
     */
61
    protected function getCountOf($other): ?int
62
    {
63
        if ($other instanceof Countable || is_array($other)) {
64
            return count($other);
65
        }
66
 
67
        if ($other instanceof EmptyIterator) {
68
            return 0;
69
        }
70
 
71
        if ($other instanceof Traversable) {
72
            while ($other instanceof IteratorAggregate) {
73
                try {
74
                    $other = $other->getIterator();
75
                } catch (\Exception $e) {
76
                    throw new Exception(
77
                        $e->getMessage(),
78
                        $e->getCode(),
79
                        $e
80
                    );
81
                }
82
            }
83
 
84
            $iterator = $other;
85
 
86
            if ($iterator instanceof Generator) {
87
                return $this->getCountOfGenerator($iterator);
88
            }
89
 
90
            if (!$iterator instanceof Iterator) {
91
                return iterator_count($iterator);
92
            }
93
 
94
            $key   = $iterator->key();
95
            $count = iterator_count($iterator);
96
 
97
            // Manually rewind $iterator to previous key, since iterator_count
98
            // moves pointer.
99
            if ($key !== null) {
100
                $iterator->rewind();
101
 
102
                while ($iterator->valid() && $key !== $iterator->key()) {
103
                    $iterator->next();
104
                }
105
            }
106
 
107
            return $count;
108
        }
109
 
110
        return null;
111
    }
112
 
113
    /**
114
     * Returns the total number of iterations from a generator.
115
     * This will fully exhaust the generator.
116
     */
117
    protected function getCountOfGenerator(Generator $generator): int
118
    {
119
        for ($count = 0; $generator->valid(); $generator->next()) {
120
            $count++;
121
        }
122
 
123
        return $count;
124
    }
125
 
126
    /**
127
     * Returns the description of the failure.
128
     *
129
     * The beginning of failure messages is "Failed asserting that" in most
130
     * cases. This method should return the second part of that sentence.
131
     *
132
     * @param mixed $other evaluated value or object
133
     */
134
    protected function failureDescription($other): string
135
    {
136
        return sprintf(
137
            'actual size %d matches expected size %d',
138
            (int) $this->getCountOf($other),
139
            $this->expectedCount
140
        );
141
    }
142
}