Skip to content

Commit 0faf80f

Browse files
authored
Merge pull request #9 from blitz-php/1.x-devs
Ajout de tests unitaires
2 parents afcb969 + a739dff commit 0faf80f

21 files changed

Lines changed: 932 additions & 34 deletions

spec/Builder/Binding.spec.php

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
<?php
2+
3+
use BlitzPHP\Database\Builder\BaseBuilder;
4+
use BlitzPHP\Database\Builder\BindingCollection;
5+
use BlitzPHP\Database\Spec\Mock\MockConnection;
6+
7+
use function Kahlan\expect;
8+
9+
describe("Database / Query Builder : Bindings", function() {
10+
11+
beforeEach(function() {
12+
$this->builder = new BaseBuilder(new MockConnection([]));
13+
});
14+
15+
describe("BindingCollection simple", function() {
16+
it(": BindingCollection ajout simple", function() {
17+
$collection = new BindingCollection();
18+
$collection->add('value1');
19+
$collection->add(123);
20+
$collection->add(true);
21+
$collection->add(null);
22+
23+
expect($collection->count())->toBe(4);
24+
expect($collection->getOrdered())->toBe(['value1', 123, true, null]);
25+
});
26+
27+
it(": BindingCollection ajout nommé", function() {
28+
$collection = new BindingCollection();
29+
$collection->addNamed(':name', 'John');
30+
$collection->addNamed(':age', 30);
31+
32+
expect($collection->get('where', ':name'))->toBe('John');
33+
expect($collection->get('where', ':age'))->toBe(30);
34+
});
35+
36+
it(": BindingCollection types", function() {
37+
$collection = new BindingCollection();
38+
$collection->add('string');
39+
$collection->add(123);
40+
$collection->add(true);
41+
$collection->add(null);
42+
43+
$types = $collection->getTypesOrdered();
44+
expect($types[0])->toBe(PDO::PARAM_STR);
45+
expect($types[1])->toBe(PDO::PARAM_INT);
46+
expect($types[2])->toBe(PDO::PARAM_BOOL);
47+
expect($types[3])->toBe(PDO::PARAM_NULL);
48+
});
49+
50+
it(": BindingCollection merge", function() {
51+
$col1 = new BindingCollection();
52+
$col1->add('a')->add('b');
53+
54+
$col2 = new BindingCollection();
55+
$col2->add('c')->add('d');
56+
57+
$col1->merge($col2);
58+
59+
expect($col1->count())->toBe(4);
60+
expect($col1->getOrdered())->toBe(['a', 'b', 'c', 'd']);
61+
});
62+
63+
it(": BindingCollection clear", function() {
64+
$collection = new BindingCollection();
65+
$collection->add('test');
66+
expect($collection->isEmpty())->toBe(false);
67+
68+
$collection->clear();
69+
expect($collection->isEmpty())->toBe(true);
70+
});
71+
72+
it(": Les bindings sont correctement transmis dans la requête", function() {
73+
$builder = $this->builder->testMode()
74+
->from('users')
75+
->where('id', 5)
76+
->where('name', 'John')
77+
->whereIn('status', [1, 2, 3]);
78+
79+
expect($builder->bindings->count())->toBe(5);
80+
expect($builder->bindings->getOrdered())->toBe([5, 'John', 1, 2, 3]);
81+
});
82+
83+
it(": Les bindings sont réinitialisés après exécution", function() {
84+
$builder = $this->builder->from('users')->where('id', 5);
85+
86+
expect($builder->bindings->isEmpty())->toBe(false);
87+
88+
try {
89+
$sql = $builder->get();
90+
} catch(Exception) {
91+
// l'execution ne passera pas car on a pas de bd.
92+
// on veut juste se rassuer que les bindings sont reset
93+
expect($builder->bindings->isEmpty())->toBe(true);
94+
}
95+
});
96+
97+
it(": Les bindings sont préservés dans les sous-requêtes", function() {
98+
$builder = $this->builder->testMode()
99+
->from('users')
100+
->whereIn('id', function($q) {
101+
$q->from('profiles')
102+
->select('user_id')
103+
->where('active', 1)
104+
->where('points >', 100);
105+
});
106+
107+
expect($builder->bindings->count())->toBe(2);
108+
expect($builder->bindings->getOrdered())->toBe([1, 100]);
109+
});
110+
});
111+
112+
describe("BindingCollection avec types", function() {
113+
it(": getOrdered avec types spécifiques", function() {
114+
$bindings = new BindingCollection();
115+
$bindings->add('value1', 'values');
116+
$bindings->add(5, 'where');
117+
$bindings->add('join_cond', 'join');
118+
119+
expect($bindings->getOrdered(['values', 'where']))->toBe(['value1', 5]);
120+
expect($bindings->getOrdered(['where', 'values']))->toBe([5, 'value1']);
121+
expect($bindings->getOrdered())->toHaveLength(3);
122+
});
123+
124+
it(": getOrdered ignore les types vides", function() {
125+
$bindings = new BindingCollection();
126+
$bindings->add('value1', 'values');
127+
128+
expect($bindings->getOrdered(['values', 'where', 'having']))->toBe(['value1']);
129+
});
130+
});
131+
132+
describe("BaseBuilder::getBindings", function() {
133+
it(": UPDATE - valeurs avant where", function() {
134+
$builder = $this->builder->table('users')
135+
->where('id', 5)
136+
->where('active', 1)
137+
->set(['name' => 'John'])
138+
->pending() // pour eviter l'execution
139+
->update();
140+
141+
expect($builder->getBindings())->toBe(['John', 5, 1]);
142+
});
143+
144+
it(": INSERT - seulement valeurs", function() {
145+
$builder = $this->builder->table('users')
146+
->set(['name' => 'John', 'age' => 30])
147+
->pending() // pour eviter l'execution
148+
->insert();
149+
150+
expect($builder->getBindings())->toBe(['John', 30]);
151+
});
152+
153+
it(": SELECT - where dans l'ordre", function() {
154+
$builder = $this->builder->table('users')
155+
->where('id', 5)
156+
->where('name', 'John')
157+
->orderBy('created_at');
158+
159+
expect($builder->getBindings())->toBe([5, 'John']);
160+
});
161+
});
162+
});

