|
1
|
|
|
<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName |
|
2
|
|
|
/** |
|
3
|
|
|
* Tests for the WordPress versioning plugin. |
|
4
|
|
|
* |
|
5
|
|
|
* @package automattic/jetpack-changelogger |
|
6
|
|
|
*/ |
|
7
|
|
|
|
|
8
|
|
|
// phpcs:disable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase |
|
9
|
|
|
|
|
10
|
|
|
namespace Automattic\Jetpack\Changelogger\Tests\Plugins; |
|
11
|
|
|
|
|
12
|
|
|
use Automattic\Jetpack\Changelog\ChangeEntry; |
|
13
|
|
|
use Automattic\Jetpack\Changelogger\Plugins\WordpressVersioning; |
|
14
|
|
|
use InvalidArgumentException; |
|
15
|
|
|
use PHPUnit\Framework\TestCase; |
|
16
|
|
|
use Symfony\Component\Console\Input\ArrayInput; |
|
17
|
|
|
use Symfony\Component\Console\Input\InputDefinition; |
|
18
|
|
|
use Symfony\Component\Console\Input\InputOption; |
|
19
|
|
|
use Symfony\Component\Console\Output\BufferedOutput; |
|
20
|
|
|
|
|
21
|
|
|
/** |
|
22
|
|
|
* Tests for the WordPress versioning plugin. |
|
23
|
|
|
* |
|
24
|
|
|
* @covers \Automattic\Jetpack\Changelogger\Plugins\WordpressVersioning |
|
25
|
|
|
*/ |
|
26
|
|
|
class WordpressVersioningTest extends TestCase { |
|
27
|
|
|
use \Yoast\PHPUnitPolyfills\Polyfills\AssertIsType; |
|
28
|
|
|
use \Yoast\PHPUnitPolyfills\Polyfills\ExpectException; |
|
29
|
|
|
|
|
30
|
|
|
/** |
|
31
|
|
|
* Test getOptions. |
|
32
|
|
|
*/ |
|
33
|
|
|
public function testGetOptions() { |
|
34
|
|
|
$obj = new WordpressVersioning( array() ); |
|
|
|
|
|
|
35
|
|
|
$opts = $obj->getOptions(); |
|
36
|
|
|
$this->assertIsArray( $opts ); |
|
37
|
|
|
foreach ( $opts as $opt ) { |
|
38
|
|
|
$this->assertInstanceOf( InputOption::class, $opt ); |
|
39
|
|
|
} |
|
40
|
|
|
} |
|
41
|
|
|
|
|
42
|
|
|
/** |
|
43
|
|
|
* Test normalizeVersion and parseVersion. |
|
44
|
|
|
* |
|
45
|
|
|
* @dataProvider provideNormalizeVersion |
|
46
|
|
|
* @param string $version Version. |
|
47
|
|
|
* @param string|InvalidArgumentException $expect Expected result. |
|
48
|
|
|
*/ |
|
49
|
|
View Code Duplication |
public function testNormalizeVersion( $version, $expect ) { |
|
50
|
|
|
$obj = new WordpressVersioning( array() ); |
|
|
|
|
|
|
51
|
|
|
if ( $expect instanceof InvalidArgumentException ) { |
|
52
|
|
|
$this->expectException( InvalidArgumentException::class ); |
|
53
|
|
|
$this->expectExceptionMessage( $expect->getMessage() ); |
|
54
|
|
|
$obj->normalizeVersion( $version ); |
|
55
|
|
|
} else { |
|
56
|
|
|
$this->assertSame( $expect, $obj->normalizeVersion( $version ) ); |
|
57
|
|
|
} |
|
58
|
|
|
} |
|
59
|
|
|
|
|
60
|
|
|
/** |
|
61
|
|
|
* Data provider for testNormalizeVersion. |
|
62
|
|
|
*/ |
|
63
|
|
|
public function provideNormalizeVersion() { |
|
64
|
|
|
return array( |
|
65
|
|
|
array( '1.2', '1.2' ), |
|
66
|
|
|
array( '1000.2', '1000.2' ), |
|
67
|
|
|
array( '1000.2.999', '1000.2.999' ), |
|
68
|
|
|
array( '1.2.3', '1.2.3' ), |
|
69
|
|
|
array( '1.2.0', '1.2' ), |
|
70
|
|
|
array( '0.0.0', '0.0' ), |
|
71
|
|
|
array( '1.2-dev', '1.2-dev' ), |
|
72
|
|
|
array( '1.2.3-dev', '1.2.3-dev' ), |
|
73
|
|
|
array( '1.2.3-alpha', '1.2.3-alpha' ), |
|
74
|
|
|
array( '1.2-alpha1', '1.2-alpha1' ), |
|
75
|
|
|
array( '1.2.3-beta', '1.2.3-beta' ), |
|
76
|
|
|
array( '1.2-beta1', '1.2-beta1' ), |
|
77
|
|
|
array( '1.2.3-rc', '1.2.3-rc' ), |
|
78
|
|
|
array( '1.2-rc1', '1.2-rc1' ), |
|
79
|
|
|
array( '1.2.3-alpha+foobar', '1.2.3-alpha+foobar' ), |
|
80
|
|
|
array( '1.2.3-alpha1+foobar.2', '1.2.3-alpha1+foobar.2' ), |
|
81
|
|
|
array( '0001.2.0003-alpha0001+000foobar000....0002', '1.2.3-alpha0001+000foobar000....0002' ), |
|
82
|
|
|
|
|
83
|
|
|
array( '1.22', new InvalidArgumentException( 'Version number "1.22" is not in a recognized format.' ) ), |
|
84
|
|
|
array( '1.2.x', new InvalidArgumentException( 'Version number "1.2.x" is not in a recognized format.' ) ), |
|
85
|
|
|
array( '1.x.4', new InvalidArgumentException( 'Version number "1.x.4" is not in a recognized format.' ) ), |
|
86
|
|
|
array( '1..4', new InvalidArgumentException( 'Version number "1..4" is not in a recognized format.' ) ), |
|
87
|
|
|
array( '.2.3', new InvalidArgumentException( 'Version number ".2.3" is not in a recognized format.' ) ), |
|
88
|
|
|
array( '1.2.', new InvalidArgumentException( 'Version number "1.2." is not in a recognized format.' ) ), |
|
89
|
|
|
array( '1.2.-1', new InvalidArgumentException( 'Version number "1.2.-1" is not in a recognized format.' ) ), |
|
90
|
|
|
array( 'v1.2.3', new InvalidArgumentException( 'Version number "v1.2.3" is not in a recognized format.' ) ), |
|
91
|
|
|
array( '1.2.3.4', new InvalidArgumentException( 'Version number "1.2.3.4" is not in a recognized format.' ) ), |
|
92
|
|
|
array( '1.2-alpha.1', new InvalidArgumentException( 'Version number "1.2-alpha.1" is not in a recognized format.' ) ), |
|
93
|
|
|
array( '1.2-dev1', new InvalidArgumentException( 'Version number "1.2-dev1" is not in a recognized format.' ) ), |
|
94
|
|
|
array( '1.2-DEV', new InvalidArgumentException( 'Version number "1.2-DEV" is not in a recognized format.' ) ), |
|
95
|
|
|
array( '1.2-foo', new InvalidArgumentException( 'Version number "1.2-foo" is not in a recognized format.' ) ), |
|
96
|
|
|
array( '1.2-foo1', new InvalidArgumentException( 'Version number "1.2-foo1" is not in a recognized format.' ) ), |
|
97
|
|
|
array( '1.2.3-?', new InvalidArgumentException( 'Version number "1.2.3-?" is not in a recognized format.' ) ), |
|
98
|
|
|
array( '1.2.3+?', new InvalidArgumentException( 'Version number "1.2.3+?" is not in a recognized format.' ) ), |
|
99
|
|
|
array( '1.2.3-a..b', new InvalidArgumentException( 'Version number "1.2.3-a..b" is not in a recognized format.' ) ), |
|
100
|
|
|
); |
|
101
|
|
|
} |
|
102
|
|
|
|
|
103
|
|
|
/** |
|
104
|
|
|
* Test nextVersion. |
|
105
|
|
|
* |
|
106
|
|
|
* @dataProvider provideNextVersion |
|
107
|
|
|
* @param string $version Version. |
|
108
|
|
|
* @param ChangeEntry[] $changes Changes. |
|
109
|
|
|
* @param array $extra Extra components. |
|
110
|
|
|
* @param string|InvalidArgumentException $expect Expected result. |
|
111
|
|
|
* @param string $expectPoint Expected result for a point release. |
|
|
|
|
|
|
112
|
|
|
*/ |
|
113
|
|
|
public function testNextVersion( $version, array $changes, array $extra, $expect, $expectPoint = null ) { |
|
114
|
|
|
$obj = new WordpressVersioning( array() ); |
|
|
|
|
|
|
115
|
|
|
|
|
116
|
|
|
$out1 = $this->getMockBuilder( BufferedOutput::class ) |
|
117
|
|
|
->setMethods( array( 'getErrorOutput' ) ) |
|
118
|
|
|
->getMock(); |
|
119
|
|
|
$out2 = new BufferedOutput(); |
|
120
|
|
|
$out1->method( 'getErrorOutput' )->willReturn( $out2 ); |
|
121
|
|
|
|
|
122
|
|
|
$def = new InputDefinition( $obj->getOptions() ); |
|
123
|
|
|
$obj->setIO( new ArrayInput( array(), $def ), $out1 ); |
|
124
|
|
|
|
|
125
|
|
|
if ( $expect instanceof InvalidArgumentException ) { |
|
126
|
|
|
$this->expectException( InvalidArgumentException::class ); |
|
127
|
|
|
$this->expectExceptionMessage( $expect->getMessage() ); |
|
128
|
|
|
$obj->nextVersion( $version, $changes, $extra ); |
|
|
|
|
|
|
129
|
|
|
} else { |
|
130
|
|
|
$this->assertSame( $expect, $obj->nextVersion( $version, $changes, $extra ) ); |
|
|
|
|
|
|
131
|
|
|
$this->assertSame( '', $out1->fetch() ); |
|
132
|
|
|
$this->assertSame( '', $out2->fetch() ); |
|
133
|
|
|
|
|
134
|
|
|
$obj->setIO( new ArrayInput( array( '--point-release' => true ), $def ), $out1 ); |
|
135
|
|
|
$this->assertSame( $expectPoint, $obj->nextVersion( $version, $changes, $extra ) ); |
|
|
|
|
|
|
136
|
|
|
$this->assertSame( '', $out1->fetch() ); |
|
137
|
|
|
$this->assertSame( '', $out2->fetch() ); |
|
138
|
|
|
} |
|
139
|
|
|
} |
|
140
|
|
|
|
|
141
|
|
|
/** |
|
142
|
|
|
* Data provider for testNextVersion. |
|
143
|
|
|
*/ |
|
144
|
|
|
public function provideNextVersion() { |
|
145
|
|
|
return array( |
|
146
|
|
|
'No changes' => array( |
|
147
|
|
|
'1.2.3', |
|
148
|
|
|
array(), |
|
149
|
|
|
array(), |
|
150
|
|
|
'1.3', |
|
151
|
|
|
'1.2.4', |
|
152
|
|
|
), |
|
153
|
|
|
'Patch changes' => array( |
|
154
|
|
|
'1.2.3', |
|
155
|
|
|
array( |
|
156
|
|
|
new ChangeEntry( array( 'significance' => 'patch' ) ), |
|
157
|
|
|
new ChangeEntry( array( 'significance' => 'patch' ) ), |
|
158
|
|
|
new ChangeEntry( array( 'significance' => null ) ), |
|
159
|
|
|
new ChangeEntry( array( 'significance' => 'patch' ) ), |
|
160
|
|
|
), |
|
161
|
|
|
array(), |
|
162
|
|
|
'1.3', |
|
163
|
|
|
'1.2.4', |
|
164
|
|
|
), |
|
165
|
|
|
'Minor change' => array( |
|
166
|
|
|
'1.2.3', |
|
167
|
|
|
array( |
|
168
|
|
|
new ChangeEntry( array( 'significance' => 'patch' ) ), |
|
169
|
|
|
new ChangeEntry( array( 'significance' => 'minor' ) ), |
|
170
|
|
|
new ChangeEntry( array( 'significance' => null ) ), |
|
171
|
|
|
new ChangeEntry( array( 'significance' => 'patch' ) ), |
|
172
|
|
|
), |
|
173
|
|
|
array(), |
|
174
|
|
|
'1.3', |
|
175
|
|
|
'1.2.4', |
|
176
|
|
|
), |
|
177
|
|
|
'Major change' => array( |
|
178
|
|
|
'1.2.3', |
|
179
|
|
|
array( |
|
180
|
|
|
new ChangeEntry( array( 'significance' => 'patch' ) ), |
|
181
|
|
|
new ChangeEntry( array( 'significance' => 'minor' ) ), |
|
182
|
|
|
new ChangeEntry( array( 'significance' => null ) ), |
|
183
|
|
|
new ChangeEntry( array( 'significance' => 'major' ) ), |
|
184
|
|
|
new ChangeEntry( array( 'significance' => 'patch' ) ), |
|
185
|
|
|
), |
|
186
|
|
|
array(), |
|
187
|
|
|
'1.3', |
|
188
|
|
|
'1.2.4', |
|
189
|
|
|
), |
|
190
|
|
|
'Version number with extra components' => array( |
|
191
|
|
|
'1.2.3-dev', |
|
192
|
|
|
array(), |
|
193
|
|
|
array(), |
|
194
|
|
|
'1.3', |
|
195
|
|
|
'1.2.4', |
|
196
|
|
|
), |
|
197
|
|
|
'Version number with extra components (2)' => array( |
|
198
|
|
|
'1.2.9+123', |
|
199
|
|
|
array(), |
|
200
|
|
|
array(), |
|
201
|
|
|
'1.3', |
|
202
|
|
|
'1.2.10', |
|
203
|
|
|
), |
|
204
|
|
|
'Version number with extra components (3)' => array( |
|
205
|
|
|
'1.2.3-dev+bar', |
|
206
|
|
|
array(), |
|
207
|
|
|
array(), |
|
208
|
|
|
'1.3', |
|
209
|
|
|
'1.2.4', |
|
210
|
|
|
), |
|
211
|
|
|
'Roll over major component' => array( |
|
212
|
|
|
'99.9.999', |
|
213
|
|
|
array(), |
|
214
|
|
|
array(), |
|
215
|
|
|
'100.0', |
|
216
|
|
|
'99.9.1000', |
|
217
|
|
|
), |
|
218
|
|
|
|
|
219
|
|
|
'Including extra components' => array( |
|
220
|
|
|
'1.2.3', |
|
221
|
|
|
array(), |
|
222
|
|
|
array( |
|
223
|
|
|
'prerelease' => 'alpha2', |
|
224
|
|
|
'buildinfo' => 'g12345678.003', |
|
225
|
|
|
), |
|
226
|
|
|
'1.3-alpha2+g12345678.003', |
|
227
|
|
|
'1.2.4-alpha2+g12345678.003', |
|
228
|
|
|
), |
|
229
|
|
|
'Including extra components (2)' => array( |
|
230
|
|
|
'1.2.3-dev', |
|
231
|
|
|
array(), |
|
232
|
|
|
array( 'buildinfo' => 'g12345678' ), |
|
233
|
|
|
'1.3+g12345678', |
|
234
|
|
|
'1.2.4+g12345678', |
|
235
|
|
|
), |
|
236
|
|
|
|
|
237
|
|
|
'Invalid prerelease component' => array( |
|
238
|
|
|
'1.2.3-dev', |
|
239
|
|
|
array(), |
|
240
|
|
|
array( 'prerelease' => 'delta' ), |
|
241
|
|
|
new InvalidArgumentException( 'Invalid prerelease data' ), |
|
242
|
|
|
), |
|
243
|
|
|
'Invalid buildinfo component' => array( |
|
244
|
|
|
'1.2.3-dev', |
|
245
|
|
|
array(), |
|
246
|
|
|
array( 'buildinfo' => 'build?' ), |
|
247
|
|
|
new InvalidArgumentException( 'Invalid buildinfo data' ), |
|
248
|
|
|
), |
|
249
|
|
|
); |
|
250
|
|
|
} |
|
251
|
|
|
|
|
252
|
|
|
/** |
|
253
|
|
|
* Test compareVersions. |
|
254
|
|
|
* |
|
255
|
|
|
* @dataProvider provideCompareVersions |
|
256
|
|
|
* @param string $a Version A. |
|
257
|
|
|
* @param string $expect Expected result converted to a string, '>', '==', or '<'. |
|
258
|
|
|
* @param string $b Version B. |
|
259
|
|
|
*/ |
|
260
|
|
View Code Duplication |
public function testCompareVersions( $a, $expect, $b ) { |
|
261
|
|
|
$obj = new WordpressVersioning( array() ); |
|
|
|
|
|
|
262
|
|
|
$ret = $obj->compareVersions( $a, $b ); |
|
263
|
|
|
$this->assertIsInt( $ret ); |
|
264
|
|
|
$ret = $ret < 0 ? '<' : ( $ret > 0 ? '>' : '==' ); |
|
265
|
|
|
$this->assertSame( $expect, $ret ); |
|
266
|
|
|
} |
|
267
|
|
|
|
|
268
|
|
|
/** |
|
269
|
|
|
* Data provider for testCompareVersions. |
|
270
|
|
|
*/ |
|
271
|
|
|
public function provideCompareVersions() { |
|
272
|
|
|
return array( |
|
273
|
|
|
array( '1.0', '==', '1.0' ), |
|
274
|
|
|
array( '1.0.0', '==', '1.0' ), |
|
275
|
|
|
array( '1.0', '<', '2.0' ), |
|
276
|
|
|
array( '2.0', '>', '1.0' ), |
|
277
|
|
|
array( '1.1', '>', '1.0' ), |
|
278
|
|
|
array( '1.0', '<', '1.1' ), |
|
279
|
|
|
array( '1.9.999', '<', '2.0' ), |
|
280
|
|
|
array( '1.1', '<', '1.1.1' ), |
|
281
|
|
|
array( '1.0.999', '<', '1.1' ), |
|
282
|
|
|
array( '1.1.2', '>', '1.1.1' ), |
|
283
|
|
|
array( '1.1.1', '>', '1.1.1-dev' ), |
|
284
|
|
|
array( '1.1.0', '<', '1.1.1-dev' ), |
|
285
|
|
|
array( '1.1.1-alpha', '<', '1.1.1-beta' ), |
|
286
|
|
|
array( '1.1.1-dev', '<', '1.1.1-alpha' ), |
|
287
|
|
|
array( '1.1.1-alpha9', '<', '1.1.1-beta1' ), |
|
288
|
|
|
array( '1.1.1-beta9', '>', '1.1.1-beta1' ), |
|
289
|
|
|
array( '1.1.1-beta9', '==', '1.1.1-beta9' ), |
|
290
|
|
|
array( '1.1.1-alpha2', '<', '1.1.1-alpha10' ), |
|
291
|
|
|
array( '1.1.1+beta.9.1', '==', '1.1.1+beta.9' ), |
|
292
|
|
|
); |
|
293
|
|
|
} |
|
294
|
|
|
|
|
295
|
|
|
/** |
|
296
|
|
|
* Test firstVersion. |
|
297
|
|
|
* |
|
298
|
|
|
* @dataProvider provideFirstVersion |
|
299
|
|
|
* @param array $extra Extra components. |
|
300
|
|
|
* @param string|InvalidArgumentException $expect Expected result. |
|
301
|
|
|
*/ |
|
302
|
|
View Code Duplication |
public function testFirstVersion( array $extra, $expect ) { |
|
303
|
|
|
$obj = new WordpressVersioning( array() ); |
|
|
|
|
|
|
304
|
|
|
|
|
305
|
|
|
if ( $expect instanceof InvalidArgumentException ) { |
|
306
|
|
|
$this->expectException( InvalidArgumentException::class ); |
|
307
|
|
|
$this->expectExceptionMessage( $expect->getMessage() ); |
|
308
|
|
|
$obj->firstVersion( $extra ); |
|
309
|
|
|
} else { |
|
310
|
|
|
$this->assertSame( $expect, $obj->firstVersion( $extra ) ); |
|
311
|
|
|
} |
|
312
|
|
|
} |
|
313
|
|
|
|
|
314
|
|
|
/** |
|
315
|
|
|
* Data provider for testFirstVersion. |
|
316
|
|
|
*/ |
|
317
|
|
View Code Duplication |
public function provideFirstVersion() { |
|
318
|
|
|
return array( |
|
319
|
|
|
'Normal' => array( |
|
320
|
|
|
array(), |
|
321
|
|
|
'0.0', |
|
322
|
|
|
), |
|
323
|
|
|
'Some extra' => array( |
|
324
|
|
|
array( 'prerelease' => 'alpha' ), |
|
325
|
|
|
'0.0-alpha', |
|
326
|
|
|
), |
|
327
|
|
|
'Invalid prerelease' => array( |
|
328
|
|
|
array( 'prerelease' => 'delta' ), |
|
329
|
|
|
new InvalidArgumentException( 'Invalid prerelease data' ), |
|
330
|
|
|
), |
|
331
|
|
|
'Invalid buildinfo' => array( |
|
332
|
|
|
array( 'buildinfo' => 'build?' ), |
|
333
|
|
|
new InvalidArgumentException( 'Invalid buildinfo data' ), |
|
334
|
|
|
), |
|
335
|
|
|
); |
|
336
|
|
|
} |
|
337
|
|
|
|
|
338
|
|
|
} |
|
339
|
|
|
|
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignorePhpDoc annotation to the duplicate definition and it will be ignored.