Completed
Push — master ( 6ecafd...3d8b1a )
by Dmitry
03:08
created

TarantoolTest   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 329
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 7
c 0
b 0
f 0
dl 0
loc 329
rs 10

14 Methods

Rating   Name   Duplication   Size   Complexity  
A testPool() 0 21 1
B hp$0 ➔ run() 0 36 1
A tearDown() 0 17 3
A testProcedureRegistration() 0 4 1
B testMigrationOrder() 0 37 2
A testMigrationGenerator() 0 14 1
A testEntity() 0 21 1
A testRepositoryRegistration() 0 5 1
A testJobShortcuts() 0 49 1
A testPoolConfiguration() 0 10 1
A testSelectRegistration() 0 10 1
A testSelectUsage() 0 47 1
B testSelectUsageWithCompositeKeys() 0 32 1
B testSelectUsageWithNestedStructures() 0 30 1
1
<?php
2
3
namespace Test;
4
5
use Basis\Filesystem;
6
use Basis\Job;
7
use Basis\Procedure\Select;
8
use Basis\Test;
9
use Exception;
10
use Procedure\Greet;
11
use ReflectionClass;
12
use Repository\Note;
13
use Tarantool\Mapper\Bootstrap;
14
use Tarantool\Mapper\Mapper;
15
use Tarantool\Mapper\Pool;
16
17
class TarantoolTest extends Test
18
{
19
    public $data = [
20
        'guard.session' => [],
21
        'web.services' => [
22
            ['id' => 1, 'name' => 'tester'],
23
            ['id' => 2, 'name' => 'basis'],
24
            ['id' => 3, 'name' => 'web'],
25
        ],
26
        'tester.data' => [
27
            ['id' => 3, 'value' => 'test'],
28
            ['id' => 4, 'value' => 'test'],
29
        ],
30
    ];
31
32
    public $mocks = [
33
        ['web.services', [], ['services' => ['web', 'tester', 'basis']]]
34
    ];
35
36
    public function testPool()
37
    {
38
        $web = $this->get(Pool::class)->get('web');
39
        $this->assertCount(3, $web->find('services'));
40
        $this->assertCount(1, $web->find('services', ['name' => 'web']));
41
42
        $tester = $this->get(Pool::class)->get('tester');
43
        $this->assertCount(0, $tester->find('data', ['id' => 2]));
44
        $this->assertCount(1, $tester->find('data', ['id' => 3]));
45
        $this->assertCount(2, $tester->find('data', ['value' => 'test']));
46
47
        $this->data['web.services'][] = ['id' => 4, 'name' => 'guard'];
48
        $this->assertCount(4, $web->find('services'));
49
50
        $this->assertSame($tester->findOne('data', ['value' => 'test'])->id, 3);
51
        $this->assertSame($tester->findOrFail('data', ['value' => 'test'])->id, 3);
52
        $this->assertNull($tester->findOne('data', ['id' => 1]));
53
54
        $this->expectException(Exception::class);
55
        $tester->findOrFail('data', ['id' => 1]);
56
    }
57
58
    public function tearDown()
59
    {
60
        $fs = $this->app->get(Filesystem::class);
61
        $classes = $fs->listClasses('Migration');
62
63
        $dirs = [];
64
        foreach ($classes as $class) {
65
            $filename = $fs->getPath('php/'.str_replace('\\', '/', $class).'.php');
66
            unlink($filename);
67
            $dirs[dirname($filename)] = true;
68
        }
69
        foreach ($dirs as $dir => $_) {
70
            rmdir($dir);
71
        }
72
73
        parent::tearDown();
74
    }
75
76
    public function testProcedureRegistration()
77
    {
78
        $this->assertSame($this->app->get(Greet::class)('Dmitry'), 'Hello, Dmitry!');
79
    }
80
81
    public function testMigrationOrder()
82
    {
83
        $migration = $this->app->dispatch('generate.migration', [
84
            'name' => 'b',
85
        ]);
86
        $contents = file_get_contents($migration->filename);
87
        $contents = str_replace('throw', '//throw', $contents);
88
        file_put_contents($migration->filename, $contents);
89
90
        sleep(1);
91
92
        $migration = $this->app->dispatch('generate.migration', [
93
            'name' => 'a',
94
        ]);
95
96
        $contents = file_get_contents($migration->filename);
97
        $contents = str_replace('throw', '//throw', $contents);
98
        file_put_contents($migration->filename, $contents);
99
100
        $this->app->dispatch('tarantool.migrate');
101
102
        $bootstrap = $this->app->get(Bootstrap::class);
103
104
        $reflection = new ReflectionClass(Bootstrap::class);
105
        $property = $reflection->getProperty('migrations');
106
        $property->setAccessible(true);
107
108
        $migrations = $property->getValue($bootstrap);
109
110
        $this->assertCount(2, $migrations);
111
112
        $order = [];
113
        foreach ($migrations as $migration) {
114
            $order[] = substr($migration, -1);
115
        }
116
        $this->assertSame(['B', 'A'], $order);
117
    }
118
119
    public function testMigrationGenerator()
120
    {
121
        $fs = $this->app->get(Filesystem::class);
122
123
        $classes = $fs->listClasses('Migration');
124
        $this->assertCount(0, $classes);
125
126
        $this->app->dispatch('generate.migration', [
127
            'name' => 'my migration created at ' . time(),
128
        ]);
129
130
        $classes = $fs->listClasses('Migration');
131
        $this->assertCount(1, $classes);
132
    }
133
134
    public function testEntity()
135
    {
136
        $mapper = $this->app->get(Mapper::class);
137
        $mapper->getRepository('note')->truncate();
138
        $note = $mapper->getRepository('note')->create('zzz');
139
        $this->assertSame($note->message, 'zzz');
140
141
        $note->message = 'test';
142
        $note->save();
143
144
        $this->assertNotNull($note->id);
145
        $this->assertSame($note->message, 'test');
146
147
        $this->assertSame($note->app, $this->app);
148
149
        ob_start();
150
        var_dump($note);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($note); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
151
        $contents = ob_get_clean();
152
153
        $this->assertNotContains("app", $contents);
154
    }
155
156
    public function testRepositoryRegistration()
157
    {
158
        $repository = $this->app->get(Note::class);
159
        $this->assertSame($this->app->get(Mapper::class), $repository->getMapper());
160
    }
161
162
    public function testJobShortcuts()
163
    {
164
        $job = new class($this->app) extends Job {
165
            public function run(TarantoolTest $test)
166
            {
167
                // dispatch shortcut
168
                $result = $this->dispatch('test.hello');
169
                $test->assertSame($result->message, 'hello world!');
170
171
                // get instance shortcut
172
                $mapper = $this->get(Mapper::class);
173
                $mapper->getRepository('note')->truncate();
174
175
                // find shortcut
176
                $test->assertCount(0, $this->find('note'));
177
                $note = $this->create('note', ['message' => 'hello world']);
178
                $test->assertCount(1, $this->find('note'));
179
                // find one shortcut
180
                $test->assertNotNull($this->findOne('note', ['id' => $note->id]));
0 ignored issues
show
Bug introduced by
The property id does not seem to exist in Tarantool\Mapper\Entity.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
181
                $test->assertSame([$note], $this->find('note'));
182
183
                // find or create shortcut
184
                $testing = $this->findOrCreate('note', ['id' => $note->id]);
185
                $test->assertSame($note, $testing);
186
187
                $testing = $this->findOrCreate('note', ['id' => $note->id+1]);
188
                $test->assertCount(2, $this->find('note'));
189
190
                // find or fail shortcut
191
                $this->findOrFail('note', $testing->id);
192
193
                // remove shortcut
194
                $this->remove('note', ['id' => $testing->id]);
195
196
                $test->assertNull($this->findOne('note', ['id' => $testing->id]));
197
198
                $test->expectException(Exception::class);
199
                $this->findOrFail('note', $testing->id);
200
            }
201
        };
202
203
        $job->run($this);
204
205
        ob_start();
206
        var_dump($job);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($job); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
207
        $contents = ob_get_clean();
208
209
        $this->assertNotContains("app", $contents);
210
    }
211
212
    public function testPoolConfiguration()
213
    {
214
        $pool = $this->get(Pool::class);
215
216
        $this->mock('web.services')->willReturn(['services' => ['guard']]);
217
        $this->assertSame('guard', $pool->get('guard')->serviceName);
218
219
        $this->expectException(Exception::class);
220
        $pool->get('gateway');
221
    }
222
223
    public function testSelectRegistration()
224
    {
225
        $this->dispatch('tarantool.clear');
226
        $this->dispatch('module.bootstrap');
227
228
        // procedure was registered
229
        $mapper = $this->getMapper();
230
        $result = $mapper->getClient()->evaluate("return basis_select(nil, nil, nil)")->getData();
231
        $this->assertNull($result[0]);
232
    }
233
234
    public function testSelectUsage()
235
    {
236
        $this->dispatch('tarantool.clear');
237
        $this->dispatch('module.bootstrap');
238
239
        $mapper = $this->getMapper();
240
        $mapper->getSchema()
241
            ->createSpace('tester', [
242
                'id' => 'unsigned',
243
                'name' => 'string',
244
            ])
245
            ->createIndex('id')
246
            ->createIndex('name');
247
248
        $nekufa = $mapper->create('tester', ['id' => 1, 'name' => 'nekufa']);
249
        $bazyaba = $mapper->create('tester', ['id' => 2, 'name' => 'bazyaba']);
250
251
        $result = $this->get(Select::class)
252
            ('tester', 'id', [$nekufa->id]);
253
254
        $this->assertCount(1, $result);
255
256
        $result = $this->get(Select::class)
257
            ('tester', 'id', [$nekufa->id, $nekufa->id]);
258
259
        $this->assertCount(1, $result);
260
261
        $result = $this->get(Select::class)
262
            ('tester', 'id', [$bazyaba->id, $nekufa->id, $nekufa->id]);
263
264
        $this->assertCount(2, $result);
265
266
        $result = $this->get(Select::class)
267
            ('tester', 'name', ['nekufa']);
268
269
        $this->assertCount(1, $result);
270
271
        $result = $this->get(Select::class)
272
            ('tester', 'name', ['nekufa', 'bazyaba']);
273
274
        $this->assertCount(2, $result);
275
276
        $result = $this->get(Select::class)
277
            ('tester', 'name', ['nekufa', 'bazyaba', 'nekufa', 'dmitry']);
278
279
        $this->assertCount(2, $result);
280
    }
281
282
    public function testSelectUsageWithCompositeKeys()
283
    {
284
        $this->dispatch('tarantool.clear');
285
        $this->dispatch('module.bootstrap');
286
287
        $mapper = $this->getMapper();
288
        $mapper->getSchema()
289
            ->createSpace('calendar', [
290
                'year' => 'unsigned',
291
                'month' => 'unsigned',
292
                'day' => 'unsigned',
293
            ])
294
            ->createIndex(['year', 'month', 'day']);
295
296
        $mapper->create('calendar', ['year' => 2018, 'month' => 4, 'day' => 1]);
297
        $mapper->create('calendar', ['year' => 2018, 'month' => 5, 'day' => 1]);
298
        $mapper->create('calendar', ['year' => 2018, 'month' => 5, 'day' => 2]);
299
        $mapper->create('calendar', ['year' => 2018, 'month' => 5, 'day' => 3]);
300
        $mapper->create('calendar', ['year' => 2018, 'month' => 5, 'day' => 5]);
301
        $mapper->create('calendar', ['year' => 2018, 'month' => 6, 'day' => 15]);
302
303
        $select = function($values) {
304
            return $this->get(Select::class)('calendar', 'year_month_day', $values);
305
        };
306
307
        $this->assertCount(4, $select([[2018, 5]]));
308
        $this->assertCount(5, $select([[2018, 5], [2018, 6]]));
309
        $this->assertCount(2, $select([[2018, 5, 1], [2018, 5, 2]]));
310
        $this->assertCount(1, $select([[2018, 5, 3], [2018, 5, 4]]));
311
        $this->assertCount(2, $select([[2018, 5, 3], [2018, 5, 4], [2018, 4]]));
312
        $this->assertCount(2, $select([[2018, 5, 3], [2018, 5, 4], [2018, 4], [2018, 4]]));
313
    }
314
315
    public function testSelectUsageWithNestedStructures()
316
    {
317
        $mapper = $this->getMapper();
318
        $mapper->getSchema()
319
            ->createSpace('sector', [
320
                'id' => 'unsigned',
321
            ])
322
            ->addProperty('parent', 'unsigned', false, 'sector')
323
            ->createIndex([
324
                'fields' => ['id'],
325
            ])
326
            ->createIndex([
327
                'fields' => ['parent'],
328
                'unique' => false,
329
            ]);
330
331
        $root = $this->create('sector', []);
332
        $moscow = $this->create('sector', ['parent' => $root]);
333
        $kaluga = $this->create('sector', ['parent' => $root]);
334
        $obninsk = $this->create('sector', ['parent' => $kaluga]);
335
336
        $select = function($values) {
337
            return $this->get(Select::class)('sector', 'id', $values);
338
        };
339
340
        $this->assertCount(1, $select([[$obninsk->id]]));
0 ignored issues
show
Bug introduced by
The property id does not seem to exist in Tarantool\Mapper\Entity.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
341
        $this->assertCount(2, $select([[$kaluga->id]]));
342
        $this->assertCount(3, $select([$kaluga->id, $moscow->id]));
343
        $this->assertCount(4, $select([$obninsk->id, $root->id]));
344
    }
345
}
346
347