Passed
Pull Request — master (#18)
by Marc
03:37
created

TableTest::testFilterCount()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 21
rs 9.3142
c 0
b 0
f 0
cc 1
eloc 13
nc 1
nop 0
1
<?php
2
declare(strict_types=1);
3
4
namespace TBolier\RethinkConnect\Test\Connection;
5
6
use ArrayObject;
7
use TBolier\RethinkQL\Response\Cursor;
8
use TBolier\RethinkQL\Response\ResponseInterface;
9
use TBolier\RethinkQL\IntegrationTest\BaseTestCase;
10
11
class TableTest extends BaseTestCase
12
{
13
    public function setUp()
14
    {
15
        parent::setUp();
16
17
        if (!\in_array('tabletest', $this->r()->db()->tableList()->run()->getData()[0], true)) {
18
            $this->r()->db()->tableCreate('tabletest')->run();
19
        }
20
    }
21
22
    public function tearDown()
23
    {
24
        if (\in_array('tabletest', $this->r()->db()->tableList()->run()->getData()[0], true)) {
25
            $this->r()->db()->tableDrop('tabletest')->run();
26
        }
27
28
        parent::tearDown();
29
    }
30
31
    /**
32
     * @throws \Exception
33
     */
34
    public function testEmptyTable()
35
    {
36
        /** @var ResponseInterface $count */
37
        $count = $this->r()
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class TBolier\RethinkQL\Query\AbstractQuery as the method count() does only exist in the following sub-classes of TBolier\RethinkQL\Query\AbstractQuery: TBolier\RethinkQL\Query\...ation\AbstractOperation, TBolier\RethinkQL\Query\Operation\Count, TBolier\RethinkQL\Query\Operation\DbCreate, TBolier\RethinkQL\Query\Operation\DbDrop, TBolier\RethinkQL\Query\Operation\DbList, TBolier\RethinkQL\Query\Operation\Delete, TBolier\RethinkQL\Query\Operation\Filter, TBolier\RethinkQL\Query\Operation\Get, TBolier\RethinkQL\Query\Operation\Insert, TBolier\RethinkQL\Query\Operation\TableCreate, TBolier\RethinkQL\Query\Operation\TableDrop, TBolier\RethinkQL\Query\Operation\TableList, TBolier\RethinkQL\Query\Operation\Update, TBolier\RethinkQL\Query\Table. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
38
            ->table('tabletest')
39
            ->filter([
40
                [
41
                    'title' => 'Test document',
42
                ],
43
            ])
44
            ->count()
45
            ->run();
46
47
        $this->assertInternalType('int', $count->getData()[0]);
48
49
        $res = $this->r()
50
            ->table('tabletest')
51
            ->delete()
52
            ->run();
53
54
        $this->assertObStatus(['deleted' => $count->getData()[0]], $res->getData()[0]);
55
    }
56
57
    /**
58
     * @throws \Exception
59
     */
60
    public function testInsert()
61
    {
62
        $res = $this->insertDocument(1);
63
64
        $this->assertObStatus(['inserted' => 1], $res->getData()[0]);
65
    }
66
67
    /**
68
     * @throws \Exception
69
     */
70
    public function testCount()
71
    {
72
        $this->insertDocument(1);
73
74
        $res = $this->r()
75
            ->table('tabletest')
76
            ->count()
77
            ->run();
78
79
        $this->assertInternalType('int', $res->getData()[0]);
80
    }
81
82
    /**
83
     * @throws \Exception
84
     */
85
    public function testFilter()
86
    {
87
        $this->insertDocument(1);
88
89
        /** @var Cursor $cursor */
90
        $cursor = $this->r()
91
            ->table('tabletest')
92
            ->filter([
93
                [
94
                    'title' => 'Test document',
95
                ],
96
            ])
97
            ->run();
98
99
        $this->assertInstanceOf(\Iterator::class, $cursor);
100
        $this->assertInternalType('array', $cursor->current());
101
    }
102
103
    /**
104
     * @throws \Exception
105
     */
106
    public function testFilterCount()
107
    {
108
        $this->insertDocument(1);
109
        $this->insertDocument(2);
110
        $this->insertDocument(3);
111
        $this->insertDocument(4);
112
        $this->insertDocument(5);
113
114
        /** @var ResponseInterface $res */
115
        $res = $this->r()
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class TBolier\RethinkQL\Query\AbstractQuery as the method count() does only exist in the following sub-classes of TBolier\RethinkQL\Query\AbstractQuery: TBolier\RethinkQL\Query\...ation\AbstractOperation, TBolier\RethinkQL\Query\Operation\Count, TBolier\RethinkQL\Query\Operation\DbCreate, TBolier\RethinkQL\Query\Operation\DbDrop, TBolier\RethinkQL\Query\Operation\DbList, TBolier\RethinkQL\Query\Operation\Delete, TBolier\RethinkQL\Query\Operation\Filter, TBolier\RethinkQL\Query\Operation\Get, TBolier\RethinkQL\Query\Operation\Insert, TBolier\RethinkQL\Query\Operation\TableCreate, TBolier\RethinkQL\Query\Operation\TableDrop, TBolier\RethinkQL\Query\Operation\TableList, TBolier\RethinkQL\Query\Operation\Update, TBolier\RethinkQL\Query\Table. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
116
            ->table('tabletest')
117
            ->filter([
118
                [
119
                    'title' => 'Test document',
120
                ],
121
            ])
122
            ->count()
123
            ->run();
124
125
        $this->assertEquals(5, $res->getData()[0]);
126
    }
127
128
    /**
129
     * @throws \Exception
130
     */
131
    public function testUpdate()
132
    {
133
        $this->insertDocument(1);
134
135
        $this->r()
136
            ->table('tabletest')
137
            ->insert([
138
                [
139
                    'title' => 'Update document',
140
                ],
141
            ])
142
            ->run();
143
144
        /** @var ResponseInterface $count */
145
        $count = $this->r()
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class TBolier\RethinkQL\Query\AbstractQuery as the method count() does only exist in the following sub-classes of TBolier\RethinkQL\Query\AbstractQuery: TBolier\RethinkQL\Query\...ation\AbstractOperation, TBolier\RethinkQL\Query\Operation\Count, TBolier\RethinkQL\Query\Operation\DbCreate, TBolier\RethinkQL\Query\Operation\DbDrop, TBolier\RethinkQL\Query\Operation\DbList, TBolier\RethinkQL\Query\Operation\Delete, TBolier\RethinkQL\Query\Operation\Filter, TBolier\RethinkQL\Query\Operation\Get, TBolier\RethinkQL\Query\Operation\Insert, TBolier\RethinkQL\Query\Operation\TableCreate, TBolier\RethinkQL\Query\Operation\TableDrop, TBolier\RethinkQL\Query\Operation\TableList, TBolier\RethinkQL\Query\Operation\Update, TBolier\RethinkQL\Query\Table. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
146
            ->table('tabletest')
147
            ->filter([
148
                [
149
                    'title' => 'Update document',
150
                ],
151
            ])
152
            ->count()
153
            ->run();
154
        /** @var ResponseInterface $res */
155
        $res = $this->r()
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class TBolier\RethinkQL\Query\AbstractQuery as the method update() does only exist in the following sub-classes of TBolier\RethinkQL\Query\AbstractQuery: TBolier\RethinkQL\Query\...ation\AbstractOperation, TBolier\RethinkQL\Query\Operation\Count, TBolier\RethinkQL\Query\Operation\DbCreate, TBolier\RethinkQL\Query\Operation\DbDrop, TBolier\RethinkQL\Query\Operation\DbList, TBolier\RethinkQL\Query\Operation\Delete, TBolier\RethinkQL\Query\Operation\Filter, TBolier\RethinkQL\Query\Operation\Get, TBolier\RethinkQL\Query\Operation\Insert, TBolier\RethinkQL\Query\Operation\TableCreate, TBolier\RethinkQL\Query\Operation\TableDrop, TBolier\RethinkQL\Query\Operation\TableList, TBolier\RethinkQL\Query\Operation\Update, TBolier\RethinkQL\Query\Table. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
156
            ->table('tabletest')
157
            ->filter([
158
                [
159
                    'title' => 'Update document',
160
                ],
161
            ])
162
            ->update([
163
                [
164
                    'title' => 'Updated document',
165
                ],
166
            ])
167
            ->run();
168
169
        $this->assertObStatus(['replaced' => $count->getData()[0]], $res->getData()[0]);
170
    }
171
172
    /**
173
     * @throws \Exception
174
     */
175
    public function testDeleteDocument()
176
    {
177
        $this->r()
178
            ->table('tabletest')
179
            ->insert([
180
                [
181
                    'title' => 'Delete document',
182
                ],
183
            ])
184
            ->run();
185
186
        /** @var ResponseInterface $count */
187
        $count = $this->r()
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class TBolier\RethinkQL\Query\AbstractQuery as the method count() does only exist in the following sub-classes of TBolier\RethinkQL\Query\AbstractQuery: TBolier\RethinkQL\Query\...ation\AbstractOperation, TBolier\RethinkQL\Query\Operation\Count, TBolier\RethinkQL\Query\Operation\DbCreate, TBolier\RethinkQL\Query\Operation\DbDrop, TBolier\RethinkQL\Query\Operation\DbList, TBolier\RethinkQL\Query\Operation\Delete, TBolier\RethinkQL\Query\Operation\Filter, TBolier\RethinkQL\Query\Operation\Get, TBolier\RethinkQL\Query\Operation\Insert, TBolier\RethinkQL\Query\Operation\TableCreate, TBolier\RethinkQL\Query\Operation\TableDrop, TBolier\RethinkQL\Query\Operation\TableList, TBolier\RethinkQL\Query\Operation\Update, TBolier\RethinkQL\Query\Table. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
188
            ->table('tabletest')
189
            ->filter([
190
                [
191
                    'title' => 'Delete document',
192
                ],
193
            ])
194
            ->count()
195
            ->run();
196
197
        $this->assertInternalType('int', $count->getData()[0]);
198
199
        /** @var ResponseInterface $res */
200
        $res = $this->r()
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class TBolier\RethinkQL\Query\AbstractQuery as the method delete() does only exist in the following sub-classes of TBolier\RethinkQL\Query\AbstractQuery: TBolier\RethinkQL\Query\...ation\AbstractOperation, TBolier\RethinkQL\Query\Operation\Count, TBolier\RethinkQL\Query\Operation\DbCreate, TBolier\RethinkQL\Query\Operation\DbDrop, TBolier\RethinkQL\Query\Operation\DbList, TBolier\RethinkQL\Query\Operation\Delete, TBolier\RethinkQL\Query\Operation\Filter, TBolier\RethinkQL\Query\Operation\Get, TBolier\RethinkQL\Query\Operation\Insert, TBolier\RethinkQL\Query\Operation\TableCreate, TBolier\RethinkQL\Query\Operation\TableDrop, TBolier\RethinkQL\Query\Operation\TableList, TBolier\RethinkQL\Query\Operation\Update, TBolier\RethinkQL\Query\Table. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
201
            ->table('tabletest')
202
            ->filter([
203
                [
204
                    'title' => 'Delete document',
205
                ],
206
            ])
207
            ->delete()
208
            ->run();
209
210
        $this->assertObStatus(['deleted' => $count->getData()[0]], $res->getData()[0]);
211
    }
212
213
    /**
214
     * @return void
215
     * @throws \Exception
216
     */
217
    public function testGet(): void
218
    {
219
        $this->r()
220
            ->table('tabletest')
221
            ->insert([
222
                [
223
                    'id' => 'foo',
224
                ],
225
            ])
226
            ->run();
227
228
        /** @var ResponseInterface $res */
229
        $res = $this->r()
230
            ->table('tabletest')
231
            ->get('foo')
232
            ->run();
233
234
        $this->assertEquals([0 => ['id' => 'foo']], $res->getData());
235
    }
236
237
    /**
238
     * @return void
239
     * @throws \Exception
240
     */
241
    public function testGetNonExistingDocument(): void
242
    {
243
        /** @var ResponseInterface $res */
244
        $res = $this->r()
245
            ->table('tabletest')
246
            ->get('bar')
247
            ->run();
248
249
        $this->assertEquals([0 => null], $res->getData());
250
    }
251
252
    /**
253
     * @param $status
254
     * @param $data
255
     * @throws \Exception
256
     */
257
    protected function assertObStatus($status, $data)
258
    {
259
        $res = [];
260
        $statuses = [
261
            'unchanged',
262
            'skipped',
263
            'replaced',
264
            'inserted',
265
            'errors',
266
            'deleted',
267
        ];
268
        $data = new ArrayObject($data);
269
270
        foreach ($statuses as $s) {
271
            $status[$s] = $status[$s] ?? 0;
272
        }
273
274
        $data->setFlags($data::ARRAY_AS_PROPS);
275
276
        foreach ($statuses as $s) {
277
            $res[$s] = $data[$s] ?? 0;
278
        }
279
280
        $this->assertEquals($status, $res);
281
    }
282
283
    /**
284
     * @param int $documentId
285
     * @return ResponseInterface
286
     */
287
    private function insertDocument(int $documentId): ResponseInterface
288
    {
289
        $res = $this->r()
290
            ->table('tabletest')
291
            ->insert([
292
                [
293
                    'documentId' => $documentId,
294
                    'title' => 'Test document',
295
                    'description' => 'My first document.',
296
                ],
297
            ])
298
            ->run();
299
300
        return $res;
301
    }
302
}
303