spec/Builder/Count.spec.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,34 +18,36 @@
1818
it(": Nombre de ligne avec condition", function() {
1919
$builder = $this->builder->testMode()->from('jobs j')->where('id >', 3);
2020

21-
expect($builder->count())->toBe('SELECT COUNT(*) AS count_value FROM jobs AS j WHERE id > 3');
21+
expect($builder->getBindings())->toBe([3]);
22+
expect($builder->count())->toBe('SELECT COUNT(*) AS count_value FROM jobs AS j WHERE id > ?');
2223
});
2324

2425
it(": Nombre de ligne avec regroupement", function() {
2526
$builder = $this->builder->testMode()->from('jobs j')->where('id >', 3)->groupBy('id');
2627

27-
expect($builder->bindings->getValues())->toBe([3]);
28+
expect($builder->getBindings())->toBe([3]);
2829
expect($builder->count())->toBe('SELECT COUNT(*) AS count_value FROM (SELECT * FROM jobs AS j WHERE id > ? GROUP BY id) AS count_table');
2930
});
3031

3132
it(": Compter tous les résultats avec GroupBy et le prefixe de la base de données", function() {
3233
$this->builder->db()->setPrefix('db_');
3334
$builder = $this->builder->testMode()->select('j.*')->from('jobs j')->where('id >', 3)->groupBy('id');
3435

35-
expect($builder->bindings->getValues())->toBe([3]);
36+
expect($builder->getBindings())->toBe([3]);
3637
expect($builder->count())->toBe('SELECT COUNT(*) AS count_value FROM (SELECT j.* FROM db_jobs AS j WHERE id > ? GROUP BY id) AS count_table');
3738
});
3839

