SQLTest   A
last analyzed

Complexity

Total Complexity 38

Size/Duplication

Total Lines 394
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 38
eloc 168
c 3
b 0
f 0
dl 0
loc 394
rs 9.36

36 Methods

Rating   Name   Duplication   Size   Complexity  
A testNot() 0 4 1
A testParseInvalidStructure() 0 4 1
A testGetConditionSourceInvalidOperator() 0 4 1
A testGetSortationSourceInvalidDirection() 0 4 1
A testSliceOffsetLimit() 0 9 1
A tearDown() 0 3 1
A testGetConditionSource() 0 40 1
A testAddExpression() 0 10 1
A testToArray() 0 11 1
A testParseInvalid() 0 4 1
A testCombine() 0 3 1
A testGetSortationSourceInvalidName() 0 8 1
A testCompare() 0 3 1
A testMake() 0 4 1
A testParseCompare() 0 8 1
A testGetSortations() 0 7 1
A setUp() 0 8 2
A testGetConditionSourceInvalidName() 0 7 1
A testGetOperators() 0 9 1
A testOr() 0 3 1
A testOrderMultiple() 0 9 1
A testParseInvalidOperator() 0 4 1
A testAddArray() 0 13 1
A testIs() 0 3 1
A testOrderDesc() 0 9 1
A testOrder() 0 9 1
A testGetConditions() 0 6 1
A testParseEmptyArray() 0 3 1
A testGetSortationSource() 0 10 1
A testTranslate() 0 7 1
A testAdd() 0 10 1
A testSort() 0 3 1
A testGetSortationNoSortation() 0 8 1
A testParseCombine() 0 24 2
A testAnd() 0 3 1
A testType() 0 9 1
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-2025
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( \TestHelper::getConfig()->get( 'resource/db/adapter', false ) === false ) {
21
			$this->markTestSkipped( 'No database configured' );
22
		}
23
24
		$conn = \TestHelper::getConnection();
25
		$this->object = new \Aimeos\Base\Criteria\SQL( $conn );
26
	}
27
28
29
	protected function tearDown() : void
30
	{
31
		$this->object = null;
32
	}
33
34
35
	public function testAdd()
36
	{
37
		$expected = $this->object->and( [
38
			$this->object->is( 'test', '==', 'value' ),
39
			$this->object->getConditions(),
40
		] );
41
		$result = $this->object->add( 'test', '==', 'value' );
42
43
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Iface::class, $result );
44
		$this->assertEquals( $expected, $result->getConditions() );
45
	}
46
47
48
	public function testAddArray()
49
	{
50
		$expected = $this->object->and( [
51
			$this->object->and( [
52
				$this->object->is( 'test', '=~', 'value' ),
53
				$this->object->is( 'key', '=~', 'val' )
54
			] ),
55
			$this->object->getConditions()
56
		] );
57
		$result = $this->object->add( ['test' => 'value', 'key' => 'val'], '=~' );
58
59
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Iface::class, $result );
60
		$this->assertEquals( $expected, $result->getConditions() );
61
	}
62
63
64
	public function testAddExpression()
65
	{
66
		$expected = $this->object->and( [
67
			$this->object->is( 'test', '==', 'value' ),
68
			$this->object->getConditions(),
69
		] );
70
		$result = $this->object->add( $this->object->is( 'test', '==', 'value' ) );
71
72
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Iface::class, $result );
73
		$this->assertEquals( $expected, $result->getConditions() );
74
	}
75
76
77
	public function testMake()
78
	{
79
		$func = $this->object->make( 'test', [1, null, 2] );
80
		$this->assertEquals( 'test(1,null,2)', $func );
81
	}
82
83
84
	public function testGetOperators()
85
	{
86
		$expected = array(
87
			'combine' => ['&&', '||', '!'],
88
			'compare' => ['=~', '~=', '==', '!=', '>', '>=', '<', '<=', '-'],
89
			'sort' => ['+', '-'],
90
		);
91
		$actual = $this->object->getOperators();
92
		$this->assertEquals( $expected, $actual );
93
	}
94
95
96
	public function testIs()
97
	{
98
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Expression\Compare\SQL::class, $this->object->is( 'name', '!=', 'value' ) );
99
	}
100
101
102
	public function testCompare()
103
	{
104
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Expression\Compare\SQL::class, $this->object->compare( '!=', 'name', 'value' ) );
105
	}
106
107
108
	public function testAnd()
109
	{
110
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Expression\Combine\SQL::class, $this->object->and( [] ) );
111
	}
112
113
114
	public function testOr()
115
	{
116
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Expression\Combine\SQL::class, $this->object->or( [] ) );
117
	}
