Completed
Push — master ( 20edd5...7d7f4e )
by smiley
02:32
created

QueryTestAbstract::testDelete()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 8
nc 1
nop 0
1
<?php
2
/**
3
 * Class QueryTestAbstract
4
 *
5
 * @filesource   QueryTest.php
6
 * @created      12.05.2017
7
 * @package      chillerlan\DatabaseTest\Query
8
 * @author       Smiley <[email protected]>
9
 * @copyright    2017 Smiley
10
 * @license      MIT
11
 */
12
13
namespace chillerlan\DatabaseTest\Query;
14
15
use chillerlan\Database\{DBQuery, DBResult};
16
use chillerlan\Database\Drivers\DBDriverException;
17
use chillerlan\Database\Query\{
18
	CreateDatabaseInterface, CreateTableInterface, DeleteInterface,
19
	InsertInterface, SelectInterface, StatementInterface, UpdateInterface
20
};
21
use chillerlan\DatabaseTest\TestAbstract;
22
23
abstract class QueryTestAbstract extends TestAbstract{
24
25
	const TEST_DBNAME = 'vagrant';
26
	const TEST_TABLENAME = 'querytest';
27
	/**
28
	 * @var \chillerlan\Database\DBQuery
29
	 */
30
	protected $statement;
31
32
	public function setUp(){
33
		parent::setUp();
34
35
		$this->statement = new DBQuery($this->DBDriver);
36
	}
37
38
	protected function createDatabase(){
39
		$createdb = $this->statement->create->database(self::TEST_DBNAME);
40
		$this->assertInstanceOf(StatementInterface::class, $createdb);
41
		$this->assertInstanceOf(CreateDatabaseInterface::class, $createdb);
42
43
		return $createdb->name(self::TEST_DBNAME)->charset('utf8');
44
	}
45
46
	/**
47
	 * @expectedException \chillerlan\Database\Query\QueryException
48
	 * @expectedExceptionMessage no name specified
49
	 */
50
	public function testCreateDatabaseNoName(){
51
		$this->statement->create->database()->sql();
52
	}
53
54
	public function testCreateTable(){
55
56
		try{
57
			$this->DBDriver->raw('DROP TABLE '.self::TEST_TABLENAME);
58
		}
59
		catch(DBDriverException $e){
60
			var_dump('cannot drop "'.self::TEST_TABLENAME.'", table does not exist');
0 ignored issues
show
Security Debugging Code introduced by
var_dump('cannot drop "'...table does not exist'); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
61
		}
62
63
		$createTable = $this->statement->create->table(self::TEST_DBNAME.'.'.self::TEST_TABLENAME);
64
65
		$this->assertInstanceOf(StatementInterface::class, $createTable);
66
		$this->assertInstanceOf(CreateTableInterface::class, $createTable);
67
68
		$createTable->name(self::TEST_TABLENAME)
69
			->ifNotExists()
70
#			->temp()
71
			->charset('utf8')
72
			->field('id', 'int', 10)
73
			->field('hash', 'varchar', 32)
74
			->field('data', 'text', null, null, 'utf8')
75
			->field('value', 'decimal', '9,6')
76
			->field('active', 'boolean', null, null, null, null, null, 'false')
77
			->field('created', 'timestamp', null, null, null, null, 'CURRENT_TIMESTAMP')
78
			->primaryKey('id')
79
		;
80
81
#		print_r(PHP_EOL.$createTable->sql().PHP_EOL);
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
82
83
		$this->assertTrue($createTable->execute());
0 ignored issues
show
Bug introduced by
It seems like $createTable->execute() targeting chillerlan\Database\Quer...entInterface::execute() can also be of type object<chillerlan\Database\DBResult>; however, PHPUnit\Framework\Assert::assertTrue() does only seem to accept boolean, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
84
	}
85
86
	/**
87
	 * @expectedException \chillerlan\Database\Query\QueryException
88
	 * @expectedExceptionMessage no name specified
89
	 */
90
	public function testCreateTableNoName(){
91
		$this->statement->create->table()->sql();
92
	}
93
94
	public function testInsert(){
95
		$insert = $this->statement->insert;
96
97
		$this->assertInstanceOf(StatementInterface::class, $insert);
98
		$this->assertInstanceOf(InsertInterface::class, $insert);
99
100
		$insert
101
			->into(self::TEST_TABLENAME)
102
			->values(['id' => 0, 'hash' => md5(0), 'data' => 'foo', 'value' => 123.456, 'active' => 1])
103
		;
104
105
#		print_r(PHP_EOL.$insert->sql().PHP_EOL);
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
106
107
		$this->assertTrue($insert->execute());
0 ignored issues
show
Bug introduced by
It seems like $insert->execute() targeting chillerlan\Database\Quer...entInterface::execute() can also be of type object<chillerlan\Database\DBResult>; however, PHPUnit\Framework\Assert::assertTrue() does only seem to accept boolean, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
108
	}
109
110
	public function testInsertMulti(){
111
		$insert = $this->statement->insert;
112
113
		$insert
114
			->into(self::TEST_TABLENAME)
115
			->values([
116
				['id' => 1, 'hash' => md5(1), 'data' => 'foo', 'value' => 123.456,    'active' => 0],
117
				['id' => 2, 'hash' => md5(2), 'data' => 'foo', 'value' => 123.456789, 'active' => 1],
118
				['id' => 3, 'hash' => md5(3), 'data' => 'foo', 'value' => 123.456,    'active' => 0],
119
			])
120
		;
121
122
		$this->assertTrue($insert->execute());
0 ignored issues
show
Bug introduced by
It seems like $insert->execute() targeting chillerlan\Database\Quer...entInterface::execute() can also be of type object<chillerlan\Database\DBResult>; however, PHPUnit\Framework\Assert::assertTrue() does only seem to accept boolean, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
123
	}
124
125
	/**
126
	 * @expectedException \chillerlan\Database\Query\QueryException
127
	 * @expectedExceptionMessage no table specified
128
	 */
129
	public function testInsertNoTable(){
130
		$this->statement->insert->into('')->sql();
131
	}
132
133
	/**
134
	 * @expectedException \chillerlan\Database\Query\QueryException
135
	 * @expectedExceptionMessage no values given
136
	 */
137
	public function testInsertInvalidData(){
138
		$this->statement->insert->into(self::TEST_TABLENAME)->values([])->sql();
139
	}
140
141
	public function testSelect(){
142
		$select = $this->statement->select;
143
		$this->assertInstanceOf(StatementInterface::class, $select);
144
		$this->assertInstanceOf(SelectInterface::class, $select);
145
146
		$select
147
			->cols([
148
				'id'   => 't1.id',
149
				'hash' => ['t1.hash', 'upper'],
150
			])
151
			->from(['t1' => self::TEST_TABLENAME])
152
			->offset(1)
153
			->limit(2);
154
#		print_r(PHP_EOL.$select->sql().PHP_EOL);
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
155
		$result = $select->execute();
156
		$this->assertInstanceOf(DBResult::class, $result);
157
		$this->assertCount(2, $result);
158
#		print_r($result);
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
159
160
		$select = $this->statement->select;
161
		$select
162
			->cols(['id', 'hash', 'value'])
163
			->from([self::TEST_TABLENAME])
164
			->where('active', 1);
165
#		print_r(PHP_EOL.$select->sql().PHP_EOL);
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
166
		$result = $select->execute();
167
		$this->assertInstanceOf(DBResult::class, $result);
168
		$this->assertCount(2, $result);
169
#		print_r($result);
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
170
171
		$select = $this->statement->select;
172
		$select
173
			->from([self::TEST_TABLENAME])
174
			->where('id', [1,2,3], 'in')
175
			->orderBy(['hash' => ['desc', 'lower']]);
176
#		print_r(PHP_EOL.$select->sql().PHP_EOL);
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
177
		$result = $select->execute();
178
#		print_r($result);
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
179
180
		if((bool)$result[0]->active){
181
			// postgres t/f
182
			$this->markTestSkipped('['.$this->DBDriver->dialect.'] invalid boolean value');
0 ignored issues
show
Bug introduced by
Accessing dialect on the interface chillerlan\Database\Drivers\DBDriverInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
183
		}
184
185
		$this->assertCount(3, $result);
186
		$this->assertFalse((bool)$result[0]->active);
187
		$this->assertEquals(3, $result[0]->id); // sqlite will return the id as string, regardless
188
	}
189
190
	/**
191
	 * @expectedException \chillerlan\Database\Query\QueryException
192
	 * @expectedExceptionMessage no FROM expression specified
193
	 */
194
	public function testSelectEmptyFrom(){
195
		$this->statement->select->from([])->sql();
196
	}
197
198
	public function testUpdate(){
199
		$update = $this->statement->update;
200
		$this->assertInstanceOf(StatementInterface::class, $update);
201
		$this->assertInstanceOf(UpdateInterface::class, $update);
202
203
		$update
204
			->table(self::TEST_TABLENAME)
205
			->set([
206
				'data'   => 'bar',
207
				'value'  => 42.42,
208
				'active' => 1,
209
			])
210
			->where('id', 1)
211
		;
212
213
#		print_r(PHP_EOL.$update->sql().PHP_EOL);
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
214
		$this->assertTrue($update->execute());
0 ignored issues
show
Bug introduced by
It seems like $update->execute() targeting chillerlan\Database\Quer...entInterface::execute() can also be of type object<chillerlan\Database\DBResult>; however, PHPUnit\Framework\Assert::assertTrue() does only seem to accept boolean, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
215
216
		$r = $this->statement->select->from([self::TEST_TABLENAME])->where('id' ,1)->execute();
217
218
		$this->assertSame('bar', $r[0]->data);
219
		$this->assertSame(42.42, (float)$r[0]->value);
220
		$this->assertTrue((bool)$r[0]->active);
221
	}
222
223
	/**
224
	 * @expectedException \chillerlan\Database\Query\QueryException
225
	 * @expectedExceptionMessage no table specified
226
	 */
227
	public function testUpdateNoTable(){
228
		$this->statement->update->table('')->sql();
229
	}
230
231
	/**
232
	 * @expectedException \chillerlan\Database\Query\QueryException
233
	 * @expectedExceptionMessage no fields to update specified
234
	 */
235
	public function testUpdateNoSet(){
236
		$this->statement->update->table(self::TEST_TABLENAME)->set([])->sql();
237
	}
238
239
	public function testDelete(){
240
		$delete = $this->statement->delete;
241
		$this->assertInstanceOf(StatementInterface::class, $delete);
242
		$this->assertInstanceOf(DeleteInterface::class, $delete);
243
244
		$delete->from(self::TEST_TABLENAME)->where('id', 2);
245
246
#		print_r(PHP_EOL.$delete->sql().PHP_EOL);
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
247
		$this->assertTrue($delete->execute());
0 ignored issues
show
Bug introduced by
It seems like $delete->execute() targeting chillerlan\Database\Quer...entInterface::execute() can also be of type object<chillerlan\Database\DBResult>; however, PHPUnit\Framework\Assert::assertTrue() does only seem to accept boolean, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
248
249
		$r = $this->statement->select->from([self::TEST_TABLENAME])->execute();
250
		$this->assertCount(3,  $r);
251
	}
252
253
	/**
254
	 * @expectedException \chillerlan\Database\Query\QueryException
255
	 * @expectedExceptionMessage no table specified
256
	 */
257
	public function testDeleteNoTable(){
258
		$this->statement->delete->from('')->sql();
259
	}
260
261
262
}
263