3940
it(": Compter tous les résultats avec GroupBy et Having", function() {
4041
$builder = $this->builder->testMode()->from('jobs j')->where('id >', 3)->groupBy('id')->having('1=1');
4142

42-
expect($builder->bindings->getValues())->toBe([3, 1]);
43+
expect($builder->getBindings())->toBe([3, 1]);
4344
expect($builder->count())->toBe('SELECT COUNT(*) AS count_value FROM (SELECT * FROM jobs AS j WHERE id > ? GROUP BY id HAVING 1 = ?) AS count_table');
4445
});
4546

4647
it(": Compter tous les résultats avec Having uniquement", function() {
4748
$builder = $this->builder->testMode()->from('jobs j')->where('id >', 3)->having('1=1');
4849

49-
expect($builder->count())->toBe('SELECT COUNT(*) AS count_value FROM jobs AS j WHERE id > 3 HAVING 1 = 1');
50+
expect($builder->getBindings())->toBe([3, 1]);
51+
expect($builder->count())->toBe('SELECT COUNT(*) AS count_value FROM jobs AS j WHERE id > ? HAVING 1 = ?');
5052
});
5153
});

spec/Builder/Delete.spec.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545

4646
it(": Suppression avec limite", function() {
4747
$builder = $this->builder->testMode()->from('jobs')->where('id', 1)->limit(10);
48-
expect($builder->bindings->getValues())->toBe([1]);
48+
expect($builder->getBindings())->toBe([1]);
4949
expect($builder->delete())->toBe('DELETE FROM jobs WHERE id = 1 LIMIT 10');
5050
});
5151
});

spec/Builder/Json.spec.php

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php
2+
3+
use BlitzPHP\Database\Builder\BaseBuilder;
4+
use BlitzPHP\Database\Spec\Mock\MockConnection;
5+
6+
describe("Database / Query Builder : JSON", function() {
7+
8+
beforeEach(function() {
9+
$this->builder = new BaseBuilder(new MockConnection([]));
10+
});
11+
12+
it(": whereJsonContains", function() {
13+
$builder = $this->builder->testMode()
14+
->from('users')
15+
->whereJsonContains('preferences->languages', 'fr');
16+
17+
expect($builder->toSql())->toBe(
18+
"SELECT * FROM users WHERE JSON_CONTAINS(preferences->languages, ?)"
19+
);
20+
expect($builder->getBindings())->toBe(['fr']);
21+
});
22+
23+
it(": whereJsonDoesntContain", function() {
24+
$builder = $this->builder->testMode()
25+
->from('users')
26+
->whereJsonDoesntContain('preferences->tags', 'premium');
27+
28+
expect($builder->toSql())->toBe(
29+
"SELECT * FROM users WHERE NOT JSON_CONTAINS(preferences->tags, ?)"
30+
);
31+
expect($builder->getBindings())->toBe(['premium']);
32+
});
33+
34+
it(": whereJsonContainsKey", function() {
35+
$builder = $this->builder->testMode()
36+
->from('users')
37+
->whereJsonContainsKey('settings->notifications');
38+
39+
expect($builder->sql())->toBe(
40+
"SELECT * FROM users WHERE JSON_CONTAINS_PATH(settings->notifications, 'one', ?) = 1"
41+
);
42+
});
43+
44+
it(": whereJsonLength", function() {
45+
$builder = $this->builder->testMode()
46+
->from('users')
47+
->whereJsonLength('preferences->items', '>', 5);
48+
49+
expect($builder->toSql())->toBe(
50+
"SELECT * FROM users WHERE JSON_LENGTH(preferences->items) > ?"
51+
);
52+
expect($builder->getBindings())->toBe([5]);
53+
});
54+
55+
it(": orWhereJsonContains", function() {
56+
$builder = $this->builder->testMode()
57+
->from('users')
58+
->where('active', 1)
59+
->orWhereJsonContains('preferences->languages', 'en');
60+
61+
expect($builder->toSql())->toBe(
62+
"SELECT * FROM users WHERE active = ? OR JSON_CONTAINS(preferences->languages, ?)"
63+
);
64+
expect($builder->getBindings())->toBe([1, 'en']);
65+
});
66+
});

