Passed
Push — master ( 9b3ef7...f502a6 )
by Aimeos
02:50
created

SQLTest::testNot()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
/**
4
 * @license LGPLv3, https://opensource.org/licenses/LGPL-3.0
5
 * @copyright Metaways Infosystems GmbH, 2011
6
 * @copyright Aimeos (aimeos.org), 2015-2022
7
 */
8
9
10
namespace Aimeos\Base\Criteria;
11
12
13
class SQLTest extends \PHPUnit\Framework\TestCase
14
{
15
	private $object;
16
17
18
	protected function setUp() : void
19
	{
20
		if( \TestHelperMw::getConfig()->get( 'resource/db/adapter', false ) === false ) {
0 ignored issues
show
Bug introduced by
The type TestHelperMw was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
			$this->markTestSkipped( 'No database configured' );
22
		}
23
24
25
		$dbm = \TestHelperMw::getDBManager();
26
27
		$conn = $dbm->acquire();
28
		$this->object = new \Aimeos\Base\Criteria\SQL( $conn );
29
		$dbm->release( $conn );
30
	}
31
32
33
	protected function tearDown() : void
34
	{
35
		$this->object = null;
36
	}
37
38
39
	public function testAdd()
40
	{
41
		$expected = $this->object->and( [
42
			$this->object->is( 'test', '==', 'value' ),
43
			$this->object->getConditions(),
44
		] );
45
		$result = $this->object->add( 'test', '==', 'value' );
46
47
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Iface::class, $result );
48
		$this->assertEquals( $expected, $result->getConditions() );
49
	}
50
51
52
	public function testAddArray()
53
	{
54
		$expected = $this->object->and( [
55
			$this->object->and( [
56
				$this->object->is( 'test', '=~', 'value' ),
57
				$this->object->is( 'key', '=~', 'val' )
58
			] ),
59
			$this->object->getConditions()
60
		] );
61
		$result = $this->object->add( ['test' => 'value', 'key' => 'val'], '=~' );
62
63
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Iface::class, $result );
64
		$this->assertEquals( $expected, $result->getConditions() );
65
	}
66
67
68
	public function testAddExpression()
69
	{
70
		$expected = $this->object->and( [
71
			$this->object->is( 'test', '==', 'value' ),
72
			$this->object->getConditions(),
73
		] );
74
		$result = $this->object->add( $this->object->is( 'test', '==', 'value' ) );
75
76
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Iface::class, $result );
77
		$this->assertEquals( $expected, $result->getConditions() );
78
	}
79
80
81
	public function testMake()
82
	{
83
		$func = $this->object->make( 'test', [1, null, 2] );
84
		$this->assertEquals( 'test(1,null,2)', $func );
85
	}
86
87
88
	public function testGetOperators()
89
	{
90
		$expected = array(
91
			'combine' => ['&&', '||', '!'],
92
			'compare' => ['=~', '~=', '==', '!=', '>', '>=', '<', '<=', '-'],
93
			'sort' => ['+', '-'],
94
		);
95
		$actual = $this->object->getOperators();
96
		$this->assertEquals( $expected, $actual );
97
	}
98
99
100
	public function testIs()
101
	{
102
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Expression\Compare\SQL::class, $this->object->is( 'name', '!=', 'value' ) );
103
	}
104
105
106
	public function testCompare()
107
	{
108
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Expression\Compare\SQL::class, $this->object->compare( '!=', 'name', 'value' ) );
109
	}
110
111
112
	public function testAnd()
113
	{
114
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Expression\Combine\SQL::class, $this->object->and( [] ) );
115
	}
116
117
118
	public function testOr()
119
	{
120
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Expression\Combine\SQL::class, $this->object->or( [] ) );
121
	}
122
123
124
	public function testNot()
125
	{
126
		$expr = $this->object->is( 'name', '==', 'value' );
127
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Expression\Combine\SQL::class, $this->object->not( $expr ) );
128
	}
129
130
131
	public function testCombine()
132
	{
133
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Expression\Combine\SQL::class, $this->object->combine( '&&', [] ) );
134
	}
135
136
137
	public function testSort()
138
	{
139
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Expression\Sort\SQL::class, $this->object->sort( '+', 'name' ) );
140
	}