118
119
120
	public function testNot()
121
	{
122
		$expr = $this->object->is( 'name', '==', 'value' );
123
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Expression\Combine\SQL::class, $this->object->not( $expr ) );
124
	}
125
126
127
	public function testCombine()
128
	{
129
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Expression\Combine\SQL::class, $this->object->combine( '&&', [] ) );
130
	}
131
132
133
	public function testSort()
134
	{
135
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Expression\Sort\SQL::class, $this->object->sort( '+', 'name' ) );
136
	}
137
138
139
	public function testTranslate()
140
	{
141
		$translations = array( 'int_column' => 'int_col', 'str_column' => 'str_col' );
142
143
		$this->assertEquals( ["str_col"], $this->object->translate( array( $this->object->sort( '+', 'str_column' ) ), $translations ) );
144
		$this->assertEquals( ["str_col"], $this->object->translate( array( $this->object->compare( '==', 'str_column', 1 ) ), $translations ) );
145
		$this->assertEquals( [], $this->object->translate( array( $this->object->and( [] ) ), $translations ) );
146
	}
147
148
149
	public function testGetConditionSource()
150
	{
151
		$types = array( 'int_column' => \Aimeos\Base\DB\Statement\Base::PARAM_INT, 'str_column' => \Aimeos\Base\DB\Statement\Base::PARAM_STR );
152
		$translations = array( 'int_column' => 'int_col', 'str_column' => 'str_col' );
153
		$plugins = array( 'int_column' => new TestSQL() );
154
155
		$this->assertEquals( "1 = 1", $this->object->getConditionSource( $types, $translations ) );
156
157
		$expr = array( $this->object->compare( '==', 'int_column', '10' ), $this->object->compare( '==', 'str_column', 'test' ) );
158
		$this->object->setConditions( $this->object->and( $expr ) );
159
		$this->assertEquals( "( int_col = 10 AND str_col = 'test' )", $this->object->getConditionSource( $types, $translations, $plugins ) );
160
161
		$expr = array( $this->object->compare( '==', 'int_column', array( 1, 2, 4, 8 ) ), $this->object->compare( '==', 'str_column', 'test' ) );
162
		$this->object->setConditions( $this->object->and( $expr ) );
163
		$this->assertEquals( "( int_col IN (1,2,4,8) AND str_col = 'test' )", $this->object->getConditionSource( $types, $translations ) );
164
165
		$expr = array( $this->object->compare( '==', 'int_column', 1 ), $this->object->compare( '~=', 'str_column', array( 't1', 't2', 't3' ) ) );
166
		$this->object->setConditions( $this->object->and( $expr ) );
167
		$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 ) );
168
169
		$expr = array( $this->object->compare( '==', 'int_column', 1 ), $this->object->compare( '!=', 'int_column', 2 ) );
170
		$this->object->setConditions( $this->object->combine( '!', array( $this->object->and( $expr ) ) ) );
171
		$this->assertEquals( " NOT ( ( int_col = 1 AND int_col <> 2 ) )", $this->object->getConditionSource( $types, $translations ) );
172
173
		$expr = array( $this->object->compare( '==', 'int_column', null ), $this->object->compare( '!=', 'str_column', null ) );
174
		$this->object->setConditions( $this->object->and( $expr ) );
175
		$this->assertEquals( "( int_col IS NULL AND str_col IS NOT NULL )", $this->object->getConditionSource( $types, $translations ) );
176
177
		$expr = array( $this->object->compare( '==', 'int_column', 1 ) );
178
		$this->object->setConditions( $this->object->and( $expr ) );
179
		$this->assertEquals( "( int_col = 1 )", $this->object->getConditionSource( $types, $translations ) );
180
181
		$expr = array( $this->object->compare( '==', 'str_column', 'test' ) );
182
		$expr = array( $this->object->compare( '==', 'int_column', 1 ), $this->object->and( $expr ) );
183
		$this->object->setConditions( $this->object->and( $expr ) );
184
		$this->assertEquals( "( int_col = 1 AND ( str_col = 'test' ) )", $this->object->getConditionSource( $types, $translations ) );
185
186
		$types = array( 'column' => \Aimeos\Base\DB\Statement\Base::PARAM_BOOL );
187
		$this->object->setConditions( $this->object->compare( '==', 'column', 1 ) );
188
		$this->assertEquals( "column = 1", $this->object->getConditionSource( $types ) );
189
	}
190
191
192
	public function testGetConditionSourceInvalidName()