spec/Builder/Union.spec.php

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<?php
2+
3+
use BlitzPHP\Database\Builder\BaseBuilder;
4+
use BlitzPHP\Database\Spec\Mock\MockConnection;
5+
6+
describe("Database / Query Builder : UNION", function() {
7+
8+
beforeEach(function() {
9+
$this->builder = new BaseBuilder(new MockConnection([]));
10+
});
11+
12+
it(": UNION simple", function() {
13+
$builder = $this->builder->testMode()
14+
->from('users')
15+
->select('name, email')
16+
->where('active', 1)
17+
->union(function($q) {
18+
$q->from('deleted_users')
19+
->select('name, email')
20+
->where('restored', 0);
21+
});
22+
23+
expect($builder->toSql())->toBe(
24+
"SELECT name, email FROM users WHERE active = ? " .
25+
"UNION SELECT name, email FROM deleted_users WHERE restored = ?"
26+
);
27+
expect($builder->getBindings())->toBe([1, 0]);
28+
});
29+
30+
it(": UNION ALL", function() {
31+
$builder = $this->builder->testMode()
32+
->from('orders_2023')
33+
->select('id, total')
34+
->unionAll(function($q) {
35+
$q->from('orders_2024')
36+
->select('id, total');
37+
});
38+
39+
expect($builder->sql())->toBe(
40+
"SELECT id, total FROM orders_2023 " .
41+
"UNION ALL SELECT id, total FROM orders_2024"
42+
);
43+
});
44+
45+
it(": UNION multiples", function() {
46+
$builder = $this->builder->testMode()
47+
->from('q1')
48+
->select('data')
49+
->union(function($q) { $q->from('q2')->select('data'); })
50+
->union(function($q) { $q->from('q3')->select('data'); });
51+
52+
expect($builder->sql())->toBe(
53+
"SELECT data FROM q1 " .
54+
"UNION SELECT data FROM q2 " .
55+
"UNION SELECT data FROM q3"
56+
);
57+
});
58+
59+
it(": UNION avec ORDER BY et LIMIT", function() {
60+
$builder = $this->builder->testMode()
61+
->from('products')
62+
->select('name, price')
63+
->union(function($q) {
64+
$q->from('archived_products')
65+
->select('name, price');
66+
})
67+
->orderBy('price', 'DESC')
68+
->limit(10);
69+
70+
expect($builder->sql())->toBe(
71+
"SELECT name, price FROM products " .
72+
"UNION SELECT name, price FROM archived_products " .
73+
"ORDER BY price DESC LIMIT 10"
74+
);
75+
});
76+
77+
it(": UNION avec sous-requête complexe", function() {
78+
$subquery = (new BaseBuilder(new MockConnection([])))
79+
->from('logs')
80+
->select('user_id, COUNT(*) as count')
81+
->groupBy('user_id')
82+
->having('count >', 5);
83+
84+
$builder = $this->builder->testMode()
85+
->from('users')
86+
->select('id, name')
87+
->union(function($q) use ($subquery) {
88+
$q->fromSubquery($subquery, 'active_logs')
89+
->select('user_id as id, count as name');
90+
});
91+
92+
expect($builder->toSql())->toBe(
93+
"SELECT id, name FROM users " .
94+
"UNION SELECT user_id AS id, count AS name FROM " .
95+
"(SELECT user_id, COUNT(*) as count FROM logs GROUP BY user_id HAVING count > ?) AS active_logs"
96+
);
97+
expect($builder->getBindings())->toBe([5]);
98+
});
99+
});

0 commit comments

Comments
 (0)