141
142
143
	public function testTranslate()
144
	{
145
		$translations = array( 'int_column' => 'int_col', 'str_column' => 'str_col' );
146
147
		$this->assertEquals( ["str_col"], $this->object->translate( array( $this->object->sort( '+', 'str_column' ) ), $translations ) );
148
		$this->assertEquals( ["str_col"], $this->object->translate( array( $this->object->compare( '==', 'str_column', 1 ) ), $translations ) );
149
		$this->assertEquals( [], $this->object->translate( array( $this->object->and( [] ) ), $translations ) );
150
	}
151
152
153
	public function testGetConditionSource()
154
	{
155
		$types = array( 'int_column' => \Aimeos\Base\DB\Statement\Base::PARAM_INT, 'str_column' => \Aimeos\Base\DB\Statement\Base::PARAM_STR );
156
		$translations = array( 'int_column' => 'int_col', 'str_column' => 'str_col' );
157
		$plugins = array( 'int_column' => new TestSQL() );
158
159
		$this->assertEquals( "1 = 1", $this->object->getConditionSource( $types, $translations ) );
160
161
		$expr = array( $this->object->compare( '==', 'int_column', 'a' ), $this->object->compare( '==', 'str_column', 'test' ) );
162
		$this->object->setConditions( $this->object->and( $expr ) );
163
		$this->assertEquals( "( int_col = 10 AND str_col = 'test' )", $this->object->getConditionSource( $types, $translations, $plugins ) );
164
165
		$expr = array( $this->object->compare( '==', 'int_column', array( 1, 2, 4, 8 ) ), $this->object->compare( '==', 'str_column', 'test' ) );
166
		$this->object->setConditions( $this->object->and( $expr ) );
167
		$this->assertEquals( "( int_col IN (1,2,4,8) AND str_col = 'test' )", $this->object->getConditionSource( $types, $translations ) );
168
169
		$expr = array( $this->object->compare( '==', 'int_column', 1 ), $this->object->compare( '~=', 'str_column', array( 't1', 't2', 't3' ) ) );
170
		$this->object->setConditions( $this->object->and( $expr ) );
171
		$this->assertEquals( "( int_col = 1 AND (str_col LIKE '%t1%' ESCAPE '#' OR str_col LIKE '%t2%' ESCAPE '#' OR str_col LIKE '%t3%' ESCAPE '#') )", $this->object->getConditionSource( $types, $translations ) );
172
173
		$expr = array( $this->object->compare( '==', 'int_column', 1 ), $this->object->compare( '!=', 'int_column', 2 ) );
174
		$this->object->setConditions( $this->object->combine( '!', array( $this->object->and( $expr ) ) ) );
175
		$this->assertEquals( " NOT ( ( int_col = 1 AND int_col <> 2 ) )", $this->object->getConditionSource( $types, $translations ) );
176
177
		$expr = array( $this->object->compare( '==', 'int_column', null ), $this->object->compare( '!=', 'str_column', null ) );
178
		$this->object->setConditions( $this->object->and( $expr ) );
179
		$this->assertEquals( "( int_col IS NULL AND str_col IS NOT NULL )", $this->object->getConditionSource( $types, $translations ) );
180
181
		$expr = array( $this->object->compare( '==', 'int_column', 1 ) );
182
		$this->object->setConditions( $this->object->and( $expr ) );
183
		$this->assertEquals( "( int_col = 1 )", $this->object->getConditionSource( $types, $translations ) );
184
185
		$expr = array( $this->object->compare( '==', 'str_column', 'test' ) );
186
		$expr = array( $this->object->compare( '==', 'int_column', 1 ), $this->object->and( $expr ) );
187
		$this->object->setConditions( $this->object->and( $expr ) );
188
		$this->assertEquals( "( int_col = 1 AND ( str_col = 'test' ) )", $this->object->getConditionSource( $types, $translations ) );
189
190
		$types = array( 'column' => \Aimeos\Base\DB\Statement\Base::PARAM_BOOL );
191
		$this->object->setConditions( $this->object->compare( '==', 'column', 1 ) );
192
		$this->assertEquals( "column = 1", $this->object->getConditionSource( $types ) );
193
	}
