Completed
Push — master ( ebda25...4c5acd )
by Jeroen De
01:42
created

ProcessorTest::testSetParameterDefinitions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 23
rs 9.552
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace ParamProcessor\Tests;
4
5
use ParamProcessor\ParamDefinitionFactory;
6
use ParamProcessor\ProcessedParam;
7
use ParamProcessor\ProcessingError;
8
use ParamProcessor\ProcessingResult;
9
use ParamProcessor\Processor;
10
use ParamProcessor\Options;
11
use PHPUnit\Framework\TestCase;
12
13
/**
14
 * @covers \ParamProcessor\Processor
15
 *
16
 * @licence GNU GPL v2+
17
 * @author Jeroen De Dauw < [email protected] >
18
 */
19
class ProcessorTest extends TestCase {
20
21
	public function newFromOptionsProvider() {
22
		$options = [];
23
24
		$option = new Options();
25
26
		$options[] = clone $option;
27
28
		$option->setName( 'foobar' );
29
		$option->setLowercaseNames( false );
30
31
		$options[] = clone $option;
32
33
		return $this->arrayWrap( $options );
34
	}
35
36
	private function arrayWrap( array $elements ) {
37
		return array_map(
38
			function( $element ) {
39
				return [ $element ];
40
			},
41
			$elements
42
		);
43
	}
44
45
	public function testNewFromOptions() {
46
		$this->assertEquals( new Options(), Processor::newFromOptions( new Options() )->getOptions() );
47
	}
48
49
	/**
50
	 * Simple parameter definitions and values that should all pass.
51
	 *
52
	 * @return array
53
	 */
54
	private function getSimpleParams() {
55
		$params = [
56
			'awesome' => 'yes',
57
			'Howmuch ' => '9001',
58
			'FLOAT' => '4.2',
59
			' page' => 'Ohi there!',
60
			' text     ' => 'foo bar baz o_O',
61
		];
62
63
		$definitions = [
64
			'awesome' => [
65
				'type' => 'boolean',
66
			],
67
			'howmuch' => [
68
				'type' => 'integer',
69
			],
70
			'float' => [
71
				'type' => 'float',
72
			],
73
			'page' => [
74
				'type' => 'string',
75
				'hastoexist' => false,
76
			],
77
			'text' => [],
78
		];
79
80
		$options = new Options();
81
82
		$expected = [
83
			'awesome' => true,
84
			'howmuch' => 9001,
85
			'float' => 4.2,
86
			'page' => 'Ohi there!',
87
			'text' => 'foo bar baz o_O',
88
		];
89
90
		return [ $params, $definitions, $options, $expected ];
91
	}
92
93
	/**
94
	 * Simple parameter definitions with defaults and values
95
	 * that are invalid or missing and therefore default.
96
	 *
97
	 * @return array
98
	 */
99
	private function getDefaultingParams() {
100
		$params = [
101
			'awesome' => 'omg!',
102
			'howmuch' => 'omg!',
103
			'float' => 'omg!',
104
			'page' => 42,
105
			'whot?' => 'O_o',
106
			'integerr' => ' 9001 ',
107
		];
108
109
		$definitions = [
110
			'awesome' => [
111
				'type' => 'boolean',
112
				'default' => true,
113
			],
114
			'howmuch' => [
115
				'type' => 'integer',
116
				'default' => 9001,
117
			],
118
			'float' => [
119
				'type' => 'float',
120
				'default' => 4.2,
121
			],
122
			'page' => [
123
				'type' => 'string',
124
				'hastoexist' => false,
125
				'default' => 'Ohi there!',
126
			],
127
			'text' => [
128
				'default' => 'foo bar baz o_O',
129
			],
130
			'integerr' => [
131
				'type' => 'integer',
132
				'default' => 42,
133
			],
134
		];
135
136
		$options = new Options();
137
		$options->setTrimValues( false );
138
139
		$expected = [
140
			'awesome' => true,
141
			'howmuch' => 9001,
142
			'float' => 4.2,
143
			'page' => 'Ohi there!',
144
			'text' => 'foo bar baz o_O',
145
			'integerr' => 42,
146
		];
147
148
		return [ $params, $definitions, $options, $expected ];
149
	}
150
151
	/**
152
	 * Values and definitions in-system parameter handling.
153
	 * Options set to expect non-raw values.
154
	 *
155
	 * @return array
156
	 */
157
	private function getTypedParams() {
158
		$params = [
159
			'awesome' => true,
160
			'howmuch' => '42',
161
			'float' => 4.2,
162
			'page' => 'Ohi there!',
163
			'Text' => 'foo bar baz o_O',
164
			'text1 ' => 'foo bar baz o_O',
165
			' text2' => 'foo bar baz o_O',
166
		];
167
168
		$definitions = [
169
			'awesome' => [
170
				'type' => 'boolean',
171
			],
172
			'howmuch' => [
173
				'type' => 'integer',
174
				'default' => 9001,
175
			],
176
			'float' => [
177
				'type' => 'float',
178
				'lowerbound' => 9001,
179
				'default' => 9000.1
180
			],
181
			'page' => [
182
				'type' => 'string',
183
				'hastoexist' => false,
184
			],
185
			'text' => [
186
				'default' => 'some text',
187
			],
188
			'text1' => [
189
				'default' => 'some text',
190
			],
191
			'text2' => [
192
				'default' => 'some text',
193
			],
194
		];
195
196
		$options = new Options();
197
		$options->setRawStringInputs( false );
198
		$options->setLowercaseNames( false );
199
		$options->setTrimNames( false );
200
201
		$expected = [
202
			'awesome' => true,
203
			'howmuch' => 9001,
204
			'float' => 9000.1,
205
			'page' => 'Ohi there!',
206
			'text' => 'some text',
207
			'text1' => 'some text',
208
			'text2' => 'some text',
209
		];
210
211
		return [ $params, $definitions, $options, $expected ];
212
	}
213
214
	/**
215
	 * Values with capitalization and preceding/tailing spaces to test
216
	 * of the clean options work.
217
	 *
218
	 * @return array
219
	 */
220
	private function getUncleanParams() {
221
		$params = [
222
			'awesome' => ' yes ',
223
			'text' => ' FOO  bar  ',
224
			'integerr' => ' 9001 ',
225
		];
226
227
		$definitions = [
228
			'awesome' => [
229
				'type' => 'boolean',
230
			],
231
			'text' => [
232
				'default' => 'bar',
233
			],
234
			'integerr' => [
235
				'type' => 'integer',
236
				'default' => 42,
237
			],
238
		];
239
240
		$options = new Options();
241
		$options->setLowercaseValues( true );
242
		$options->setTrimValues( true );
243
244
		$expected = [
245
			'awesome' => true,
246
			'text' => 'foo  bar',
247
			'integerr' => 9001,
248
		];
249
250
		return [ $params, $definitions, $options, $expected ];
251
	}
252
253
	/**
254
	 * List parameters to test if list handling works correctly.
255
	 *
256
	 * @return array
257
	 */
258
	private function getListParams() {
259
		$params = [
260
			'awesome' => ' yes, no, on, off ',
261
			'float' => ' 9001 ; 42 ; 4.2;0',
262
		];
263
264
		$definitions = [
265
			'awesome' => [
266
				'type' => 'boolean',
267
				'islist' => true,
268
			],
269
			'text' => [
270
				'default' => [ 'bar' ],
271
				'islist' => true,
272
			],
273
			'float' => [
274
				'type' => 'float',
275
				'islist' => true,
276
				'delimiter' => ';'
277
			],
278
		];
279
280
		$options = new Options();
281
		$options->setLowercaseValues( true );
282
		$options->setTrimValues( true );
283
284
		$expected = [
285
			'awesome' => [ true, false, true, false ],
286
			'text' => [ 'bar' ],
287
			'float' => [ 9001.0, 42.0, 4.2, 0.0 ],
288
		];
289
290
		return [ $params, $definitions, $options, $expected ];
291
	}
292
293
	public function parameterProvider() {
294
		// $params, $definitions [, $options]
295
		$argLists = [];
296
297
		$argLists[] = $this->getSimpleParams();
298
299
		$argLists[] = $this->getDefaultingParams();
300
301
		$argLists[] = $this->getTypedParams();
302
303
		$argLists[] = $this->getUncleanParams();
304
305
		$argLists[] = $this->getListParams();
306
307
		foreach ( $argLists as &$argList ) {
308
			foreach ( $argList[1] as $key => &$definition ) {
309
				$definition['message'] = 'test-' . $key;
310
			}
311
312
			if ( !array_key_exists( 2, $argList ) ) {
313
				$argList[2] = new Options();
314
			}
315
		}
316
317
		return $argLists;
318
	}
319
320
	/**
321
	 * @dataProvider parameterProvider
322
	 */
323
	public function testSetParameters( array $params, array $definitions, Options $options ) {
324
		$validator = Processor::newFromOptions( $options );
325
326
		$validator->setParameters( $params, $definitions );
327
328
		$this->assertTrue( true ); // TODO
329
	}
330
331
	/**
332
	 * @dataProvider parameterProvider
333
	 */
334
	public function testValidateParameters( array $params, array $definitions, Options $options, array $expected = [] ) {
335
		$validator = Processor::newFromOptions( $options );
336
337
		$validator->setParameters( $params, $definitions );
338
339
		$processingResult = $validator->processParameters();
340
341
		$actualValues = [];
342
343
		foreach ( $processingResult->getParameters() as $param ) {
344
			$actualValues[$param->getName()] = $param->getValue();
345
		}
346
347
		$this->assertEquals( $expected, $actualValues );
348
349
350
	}
351
352
	public function testProcessParametersOnEmptyOptions() {
353
		$processor = Processor::newDefault();
354
355
		$this->assertInstanceOf(
356
			ProcessingResult::class,
357
			$processor->processParameters()
358
		);
359
	}
360
361
	public function testErrorsCanBeRetrievedAfterProcessing() {
362
		$processor = Processor::newDefault();
363
364
		$this->processWithOneError( $processor );
365
366
		$this->assertCount( 1, $processor->getErrors() );
367
	}
368
369
	private function processWithOneError( Processor $processor ) {
370
		$processor->setParameters(
371
			[],
372
			[
373
				'awesome' => [
374
					'type' => 'boolean',
375
					'message' => 'test-awesome'
376
				],
377
			]
378
		);
379
380
		// There should be a single "missing required parameter" error.
381
		$processor->processParameters();
382
	}
383
384
	public function testErrorsAreClearedBetweenProcessingRuns() {
385
		$processor = Processor::newDefault();
386
387
		$this->processWithOneError( $processor );
388
		$processor->setParameters( [], [] );
389
		$processor->processParameters();
390
391
		$this->assertEmpty( $processor->getErrors() );
392
	}
393
394
	public function testInvalidListElementsAreOmitted() {
395
		$processor = Processor::newDefault();
396
397
		$processor->setFunctionParams(
398
			[
399
				'some-list=1,2,3, ,4,'
400
			],
401
			[
402
				'some-list' => [
403
					'type' => 'integer',
404
					'message' => 'test',
405
					'islist' => true
406
				],
407
			]
408
		);
409
410
		$this->assertSame(
411
			[ 1, 2, 3, 4 ],
412
			$processor->processParameters()->getParameters()['some-list']->getValue()
413
		);
414
	}
415
416
	public function testListParametersAreNotDefaultedWhenSomeElementsAreInvalid() {
417
		$processor = Processor::newDefault();
418
419
		$processor->setFunctionParams(
420
			[
421
				'some-list=1,nan'
422
			],
423
			[
424
				'some-list' => [
425
					'type' => 'integer',
426
					'message' => 'test',
427
					'islist' => true,
428
					'default' => []
429
				],
430
			]
431
		);
432
433
		$this->assertSame(
434
			[ 1 ],
435
			$processor->processParameters()->getParameters()['some-list']->getValue()
436
		);
437
	}
438
439
	public function testListParametersAreDefaultedWhenAllElementsAreInvalid() {
440
		$processor = Processor::newDefault();
441
442
		$processor->setFunctionParams(
443
			[
444
				'some-list=such,nan'
445
			],
446
			[
447
				'some-list' => [
448
					'type' => 'integer',
449
					'message' => 'test',
450
					'islist' => true,
451
					'default' => [ 42 ]
452
				],
453
			]
454
		);
455
456
		$this->assertSame(
457
			[ 42 ],
458
			$processor->processParameters()->getParameters()['some-list']->getValue()
459
		);
460
	}
461
462
	public function testSetParameterDefinitions() {
463
		$processor = Processor::newDefault();
464
465
		$processor->setFunctionParams( [ 'some-list=42,23,9001' ] );
466
467
		$processor->setParameterDefinitions(
468
			[
469
				( ParamDefinitionFactory::newDefault() )->newDefinitionFromArray(
470
					[
471
						'name' => 'some-list',
472
						'type' => 'integer',
473
						'message' => 'test',
474
						'islist' => true
475
					]
476
				)
477
			]
478
		);
479
480
		$this->assertSame(
481
			[ 42, 23, 9001 ],
482
			$processor->processParameters()->getParameters()['some-list']->getValue()
483
		);
484
	}
485
486
}
487