testWhenOnRewindSetInConstructor_onRewindThrowsException()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 13
rs 9.8333
c 0
b 0
f 0
1
<?php
2
3
declare( strict_types = 1 );
4
5
use PHPUnit\Framework\TestCase;
6
7
/**
8
 * @covers RewindableGenerator
9
 *
10
 * @licence GNU GPL v2+
11
 * @author Jeroen De Dauw < [email protected] >
12
 */
13
class RewindableGeneratorTest extends TestCase {
14
15
	public function testAdaptsEmptyGenerator() {
16
		// Not using simply (yield) as a several static code analysis tools break on it
17
		$iterator = new RewindableGenerator( function() {
18
			foreach ( [] as $element ) {
19
				yield $element;
20
			}
21
		} );
22
23
		$this->assertSame( [], iterator_to_array( $iterator ) );
24
	}
25
26
	public function testAdaptsNotEmptyGenerator() {
27
		$iterator = new RewindableGenerator( function() {
28
			yield 'foo';
29
			yield 'bar';
30
			yield 'baz';
31
		} );
32
33
		$this->assertSame(
34
			[ 'foo', 'bar', 'baz' ],
35
			iterator_to_array( $iterator )
36
		);
37
	}
38
39
	public function testCanRewind() {
40
		$iterator = new RewindableGenerator( function() {
41
			yield 'foo';
42
			yield 'bar';
43
			yield 'baz';
44
		} );
45
46
		$iterator->next();
47
48
		if ( defined( 'HHVM_VERSION' ) ) {
49
			// The fuck HHVM?
50
			$iterator->next();
51
		}
52
53
		$this->assertSame( 'bar', $iterator->current(), 'next behaves as expected' );
54
		$iterator->rewind();
55
		$this->assertSame( 'foo', $iterator->current(), 'rewind behaves as expected' );
56
	}
57
58
	public function testIterateTwice() {
59
		$iterator = new RewindableGenerator( function() {
60
			yield 'foo';
61
			yield 'bar';
62
			yield 'baz';
63
		} );
64
65
		$this->assertSame(
66
			[ 'foo', 'bar', 'baz' ],
67
			iterator_to_array( $iterator )
68
		);
69
70
		$this->assertSame(
71
			[ 'foo', 'bar', 'baz' ],
72
			iterator_to_array( $iterator )
73
		);
74
	}
75
76
	public function testGivenNonGeneratorFunction_constructorThrowsException() {
77
		$this->expectException( 'InvalidArgumentException' );
78
		new RewindableGenerator( function() {} );
79
	}
80
81
	public function testWhenCallingItTwice_onRewindThrowsException() {
82
		$iterator = new RewindableGenerator( function() {
83
			yield 'foo';
84
			yield 'bar';
85
			yield 'baz';
86
		} );
87
88
89
		$iterator->onRewind( function() {} );
90
		$this->expectException( 'InvalidArgumentException' );
91
		$iterator->onRewind( function() {} );
92
	}
93
94
	public function testWhenOnRewindSetInConstructor_onRewindThrowsException() {
95
		$iterator = new RewindableGenerator(
96
			function() {
97
				yield 'foo';
98
				yield 'bar';
99
				yield 'baz';
100
			},
101
			function() {}
102
		);
103
104
		$this->expectException( 'InvalidArgumentException' );
105
		$iterator->onRewind( function() {} );
106
	}
107
108
	public function testWhenCallingRewind_onRewindCallbackGetsCalled() {
109
		$events = [];
110
111
		$iterator = new RewindableGenerator(
112
			function() {
113
				yield 'foo';
114
				yield 'bar';
115
				yield 'baz';
116
			},
117
			function() use ( &$events ) {
118
				$events[] = 'callback';
119
			}
120
		);
121
122
		$events[] = 'start';
123
		$iterator->rewind();
124
		$events[] = 'done';
125
126
		$this->assertSame(
127
			[ 'start', 'callback', 'done' ],
128
			$events
129
		);
130
	}
131
132
	public function testIteratingMultipleTimes_onRewindCallbackGetsCalled() {
133
		$events = [];
134
135
		$iterator = new RewindableGenerator(
136
			function() {
137
				yield 'foo';
138
				yield 'bar';
139
				yield 'baz';
140
			},
141
			function() use ( &$events ) {
142
				$events[] = 'callback';
143
			}
144
		);
145
146
		$events[] = 'start';
147
		iterator_to_array( $iterator );
148
		$events[] = 'one done';
149
		iterator_to_array( $iterator );
150
		$events[] = 'two done';
151
152
		$this->assertSame(
153
			[ 'start', 'callback', 'one done', 'callback', 'two done' ],
154
			$events
155
		);
156
	}
157
158
}
159
160