Passed
Push — master ( 8c8692...cf4100 )
by Eugene
05:48
created

MessagePackTest   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 165
Duplicated Lines 0 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
eloc 73
c 5
b 0
f 0
dl 0
loc 165
rs 10
wmc 12

9 Methods

Rating   Name   Duplication   Size   Complexity  
A testPackUnpack() 0 3 1
A testUnpackingBigIntegerAsString() 0 5 1
A testPackUnpackMultiDimensionalArray() 0 16 2
A providePackUnpackData() 0 15 1
A provideDecimalStrings() 0 21 1
A testPackerFactorySetsBigIntAsDecUnpackOption() 0 10 1
A testUnpackingBigIntegerAsDecimal() 0 5 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\Client;
19
use Tarantool\Client\Handler\DefaultHandler;
20
use Tarantool\Client\Packer\Extension\DecimalExtension;
21
use Tarantool\Client\Packer\PackerFactory;
22
use Tarantool\Client\Packer\PeclPacker;
23
use Tarantool\Client\Packer\PurePacker;
24
use Tarantool\Client\Schema\Criteria;
25
use Tarantool\Client\Tests\Integration\ClientBuilder;
26
use Tarantool\Client\Tests\Integration\TestCase;
27
28
final class MessagePackTest extends TestCase
29
{
30
    private const TARANTOOL_DECIMAL_PRECISION = 38;
31
32
    /**
33
     * @dataProvider providePackUnpackData
34
     */
35
    public function testPackUnpack($arg) : void
36
    {
37
        self::assertSame([$arg], $this->client->evaluate('return ...', $arg));
38
    }
39
40
    public function providePackUnpackData() : iterable
41
    {
42
        return [
43
            [[]],
44
            [42],
45
            [-42],
46
            [4.2],
47
            [-4.2],
48
            [null],
49
            [false],
50
            ['string'],
51
            ["\x04\x00\xa0\x00\x00"],
52
            [[1, 2]],
53
            [[[[1, 2]]]],
54
            [['foo' => 'bar']],
55
            // User defined types (MessagePack extensions) are not yet supported:
56
            // https://github.com/tarantool/tarantool/issues/465
57
            // [[(object) ['foo' => 'bar']]],
58
        ];
59
    }
60
61
    public function testPackUnpackMultiDimensionalArray() : void
62
    {
63
        $array = [
64
            [
65
                'foo' => [42, 'a' => [null]],
66
                'bar' => [],
67
                10000 => -1,
68
            ],
69
            true,
70
        ];
71
72
        [$result] = $this->client->evaluate('return ...', $array);
73
74
        method_exists(Assert::class, 'assertEqualsCanonicalizing')
75
            ? self::assertEqualsCanonicalizing($array, $result)
76
            : self::assertEquals($array, $result, '', 0.0, 10, true);
77
    }
78
79
    /**
80
     * @eval space = create_space('custom_type')
81
     * @eval space:create_index('primary', {type = 'hash', parts = {1, 'unsigned'}})
82
     */
83
    public function testCustomType() : void
84
    {
85
        $client = ClientBuilder::createFromEnv()
86
            ->setPackerPureFactory(static function () {
87
                return PurePacker::fromExtensions(new DateTimeExtension(42));
88
            })
89
            ->setPackerPeclFactory(static function () {
90
                return new PeclPacker(true);
91
            })
92
            ->build();
93
94
        // @see https://github.com/msgpack/msgpack-php/issues/137
95
        if (PHP_VERSION_ID >= 70400 && $client->getHandler()->getPacker() instanceof PeclPacker) {
96
            self::markTestSkipped('The msgpack extension does not pack objects correctly on PHP 7.4.');
97
        }
98
99
        $date = new \DateTimeImmutable();
100
        $space = $client->getSpace('custom_type');
101
        $result = $space->insert([100, $date]);
102
103
        self::assertEquals($date, $result[0][1]);
104
        self::assertEquals($date, $space->select(Criteria::key([100]))[0][1]);
105
    }
106
107
    /**
108
     * @requires Tarantool 2.3
109
     * @requires extension decimal
110
     * @requires function MessagePack\Packer::pack
111
     *
112
     * @eval dec = require('decimal')
113
     *
114
     * @dataProvider provideDecimalStrings
115
     */
116
    public function testDecimalType(string $decimalString) : void
117
    {
118
        $client = ClientBuilder::createFromEnv()
119
            ->setPackerPureFactory(static function () {
120
                return PurePacker::fromExtensions(new DecimalExtension());
121
            })
122
            ->build();
123
124
        [$decimal] = $client->evaluate('return dec.new(...)', $decimalString);
125
        self::assertTrue($decimal->equals($decimalString));
126
127
        [$isEqual] = $client->evaluate(
128
            "return dec.new('$decimalString') == ...",
129
            new Decimal($decimalString, self::TARANTOOL_DECIMAL_PRECISION)
130
        );
131
        self::assertTrue($isEqual);
132
    }
133
134
    public function provideDecimalStrings() : iterable
135
    {
136
        return [
137
            ['0'],
138
            ['-0'],
139
            ['42'],
140
            ['-127'],
141
            ['0.0'],
142
            ['00000.0000000'],
143
            ['00009.9000000'],
144
            ['1.000000099'],
145
            ['4.2'],
146
            ['1E-10'],
147
            ['-2E-15'],
148
            ['0.0000234'],
149
            [str_repeat('9', self::TARANTOOL_DECIMAL_PRECISION)],
150
            ['-'.str_repeat('9', self::TARANTOOL_DECIMAL_PRECISION)],
151
            ['0.'.str_repeat('1', self::TARANTOOL_DECIMAL_PRECISION)],
152
            [str_repeat('1', self::TARANTOOL_DECIMAL_PRECISION).'.0'],
153
            ['9.'.str_repeat('9', self::TARANTOOL_DECIMAL_PRECISION - 1)],
154
            [str_repeat('9', self::TARANTOOL_DECIMAL_PRECISION - 1).'.9'],
155
        ];
156
    }
157
158
    /**
159
     * @requires function MessagePack\Packer::pack
160
     */
161
    public function testUnpackingBigIntegerAsString() : void
162
    {
163
        [$number] = $this->client->evaluate('return 18446744073709551615ULL');
164
165
        self::assertSame('18446744073709551615', $number);
166
    }
167
168
    /**
169
     * @requires extension decimal
170
     * @requires function MessagePack\Packer::pack
171
     */
172
    public function testUnpackingBigIntegerAsDecimal() : void
173
    {
174
        [$number] = $this->client->evaluate('return 18446744073709551615ULL');
175
176
        self::assertTrue((new Decimal('18446744073709551615'))->equals($number));
177
    }
178
179
    /**
180
     * @requires extension decimal
181
     * @requires function MessagePack\Packer::pack
182
     */
183
    public function testPackerFactorySetsBigIntAsDecUnpackOption() : void
184
    {
185
        $client = new Client(new DefaultHandler(
186
            ClientBuilder::createFromEnv()->createConnection(),
187
            PackerFactory::create()
188
        ));
189
190
        [$number] = $client->evaluate('return 18446744073709551615ULL');
191
192
        self::assertTrue((new Decimal('18446744073709551615'))->equals($number));
193
    }
194
}
195