194
195
196
	public function testGetConditionSourceInvalidName()
197
	{
198
		$types = array( 'int_column' => \Aimeos\Base\DB\Statement\Base::PARAM_INT );
199
200
		$this->object->setConditions( $this->object->compare( '==', 'icol', 10 ) );
201
		$this->expectException( \Aimeos\Base\Common\Exception::class );
0 ignored issues
show
Bug introduced by
The type Aimeos\Base\Common\Exception was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
202
		$this->object->getConditionSource( $types );
203
	}
204
205
206
	public function testGetConditionSourceInvalidOperator()
207
	{
208
		$this->expectException( \Aimeos\Base\Common\Exception::class );
209
		$this->object->setConditions( $this->object->compare( '?', 'int_column', 10 ) );
210
	}
211
212
213
	public function testGetConditions()
214
	{
215
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Expression\Compare\SQL::class, $this->object->getConditions() );
216
217
		$conditions = $this->object->compare( '==', 'int_column', 10 );
218
		$this->object->setConditions( $conditions );
219
		$this->assertEquals( $conditions, $this->object->getConditions() );
220
	}
221
222
223
	public function testGetSortationSource()
224
	{
225
		$types = array( 'asc_column' => \Aimeos\Base\DB\Statement\Base::PARAM_INT, 'desc_column' => \Aimeos\Base\DB\Statement\Base::PARAM_STR );
226
		$translations = array( 'asc_column' => 'asc_int_col', 'desc_column' => 'desc_str_col' );
227
228
		$sortations = [];
229
		$sortations[] = $this->object->sort( '+', 'asc_column' );
230
		$sortations[] = $this->object->sort( '-', 'desc_column' );
231
		$this->object->setSortations( $sortations );
232
		$this->assertEquals( 'asc_int_col ASC, desc_str_col DESC', $this->object->getSortationSource( $types, $translations ) );
233
	}
234
235
236
	public function testGetSortationSourceInvalidName()
237
	{
238
		$types = array( 'asc_column' => \Aimeos\Base\DB\Statement\Base::PARAM_INT );
239
		$translations = array( 'asc_column' => 'asc_int_col' );
240
241
		$this->object->setSortations( array( $this->object->sort( '+', 'asc_col' ) ) );
242
		$this->expectException( \Aimeos\Base\Common\Exception::class );
243
		$this->object->getSortationSource( $types, $translations );
244
	}
245
246
247
	public function testGetSortationSourceInvalidDirection()
248
	{
249
		$this->expectException( \Aimeos\Base\Common\Exception::class );
250
		$this->object->setSortations( array( $this->object->sort( '/', 'asc_column' ) ) );
251
	}
252
253
254
	public function testGetSortationNoSortation()
255
	{
256
		$types = array( 'asc_column' => \Aimeos\Base\DB\Statement\Base::PARAM_INT, 'desc_column' => \Aimeos\Base\DB\Statement\Base::PARAM_STR );
257
258
		$this->assertEquals( 'asc_column ASC', $this->object->getSortationSource( $types ) );
259
260
		$translations = array( 'asc_column' => 'asc_int_col', 'desc_column' => 'desc_str_col' );
261
		$this->assertEquals( 'asc_int_col ASC', $this->object->getSortationSource( $types, $translations ) );
262
	}
263
264
265
	public function testOrder()
266
	{
267
		$this->assertEquals( [], $this->object->getSortations() );
268
269
		$sortations = [$this->object->sort( '+', 'asc_column' )];
270
		$result = $this->object->order( 'asc_column' );
271
272
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Iface::class, $result );
273
		$this->assertEquals( $sortations, $this->object->getSortations() );
274
	}
275
276
277
	public function testOrderDesc()
278
	{
279
		$this->assertEquals( [], $this->object->getSortations() );
280
281
		$sortations = [$this->object->sort( '-', 'desc_column' )];
282
		$result = $this->object->order( '-desc_column' );
283
284
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Iface::class, $result );
285
		$this->assertEquals( $sortations, $this->object->getSortations() );
286
	}
287
288
289
	public function testOrderMultiple()
