Completed
Pull Request — master (#63)
by Eugene
05:25
created

MessagePackTest   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 120
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 58
dl 0
loc 120
rs 10
c 2
b 0
f 0
wmc 9

6 Methods

Rating   Name   Duplication   Size   Complexity  
A testPackUnpack() 0 3 1
A testPackUnpackMultiDimensionalArray() 0 16 2
A providePackUnpackData() 0 15 1
A provideDecimalStrings() 0 16 1
A testCustomType() 0 22 3
A testDecimalType() 0 16 1
1
<?php
2
3
/**
4
 * This file is part of the Tarantool Client package.
5
 *
6
 * (c) Eugene Leonovich <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Tarantool\Client\Tests\Integration\MessagePack;
15
16
use Decimal\Decimal;
0 ignored issues
show
Bug introduced by
The type Decimal\Decimal was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use PHPUnit\Framework\Assert;
18
use Tarantool\Client\Packer\Extension\DecimalExtension;
19
use Tarantool\Client\Packer\PeclPacker;
20
use Tarantool\Client\Packer\PurePacker;
21
use Tarantool\Client\Schema\Criteria;
22
use Tarantool\Client\Tests\Integration\ClientBuilder;
23
use Tarantool\Client\Tests\Integration\TestCase;
24
25
final class MessagePackTest extends TestCase
26
{
27
    /**
28
     * @dataProvider providePackUnpackData
29
     */
30
    public function testPackUnpack($arg) : void
31
    {
32
        self::assertSame([$arg], $this->client->evaluate('return ...', $arg));
33
    }
34
35
    public function providePackUnpackData() : iterable
36
    {
37
        return [
38
            [[]],
39
            [42],
40
            [-42],
41
            [4.2],
42
            [-4.2],
43
            [null],
44
            [false],
45
            ['string'],
46
            ["\x04\x00\xa0\x00\x00"],
47
            [[1, 2]],
48
            [[[[1, 2]]]],
49
            [['foo' => 'bar']],
50
            // User defined types (MessagePack extensions) are not yet supported:
51
            // https://github.com/tarantool/tarantool/issues/465
52
            // [[(object) ['foo' => 'bar']]],
53
        ];
54
    }
55
56
    public function testPackUnpackMultiDimensionalArray() : void
57
    {
58
        $array = [
59
            [
60
                'foo' => [42, 'a' => [null]],
61
                'bar' => [],
62
                10000 => -1,
63
            ],
64
            true,
65
        ];
66
67
        [$result] = $this->client->evaluate('return ...', $array);
68
69
        method_exists(Assert::class, 'assertEqualsCanonicalizing')
70
            ? self::assertEqualsCanonicalizing($array, $result)
71
            : self::assertEquals($array, $result, '', 0.0, 10, true);
72
    }
73
74
    /**
75
     * @eval space = create_space('custom_type')
76
     * @eval space:create_index('primary', {type = 'hash', parts = {1, 'unsigned'}})
77
     */
78
    public function testCustomType() : void
79
    {
80
        $client = ClientBuilder::createFromEnv()
81
            ->setPackerPureFactory(static function () {
82
                return PurePacker::fromExtensions(new DateTimeExtension(42));
83
            })
84
            ->setPackerPeclFactory(static function () {
85
                return new PeclPacker(true);
86
            })
87
            ->build();
88
89
        // @see https://github.com/msgpack/msgpack-php/issues/137
90
        if (PHP_VERSION_ID >= 70400 && $client->getHandler()->getPacker() instanceof PeclPacker) {
91
            self::markTestSkipped('The msgpack extension does not pack objects correctly on PHP 7.4.');
92
        }
93
94
        $date = new \DateTimeImmutable();
95
        $space = $client->getSpace('custom_type');
96
        $result = $space->insert([100, $date]);
97
98
        self::assertEquals($date, $result[0][1]);
99
        self::assertEquals($date, $space->select(Criteria::key([100]))[0][1]);
100
    }
101
102
    /**
103
     * @requires Tarantool 2.3
104
     * @requires extension decimal
105
     * @requires function MessagePack\Packer::pack
106
     *
107
     * @eval dec = require('decimal')
108
     *
109
     * @dataProvider provideDecimalStrings
110
     */
111
    public function testDecimalType(string $decimalString) : void
112
    {
113
        $client = ClientBuilder::createFromEnv()
114
            ->setPackerPureFactory(static function () {
115
                return PurePacker::fromExtensions(new DecimalExtension(1));
0 ignored issues
show
Unused Code introduced by
The call to Tarantool\Client\Packer\...xtension::__construct() has too many arguments starting with 1. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

115
                return PurePacker::fromExtensions(/** @scrutinizer ignore-call */ new DecimalExtension(1));

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
116
            })
117
            ->build();
118
119
        [$decimal] = $client->evaluate('return dec.new(...)', $decimalString);
120
        self::assertTrue($decimal->equals($decimalString));
121
122
        [$isEqual] = $client->evaluate(
123
            'return dec.new(...) == ...',
124
            $decimalString, new Decimal($decimalString, DecimalExtension::DEFAULT_PRECISION)
125
        );
126
        self::assertTrue($isEqual);
127
    }
128
129
    public function provideDecimalStrings() : iterable
130
    {
131
        return [
132
            ['0'],
133
            ['-0'],
134
            ['0.0'],
135
            ['00000.0000000'],
136
            ['00009.9000000'],
137
            ['-127'],
138
            ['4.2'],
139
            ['1E-10'],
140
            ['0.0000234'],
141
            ['0.'.str_repeat('1', DecimalExtension::DEFAULT_PRECISION)],
142
            [str_repeat('1', DecimalExtension::DEFAULT_PRECISION).'.0'],
143
            ['9.'.str_repeat('9', DecimalExtension::DEFAULT_PRECISION - 1)],
144
            [str_repeat('9', DecimalExtension::DEFAULT_PRECISION - 1).'.9'],
145
        ];
146
    }
147
}
148