193
	{
194
		$types = array( 'int_column' => \Aimeos\Base\DB\Statement\Base::PARAM_INT );
195
196
		$this->object->setConditions( $this->object->compare( '==', 'icol', 10 ) );
197
		$this->expectException( \Aimeos\Base\Exception::class );
198
		$this->object->getConditionSource( $types );
199
	}
200
201
202
	public function testGetConditionSourceInvalidOperator()
203
	{
204
		$this->expectException( \Aimeos\Base\Exception::class );
205
		$this->object->setConditions( $this->object->compare( '?', 'int_column', 10 ) );
206
	}
207
208
209
	public function testGetConditions()
210
	{
211
		$conditions = $this->object->compare( '==', 'int_column', 10 );
212
		$this->object->setConditions( $conditions );
213
		$this->assertEquals( $conditions, $this->object->getConditions() );
214
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Expression\Compare\SQL::class, $conditions );
215
	}
216
217
218
	public function testGetSortationSource()
219
	{
220
		$types = array( 'asc_column' => \Aimeos\Base\DB\Statement\Base::PARAM_INT, 'desc_column' => \Aimeos\Base\DB\Statement\Base::PARAM_STR );
221
		$translations = array( 'asc_column' => 'asc_int_col', 'desc_column' => 'desc_str_col' );
222
223
		$sortations = [];
224
		$sortations[] = $this->object->sort( '+', 'asc_column' );
225
		$sortations[] = $this->object->sort( '-', 'desc_column' );
226
		$this->object->setSortations( $sortations );
227
		$this->assertEquals( 'asc_int_col ASC, desc_str_col DESC', $this->object->getSortationSource( $types, $translations ) );
228
	}
229
230
231
	public function testGetSortationSourceInvalidName()
232
	{
233
		$types = array( 'asc_column' => \Aimeos\Base\DB\Statement\Base::PARAM_INT );
234
		$translations = array( 'asc_column' => 'asc_int_col' );
235
236
		$this->object->setSortations( array( $this->object->sort( '+', 'asc_col' ) ) );
237
		$this->expectException( \Aimeos\Base\Exception::class );
238
		$this->object->getSortationSource( $types, $translations );
239
	}
240
241
242
	public function testGetSortationSourceInvalidDirection()
243
	{
244
		$this->expectException( \Aimeos\Base\Exception::class );
245
		$this->object->setSortations( array( $this->object->sort( '/', 'asc_column' ) ) );
246
	}
247
248
249
	public function testGetSortationNoSortation()
250
	{
251
		$types = array( 'asc_column' => \Aimeos\Base\DB\Statement\Base::PARAM_INT, 'desc_column' => \Aimeos\Base\DB\Statement\Base::PARAM_STR );
252
253
		$this->assertEquals( 'asc_column ASC', $this->object->getSortationSource( $types ) );
254
255
		$translations = array( 'asc_column' => 'asc_int_col', 'desc_column' => 'desc_str_col' );
256
		$this->assertEquals( 'asc_int_col ASC', $this->object->getSortationSource( $types, $translations ) );
257
	}
258
259
260
	public function testOrder()
261
	{
262
		$this->assertEquals( [], $this->object->getSortations() );
263
264
		$sortations = [$this->object->sort( '+', 'asc_column' )];
265
		$result = $this->object->order( 'asc_column' );
266
267
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Iface::class, $result );
268
		$this->assertEquals( $sortations, $this->object->getSortations() );
269
	}
270
271
272
	public function testOrderDesc()
273
	{
274
		$this->assertEquals( [], $this->object->getSortations() );
275
276
		$sortations = [$this->object->sort( '-', 'desc_column' )];
277
		$result = $this->object->order( '-desc_column' );
278
279
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Iface::class, $result );
280
		$this->assertEquals( $sortations, $this->object->getSortations() );
281
	}
282
283
284
	public function testOrderMultiple()
285
	{
286
		$this->assertEquals( [], $this->object->getSortations() );
287
288
		$sortations = [$this->object->sort( '+', 'asc_column' ), $this->object->sort( '-', 'desc_column' )];
289
		$result = $this->object->order( ['asc_column', '-desc_column'] );
290
291
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Iface::class, $result );
292
		$this->assertEquals( $sortations, $this->object->getSortations() );
293
	}
294
295
296
	public function testGetSortations()
297
	{
298
		$this->assertEquals( [], $this->object->getSortations() );
299
300
		$sortations = array( $this->object->sort( '+', 'asc_column' ) );
301
		$this->object->setSortations( $sortations );
302
		$this->assertEquals( $sortations, $this->object->getSortations() );
303
	}
304
305
306
	public function testSliceOffsetLimit()