290
	{
291
		$this->assertEquals( [], $this->object->getSortations() );
292
293
		$sortations = [$this->object->sort( '+', 'asc_column' ), $this->object->sort( '-', 'desc_column' )];
294
		$result = $this->object->order( ['asc_column', '-desc_column'] );
295
296
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Iface::class, $result );
297
		$this->assertEquals( $sortations, $this->object->getSortations() );
298
	}
299
300
301
	public function testGetSortations()
302
	{
303
		$this->assertEquals( [], $this->object->getSortations() );
304
305
		$sortations = array( $this->object->sort( '+', 'asc_column' ) );
306
		$this->object->setSortations( $sortations );
307
		$this->assertEquals( $sortations, $this->object->getSortations() );
308
	}
309
310
311
	public function testSliceOffsetLimit()
312
	{
313
		$this->assertEquals( 0, $this->object->getOffset() );
314
		$this->assertEquals( 100, $this->object->getLimit() );
315
316
		$this->object->slice( 10, 20 );
317
318
		$this->assertEquals( 10, $this->object->getOffset() );
319
		$this->assertEquals( 20, $this->object->getLimit() );
320
	}
321
322
323
	public function testParseEmptyArray()
324
	{
325
		$this->assertNull( $this->object->parse( [] ) );
326
	}
327
328
329
	public function testParseInvalid()
330
	{
331
		$this->expectException( \Aimeos\Base\Common\Exception::class );
332
		$this->object->parse( ['=][attribute.id]=15'] );
333
	}
334
335
336
	public function testParseInvalidOperator()
337
	{
338
		$this->expectException( \Aimeos\Base\Common\Exception::class );
339
		$this->object->parse( ['><' => ['name', 'value']] );
340
	}
341
342
343
	public function testParseInvalidStructure()
344
	{
345
		$this->expectException( \Aimeos\Base\Common\Exception::class );
346
		$this->object->parse( ['&&' => ['name', 'value']] );
347
	}
348
349
350
	public function testParseCompare()
351
	{
352
		$condition = $this->object->parse( ['==' => ['name' => 'value']] );
353
354
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Expression\Compare\Iface::class, $condition );
355
		$this->assertEquals( '==', $condition->getOperator() );
356
		$this->assertEquals( 'name', $condition->getName() );
357
		$this->assertEquals( 'value', $condition->getValue() );
358
	}
359
360
361
	public function testParseCombine()
362
	{
363
		$array = array(
364
			'&&' => array(
365
				0 => array(
366
					'==' => array( 'name' => 'value' ),
367
				),
368
				1 => array(
369
					'==' => array( 'name' => 'value' ),
370
				),
371
			),
372
		);
373
374
		$condition = $this->object->parse( $array );
375
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Expression\Combine\Iface::class, $condition );
376
		$this->assertEquals( '&&', $condition->getOperator() );
377
		$this->assertEquals( 2, count( $condition->getExpressions() ) );
378
379
		foreach( $condition->getExpressions() as $expr )
380
		{
381
			$this->assertInstanceOf( \Aimeos\Base\Criteria\Expression\Compare\Iface::class, $expr );
382
			$this->assertEquals( '==', $expr->getOperator() );
383
			$this->assertEquals( 'name', $expr->getName() );
384
			$this->assertEquals( 'value', $expr->getValue() );
385
		}
386
	}
387
388
389
	public function testToArray()
390
	{
391
		$array = [
392
			'&&' => [
393
				['==' => ['stringvar' => 'value']],
394
				['>' => ['intvar' => 10]],
395
			]
396
		];
397
		$this->object->setConditions( $this->object->parse( $array ) );
398
399
		$this->assertEquals( $array, $this->object->__toArray() );
400
	}
401
}
402
403
404
/**
405
 * Test plugin class
406
 */
407
class TestSQL implements \Aimeos\Base\Criteria\Plugin\Iface
408
{
409
	public function translate( $value )
410
	{
411
		switch( $value )
412
		{
413
			case 'a': return 10;
414
			default: return $value;
415
		}
416
	}
417
418
	public function reverse( $value )
419
	{
420
		switch( $value )
421
		{
422
			case 10: return 'a';
423
			default: return $value;
424
		}
425
	}
426
}
427