Completed
Push — master ( cb0578...28965e )
by Jeroen De
07:11 queued 04:27
created

testErrorsAreClearedBetweenProcessingRuns()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 1
eloc 6
nc 1
nop 0
1
<?php
2
3
namespace ParamProcessor\Tests;
4
5
use ParamProcessor\ProcessingError;
6
use ParamProcessor\ProcessingResult;
7
use ParamProcessor\Processor;
8
use ParamProcessor\Options;
9
10
/**
11
 * @covers ParamProcessor\Processor
12
 *
13
 * @licence GNU GPL v2+
14
 * @author Jeroen De Dauw < [email protected] >
15
 */
16
class ProcessorTest extends \PHPUnit_Framework_TestCase {
17
18
	public function testNewDefault() {
19
		$this->assertInstanceOf( 'ParamProcessor\Processor', Processor::newDefault() );
20
	}
21
22
	public function newFromOptionsProvider() {
23
		$options = [];
24
25
		$option = new Options();
26
27
		$options[] = clone $option;
28
29
		$option->setName( 'foobar' );
30
		$option->setLowercaseNames( false );
31
32
		$options[] = clone $option;
33
34
		return $this->arrayWrap( $options );
35
	}
36
37
	private function arrayWrap( array $elements ) {
38
		return array_map(
39
			function( $element ) {
40
				return [ $element ];
41
			},
42
			$elements
43
		);
44
	}
45
46
	public function testNewFromOptions() {
47
		$options = new Options();
48
		$validator = Processor::newFromOptions( clone $options );
49
		$this->assertInstanceOf( '\ParamProcessor\Processor', $validator );
50
		$this->assertEquals( $options, $validator->getOptions() );
51
	}
52
53
	/**
54
	 * Simple parameter definitions and values that should all pass.
55
	 *
56
	 * @return array
57
	 */
58
	private function getSimpleParams() {
59
		$params = [
60
			'awesome' => 'yes',
61
			'Howmuch ' => '9001',
62
			'FLOAT' => '4.2',
63
			' page' => 'Ohi there!',
64
			' text     ' => 'foo bar baz o_O',
65
		];
66
67
		$definitions = [
68
			'awesome' => [
69
				'type' => 'boolean',
70
			],
71
			'howmuch' => [
72
				'type' => 'integer',
73
			],
74
			'float' => [
75
				'type' => 'float',
76
			],
77
			'page' => [
78
				'type' => 'string',
79
				'hastoexist' => false,
80
			],
81
			'text' => [],
82
		];
83
84
		$options = new Options();
85
86
		$expected = [
87
			'awesome' => true,
88
			'howmuch' => 9001,
89
			'float' => 4.2,
90
			'page' => 'Ohi there!',
91
			'text' => 'foo bar baz o_O',
92
		];
93
94
		return [ $params, $definitions, $options, $expected ];
95
	}
96
97
	/**
98
	 * Simple parameter definitions with defaults and values
99
	 * that are invalid or missing and therefore default.
100
	 *
101
	 * @return array
102
	 */
103
	private function getDefaultingParams() {
104
		$params = [
105
			'awesome' => 'omg!',
106
			'howmuch' => 'omg!',
107
			'float' => 'omg!',
108
			'page' => 42,
109
			'whot?' => 'O_o',
110
			'integerr' => ' 9001 ',
111
		];
112
113
		$definitions = [
114
			'awesome' => [
115
				'type' => 'boolean',
116
				'default' => true,
117
			],
118
			'howmuch' => [
119
				'type' => 'integer',
120
				'default' => 9001,
121
			],
122
			'float' => [
123
				'type' => 'float',
124
				'default' => 4.2,
125
			],
126
			'page' => [
127
				'type' => 'string',
128
				'hastoexist' => false,
129
				'default' => 'Ohi there!',
130
			],
131
			'text' => [
132
				'default' => 'foo bar baz o_O',
133
			],
134
			'integerr' => [
135
				'type' => 'integer',
136
				'default' => 42,
137
			],
138
		];
139
140
		$options = new Options();
141
		$options->setTrimValues( false );
142
143
		$expected = [
144
			'awesome' => true,
145
			'howmuch' => 9001,
146
			'float' => 4.2,
147
			'page' => 'Ohi there!',
148
			'text' => 'foo bar baz o_O',
149
			'integerr' => 42,
150
		];
151
152
		return [ $params, $definitions, $options, $expected ];
153
	}
154
155
	/**
156
	 * Values and definitions in-system parameter handling.
157
	 * Options set to expect non-raw values.
158
	 *
159
	 * @return array
160
	 */
161
	private function getTypedParams() {
162
		$params = [
163
			'awesome' => true,
164
			'howmuch' => '42',
165
			'float' => 4.2,
166
			'page' => 'Ohi there!',
167
			'Text' => 'foo bar baz o_O',
168
			'text1 ' => 'foo bar baz o_O',
169
			' text2' => 'foo bar baz o_O',
170
		];
171
172
		$definitions = [
173
			'awesome' => [
174
				'type' => 'boolean',
175
			],
176
			'howmuch' => [
177
				'type' => 'integer',
178
				'default' => 9001,
179
			],
180
			'float' => [
181
				'type' => 'float',
182
				'lowerbound' => 9001,
183
				'default' => 9000.1
184
			],
185
			'page' => [
186
				'type' => 'string',
187
				'hastoexist' => false,
188
			],
189
			'text' => [
190
				'default' => 'some text',
191
			],
192
			'text1' => [
193
				'default' => 'some text',
194
			],
195
			'text2' => [
196
				'default' => 'some text',
197
			],
198
		];
199
200
		$options = new Options();
201
		$options->setRawStringInputs( false );
202
		$options->setLowercaseNames( false );
203
		$options->setTrimNames( false );
204
205
		$expected = [
206
			'awesome' => true,
207
			'howmuch' => 9001,
208
			'float' => 9000.1,
209
			'page' => 'Ohi there!',
210
			'text' => 'some text',
211
			'text1' => 'some text',
212
			'text2' => 'some text',
213
		];
214
215
		return [ $params, $definitions, $options, $expected ];
216
	}
217
218
	/**
219
	 * Values with capitalization and preceding/tailing spaces to test
220
	 * of the clean options work.
221
	 *
222
	 * @return array
223
	 */
224
	private function getUncleanParams() {
225
		$params = [
226
			'awesome' => ' yes ',
227
			'text' => ' FOO  bar  ',
228
			'integerr' => ' 9001 ',
229
		];
230
231
		$definitions = [
232
			'awesome' => [
233
				'type' => 'boolean',
234
			],
235
			'text' => [
236
				'default' => 'bar',
237
			],
238
			'integerr' => [
239
				'type' => 'integer',
240
				'default' => 42,
241
			],
242
		];
243
244
		$options = new Options();
245
		$options->setLowercaseValues( true );
246
		$options->setTrimValues( true );
247
248
		$expected = [
249
			'awesome' => true,
250
			'text' => 'foo  bar',
251
			'integerr' => 9001,
252
		];
253
254
		return [ $params, $definitions, $options, $expected ];
255
	}
256
257
	/**
258
	 * List parameters to test if list handling works correctly.
259
	 *
260
	 * @return array
261
	 */
262
	private function getListParams() {
263
		$params = [
264
			'awesome' => ' yes, no, on, off ',
265
			'float' => ' 9001 ; 42 ; 4.2;0',
266
		];
267
268
		$definitions = [
269
			'awesome' => [
270
				'type' => 'boolean',
271
				'islist' => true,
272
			],
273
			'text' => [
274
				'default' => [ 'bar' ],
275
				'islist' => true,
276
			],
277
			'float' => [
278
				'type' => 'float',
279
				'islist' => true,
280
				'delimiter' => ';'
281
			],
282
		];
283
284
		$options = new Options();
285
		$options->setLowercaseValues( true );
286
		$options->setTrimValues( true );
287
288
		$expected = [
289
			'awesome' => [ true, false, true, false ],
290
			'text' => [ 'bar' ],
291
			'float' => [ 9001.0, 42.0, 4.2, 0.0 ],
292
		];
293
294
		return [ $params, $definitions, $options, $expected ];
295
	}
296
297
	public function parameterProvider() {
298
		// $params, $definitions [, $options]
0 ignored issues
show
Unused Code Comprehensibility introduced by jeroendedauw
64% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
299
		$argLists = [];
300
301
		$argLists[] = $this->getSimpleParams();
302
303
		$argLists[] = $this->getDefaultingParams();
304
305
		$argLists[] = $this->getTypedParams();
306
307
		$argLists[] = $this->getUncleanParams();
308
309
		$argLists[] = $this->getListParams();
310
311
		foreach ( $argLists as &$argList ) {
312
			foreach ( $argList[1] as $key => &$definition ) {
313
				$definition['message'] = 'test-' . $key;
314
			}
315
316
			if ( !array_key_exists( 2, $argList ) ) {
317
				$argList[2] = new Options();
318
			}
319
		}
320
321
		return $argLists;
322
	}
323
324
	/**
325
	 * @dataProvider parameterProvider
326
	 */
327
	public function testSetParameters( array $params, array $definitions, Options $options ) {
328
		$validator = Processor::newFromOptions( $options );
329
330
		$validator->setParameters( $params, $definitions );
331
332
		$this->assertTrue( true ); // TODO
333
	}
334
335
	/**
336
	 * @dataProvider parameterProvider
337
	 */
338
	public function testValidateParameters( array $params, array $definitions, Options $options, array $expected = [] ) {
339
		$validator = Processor::newFromOptions( $options );
340
341
		$validator->setParameters( $params, $definitions );
342
343
		$processingResult = $validator->processParameters();
344
345
		$actualValues = [];
346
347
		foreach ( $processingResult->getParameters() as $param ) {
348
			$actualValues[$param->getName()] = $param->getValue();
349
		}
350
351
		$this->assertEquals( $expected, $actualValues );
352
353
354
	}
355
356
	public function testProcessParametersOnEmptyOptions() {
357
		$processor = Processor::newDefault();
358
359
		$this->assertInstanceOf(
360
			ProcessingResult::class,
361
			$processor->processParameters()
362
		);
363
	}
364
365
	public function testErrorsCanBeRetrievedAfterProcessing() {
366
		$processor = Processor::newDefault();
367
368
		$this->processWithOneError( $processor );
369
370
		$this->assertCount( 1, $processor->getErrors() );
371
	}
372
373
	private function processWithOneError( Processor $processor ) {
374
		$processor->setParameters(
375
			[],
376
			[
0 ignored issues
show
Documentation introduced by Jeroen De Dauw
array('awesome' => array...ge' => 'test-awesome')) is of type array<string,array<strin...ssage\":\"string\"}>"}>, but the function expects a array<integer,object<Par...ssor\IParamDefinition>>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
377
				'awesome' => [
378
					'type' => 'boolean',
379
					'message' => 'test-awesome'
380
				],
381
			]
382
		);
383
384
		// There should be a single "missing required parameter" error.
385
		$processor->processParameters();
386
	}
387
388
	public function testErrorsAreClearedBetweenProcessingRuns() {
389
		$processor = Processor::newDefault();
390
391
		$this->processWithOneError( $processor );
392
		$processor->setParameters( [], [] );
393
		$processor->processParameters();
394
395
		$this->assertEmpty( $processor->getErrors() );
396
	}
397
398
}
399