File: CountTest.php

package info (click to toggle)
phpunit 9.5.2-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 24,872 kB
  • sloc: php: 47,103; xml: 1,386; makefile: 37; sh: 8
file content (201 lines) | stat: -rw-r--r-- 6,496 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
<?php declare(strict_types=1);
/*
 * This file is part of PHPUnit.
 *
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace PHPUnit\Framework\Constraint;

use DatePeriod;
use EmptyIterator;
use Iterator;
use IteratorAggregate;
use PHPUnit\Framework\ExpectationFailedException;
use PHPUnit\Framework\TestFailure;
use PHPUnit\TestFixture\TestGeneratorMaker;
use PHPUnit\TestFixture\TestIterator;
use PHPUnit\TestFixture\TestIterator2;
use PHPUnit\TestFixture\TestIteratorAggregate;
use PHPUnit\TestFixture\TestIteratorAggregate2;
use Traversable;

/**
 * @small
 */
final class CountTest extends ConstraintTestCase
{
    public function testCount(): void
    {
        $countConstraint = new Count(3);
        $this->assertTrue($countConstraint->evaluate([1, 2, 3], '', true));

        $countConstraint = new Count(0);
        $this->assertTrue($countConstraint->evaluate([], '', true));

        $countConstraint = new Count(2);
        $it              = new TestIterator([1, 2]);
        $ia              = new TestIteratorAggregate($it);
        $ia2             = new TestIteratorAggregate2($ia);

        $this->assertTrue($countConstraint->evaluate($it, '', true));
        $this->assertTrue($countConstraint->evaluate($ia, '', true));
        $this->assertTrue($countConstraint->evaluate($ia2, '', true));
    }

    public function testCountDoesNotChangeIteratorKey(): void
    {
        $countConstraint = new Count(2);

        // test with 1st implementation of Iterator
        $it = new TestIterator([1, 2]);

        $countConstraint->evaluate($it, '', true);
        $this->assertEquals(1, $it->current());

        $it->next();
        $countConstraint->evaluate($it, '', true);
        $this->assertEquals(2, $it->current());

        $it->next();
        $countConstraint->evaluate($it, '', true);
        $this->assertFalse($it->valid());

        // test with 2nd implementation of Iterator
        $it = new TestIterator2([1, 2]);

        $countConstraint = new Count(2);
        $countConstraint->evaluate($it, '', true);
        $this->assertEquals(1, $it->current());

        $it->next();
        $countConstraint->evaluate($it, '', true);
        $this->assertEquals(2, $it->current());

        $it->next();
        $countConstraint->evaluate($it, '', true);
        $this->assertFalse($it->valid());

        // test with IteratorAggregate
        $it = new TestIterator([1, 2]);
        $ia = new TestIteratorAggregate($it);

        $countConstraint = new Count(2);
        $countConstraint->evaluate($ia, '', true);
        $this->assertEquals(1, $it->current());

        $it->next();
        $countConstraint->evaluate($ia, '', true);
        $this->assertEquals(2, $it->current());

        $it->next();
        $countConstraint->evaluate($ia, '', true);
        $this->assertFalse($it->valid());

        // test with nested IteratorAggregate
        $it  = new TestIterator([1, 2]);
        $ia  = new TestIteratorAggregate($it);
        $ia2 = new TestIteratorAggregate2($ia);

        $countConstraint = new Count(2);
        $countConstraint->evaluate($ia2, '', true);
        $this->assertEquals(1, $it->current());

        $it->next();
        $countConstraint->evaluate($ia2, '', true);
        $this->assertEquals(2, $it->current());

        $it->next();
        $countConstraint->evaluate($ia2, '', true);
        $this->assertFalse($it->valid());
    }

    public function testCountGeneratorsDoNotRewind(): void
    {
        $generatorMaker = new TestGeneratorMaker;

        $countConstraint = new Count(3);

        $generator = $generatorMaker->create([1, 2, 3]);
        $this->assertEquals(1, $generator->current());
        $countConstraint->evaluate($generator, '', true);
        $this->assertEquals(null, $generator->current());

        $countConstraint = new Count(2);

        $generator = $generatorMaker->create([1, 2, 3]);
        $this->assertEquals(1, $generator->current());
        $generator->next();
        $this->assertEquals(2, $generator->current());
        $countConstraint->evaluate($generator, '', true);
        $this->assertEquals(null, $generator->current());

        $countConstraint = new Count(1);

        $generator = $generatorMaker->create([1, 2, 3]);
        $this->assertEquals(1, $generator->current());
        $generator->next();
        $this->assertEquals(2, $generator->current());
        $generator->next();
        $this->assertEquals(3, $generator->current());
        $countConstraint->evaluate($generator, '', true);
        $this->assertEquals(null, $generator->current());
    }

    /**
     * Since PHP8, Traversable cannot be implemented directly.
     *
     * @requires PHP < 8.0
     */
    public function testCountTraversable(): void
    {
        $countConstraint = new Count(5);

        // DatePeriod is used as an object that is Traversable but does not
        // implement Iterator or IteratorAggregate. The following ISO 8601
        // recurring time interval will yield five total DateTime objects.
        $datePeriod = new DatePeriod('R4/2017-05-01T00:00:00Z/P1D');

        $this->assertInstanceOf(Traversable::class, $datePeriod);
        $this->assertNotInstanceOf(Iterator::class, $datePeriod);
        $this->assertNotInstanceOf(IteratorAggregate::class, $datePeriod);
        $this->assertTrue($countConstraint->evaluate($datePeriod, '', true));
    }

    public function testCountCanBeExportedToString(): void
    {
        $countConstraint = new Count(1);

        $this->assertEquals('count matches 1', $countConstraint->toString());
    }

    public function testCountEvaluateReturnsNullWithNonCountableAndNonTraversableOther(): void
    {
        $countConstraint = new Count(1);

        try {
            $this->assertNull($countConstraint->evaluate(1));
        } catch (ExpectationFailedException  $e) {
            $this->assertEquals(
                <<<'EOF'
Failed asserting that actual size 0 matches expected size 1.

EOF
                ,
                TestFailure::exceptionToString($e)
            );
        }
    }

    /**
     * @ticket https://github.com/sebastianbergmann/phpunit/issues/3743
     */
    public function test_EmptyIterator_is_handled_correctly(): void
    {
        $constraint = new Count(0);

        $this->assertTrue($constraint->evaluate(new EmptyIterator, '', true));
    }
}