Passed
Push — master ( 4db95c...69b01d )
by Eugene
07:17
created

DecimalExtensionTest::testLuaPackingAndUnpacking()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 7
nc 1
nop 1
dl 0
loc 12
rs 10
c 0
b 0
f 0
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;
17
use Tarantool\Client\Client;
18
use Tarantool\Client\Handler\DefaultHandler;
19
use Tarantool\Client\Packer\Extension\DecimalExtension;
20
use Tarantool\Client\Packer\PackerFactory;
21
use Tarantool\Client\Packer\PurePacker;
22
use Tarantool\Client\Schema\Criteria;
23
use Tarantool\Client\Tests\Integration\ClientBuilder;
24
use Tarantool\Client\Tests\Integration\TestCase;
25
26
/**
27
 * @requires Tarantool >=2.3
28
 * @requires extension decimal
29
 * @requires clientPacker pure
30
 *
31
 * @lua dec = require('decimal').new('18446744073709551615')
32
 * @lua space = create_space('decimal_primary')
33
 * @lua space:format({{name = 'id', type = 'decimal'}})
34
 * @lua space:create_index("primary", {parts = {1, 'decimal'}})
35
 * @lua space:insert({dec})
36
 */
37
final class DecimalExtensionTest extends TestCase
38
{
39
    private const DECIMAL_BIG_INT = '18446744073709551615';
40
    private const TARANTOOL_DECIMAL_PRECISION = 38;
41
42
    public function testBinarySelectByDecimalKeySucceeds() : void
43
    {
44
        $client = self::createClientWithDecimalSupport();
45
46
        $decimal = new Decimal(self::DECIMAL_BIG_INT, self::TARANTOOL_DECIMAL_PRECISION);
47
        $space = $client->getSpace('decimal_primary');
48
        $result = $space->select(Criteria::key([$decimal]));
49
50
        self::assertTrue(isset($result[0][0]));
51
        self::assertTrue($decimal->equals($result[0][0]));
52
    }
53
54
    /**
55
     * @requires Tarantool >=2.10-stable
56
     */
57
    public function testSqlSelectByDecimalKeySucceeds() : void
58
    {
59
        $client = self::createClientWithDecimalSupport();
60
61
        $decimal = new Decimal(self::DECIMAL_BIG_INT, self::TARANTOOL_DECIMAL_PRECISION);
62
        $result = $client->executeQuery('SELECT * FROM "decimal_primary" WHERE "id" = ?', $decimal);
63
64
        self::assertFalse($result->isEmpty());
65
        self::assertTrue($decimal->equals($result->getFirst()['id']));
66
    }
67
68
    /**
69
     * @dataProvider provideDecimalStrings
70
     */
71
    public function testLuaPackingAndUnpacking(string $decimalString) : void
72
    {
73
        $client = self::createClientWithDecimalSupport();
74
75
        [$decimal] = $client->evaluate('return require("decimal").new(...)', $decimalString);
76
        self::assertTrue($decimal->equals($decimalString));
77
78
        [$isEqual] = $client->evaluate(
79
            sprintf("return require('decimal').new('%s') == ...", $decimalString),
80
            new Decimal($decimalString, self::TARANTOOL_DECIMAL_PRECISION)
81
        );
82
        self::assertTrue($isEqual);
83
    }
84
85
    public function provideDecimalStrings() : iterable
86
    {
87
        return [
88
            ['0'],
89
            ['-0'],
90
            ['42'],
91
            ['-127'],
92
            ['0.0'],
93
            ['00000.0000000'],
94
            ['00009.9000000'],
95
            ['1.000000099'],
96
            ['4.2'],
97
            ['1E-10'],
98
            ['-2E-15'],
99
            ['0.0000234'],
100
            [str_repeat('9', self::TARANTOOL_DECIMAL_PRECISION)],
101
            ['-'.str_repeat('9', self::TARANTOOL_DECIMAL_PRECISION)],
102
            ['0.'.str_repeat('1', self::TARANTOOL_DECIMAL_PRECISION)],
103
            [str_repeat('1', self::TARANTOOL_DECIMAL_PRECISION).'.0'],
104
            ['9.'.str_repeat('9', self::TARANTOOL_DECIMAL_PRECISION - 1)],
105
            [str_repeat('9', self::TARANTOOL_DECIMAL_PRECISION - 1).'.9'],
106
        ];
107
    }
108
109
    public function testBigIntegerUnpacksToDecimal() : void
110
    {
111
        $client = self::createClientWithDecimalSupport();
112
        [$number] = $client->evaluate('return 18446744073709551615ULL');
113
114
        self::assertInstanceOf(Decimal::class, $number);
115
        self::assertTrue((new Decimal('18446744073709551615'))->equals($number));
116
    }
117
118
    public function testPackerFactorySetsBigIntAsDecUnpackOption() : void
119
    {
120
        $client = new Client(new DefaultHandler(
121
            ClientBuilder::createFromEnv()->createConnection(),
122
            PackerFactory::create()
123
        ));
124
125
        [$number] = $client->evaluate(sprintf('return %sULL', self::DECIMAL_BIG_INT));
126
127
        self::assertTrue((new Decimal(self::DECIMAL_BIG_INT))->equals($number));
128
    }
129
130
    private static function createClientWithDecimalSupport() : Client
131
    {
132
        return ClientBuilder::createFromEnv()
133
            ->setPackerPureFactory(static function () {
134
                return PurePacker::fromExtensions(new DecimalExtension());
135
            })
136
            ->build();
137
    }
138
}
139