307
	{
308
		$this->assertEquals( 0, $this->object->getOffset() );
309
		$this->assertEquals( 100, $this->object->getLimit() );
310
311
		$this->object->slice( 10, 20 );
312
313
		$this->assertEquals( 10, $this->object->getOffset() );
314
		$this->assertEquals( 20, $this->object->getLimit() );
315
	}
316
317
318
	public function testParseEmptyArray()
319
	{
320
		$this->assertNull( $this->object->parse( [] ) );
321
	}
322
323
324
	public function testParseInvalid()
325
	{
326
		$this->expectException( \Aimeos\Base\Exception::class );
327
		$this->object->parse( ['=][attribute.id]=15'] );
328
	}
329
330
331
	public function testParseInvalidOperator()
332
	{
333
		$this->expectException( \Aimeos\Base\Exception::class );
334
		$this->object->parse( ['><' => ['name', 'value']] );
335
	}
336
337
338
	public function testParseInvalidStructure()
339
	{
340
		$this->expectException( \Aimeos\Base\Exception::class );
341
		$this->object->parse( ['&&' => ['name', 'value']] );
342
	}
343
344
345
	public function testParseCompare()
346
	{
347
		$condition = $this->object->parse( ['==' => ['name' => 'value']] );
348
349
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Expression\Compare\Iface::class, $condition );
350
		$this->assertEquals( '==', $condition->getOperator() );
351
		$this->assertEquals( 'name', $condition->getName() );
352
		$this->assertEquals( 'value', $condition->getValue() );
353
	}
354
355
356
	public function testParseCombine()
357
	{
358
		$array = array(
359
			'&&' => array(
360
				0 => array(
361
					'==' => array( 'name' => 'value' ),
362
				),
363
				1 => array(
364
					'==' => array( 'name' => 'value' ),
365
				),
366
			),
367
		);
368
369
		$condition = $this->object->parse( $array );
370
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Expression\Combine\Iface::class, $condition );
371
		$this->assertEquals( '&&', $condition->getOperator() );
372
		$this->assertEquals( 2, count( $condition->getExpressions() ) );
373
374
		foreach( $condition->getExpressions() as $expr )
375
		{
376
			$this->assertInstanceOf( \Aimeos\Base\Criteria\Expression\Compare\Iface::class, $expr );
377
			$this->assertEquals( '==', $expr->getOperator() );
378
			$this->assertEquals( 'name', $expr->getName() );
379
			$this->assertEquals( 'value', $expr->getValue() );
380
		}
381
	}
382
383
384
	public function testToArray()
385
	{
386
		$array = [
387
			'&&' => [
388
				['==' => ['stringvar' => 'value']],
389
				['>' => ['intvar' => 10]],
390
			]
391
		];
392
		$this->object->setConditions( $this->object->parse( $array ) );
393
394
		$this->assertEquals( $array, $this->object->__toArray() );
395
	}
396
397
398
	public function testType()
399
	{
400
		$this->assertEquals( \Aimeos\Base\DB\Statement\Base::PARAM_NULL, \Aimeos\Base\Criteria\SQL::type( 'null' ) );
401
		$this->assertEquals( \Aimeos\Base\DB\Statement\Base::PARAM_BOOL, \Aimeos\Base\Criteria\SQL::type( 'bool' ) );
402
		$this->assertEquals( \Aimeos\Base\DB\Statement\Base::PARAM_BOOL, \Aimeos\Base\Criteria\SQL::type( 'boolean' ) );
403
		$this->assertEquals( \Aimeos\Base\DB\Statement\Base::PARAM_INT, \Aimeos\Base\Criteria\SQL::type( 'int' ) );
404
		$this->assertEquals( \Aimeos\Base\DB\Statement\Base::PARAM_INT, \Aimeos\Base\Criteria\SQL::type( 'integer' ) );
405
		$this->assertEquals( \Aimeos\Base\DB\Statement\Base::PARAM_FLOAT, \Aimeos\Base\Criteria\SQL::type( 'float' ) );
406
		$this->assertEquals( \Aimeos\Base\DB\Statement\Base::PARAM_STR, \Aimeos\Base\Criteria\SQL::type( 'string' ) );
407
	}
408
}
409
410
411
/**
412
 * Test plugin class
413
 */
414
class TestSQL implements \Aimeos\Base\Criteria\Plugin\Iface
415
{
416
	public function translate( $value, $type = null )
417
	{
418
		switch( $value )
419
		{
420
			case 'a': return 10;
421
			default: return $value;
422
		}
423
	}
424
425
	public function reverse( $value, $type = null )
426
	{
427
		switch( $value )
428
		{
429
			case 10: return 'a';
430
			default: return $value;
431
		}
432
	}
433
}
434