Skip to content

Commit fe47d48

Browse files
authored
PHPLIB-1147, PHPLIB-1148: Int64 improvements (#1112)
* PHPLIB-1147: Create Int64 instances directly * PHPLIB-1148: Add comparator for Int64 objects * Simplify comparison of Int64
1 parent eb2a813 commit fe47d48

12 files changed

+279
-55
lines changed

phpunit.evergreen.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
beStrictAboutOutputDuringTests="true"
77
beStrictAboutChangesToGlobalState="true"
88
colors="true"
9-
bootstrap="vendor/autoload.php"
9+
bootstrap="tests/bootstrap.php"
1010
defaultTestSuite="Default Test Suite"
1111
>
1212

phpunit.xml.dist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
beStrictAboutOutputDuringTests="true"
77
beStrictAboutChangesToGlobalState="true"
88
colors="true"
9-
bootstrap="vendor/autoload.php"
9+
bootstrap="tests/bootstrap.php"
1010
defaultTestSuite="Default Test Suite"
1111
>
1212

tests/Comparator/Int64Comparator.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
namespace MongoDB\Tests\Comparator;
4+
5+
use MongoDB\BSON\Int64;
6+
use SebastianBergmann\Comparator\Comparator;
7+
use SebastianBergmann\Comparator\ComparisonFailure;
8+
9+
use function is_numeric;
10+
use function sprintf;
11+
12+
class Int64Comparator extends Comparator
13+
{
14+
public function accepts($expected, $actual)
15+
{
16+
// Only compare if either value is an Int64 and the other value is numeric
17+
return ($expected instanceof Int64 && $this->isComparable($actual))
18+
|| ($actual instanceof Int64 && $this->isComparable($expected));
19+
}
20+
21+
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false): void
22+
{
23+
if ($expected == $actual) {
24+
return;
25+
}
26+
27+
throw new ComparisonFailure(
28+
$expected,
29+
$actual,
30+
'',
31+
'',
32+
false,
33+
sprintf(
34+
'Failed asserting that %s matches expected %s.',
35+
$this->exporter->export($actual),
36+
$this->exporter->export($expected)
37+
)
38+
);
39+
}
40+
41+
private function isComparable($value): bool
42+
{
43+
return $value instanceof Int64 || is_numeric($value);
44+
}
45+
}
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
<?php
2+
3+
namespace MongoDB\Tests\Comparator;
4+
5+
use Generator;
6+
use MongoDB\BSON\Int64;
7+
use PHPUnit\Framework\TestCase;
8+
use SebastianBergmann\Comparator\ComparisonFailure;
9+
10+
class Int64ComparatorTest extends TestCase
11+
{
12+
/** @dataProvider provideAcceptsValues */
13+
public function testAccepts(bool $expectedResult, $expectedValue, $actualValue): void
14+
{
15+
$this->assertSame($expectedResult, (new Int64Comparator())->accepts($expectedValue, $actualValue));
16+
}
17+
18+
public static function provideAcceptsValues(): Generator
19+
{
20+
yield 'Expects Int64, Actual Int64' => [
21+
'expectedResult' => true,
22+
'expectedValue' => new Int64(123),
23+
'actualValue' => new Int64(123),
24+
];
25+
26+
yield 'Expects Int64, Actual int' => [
27+
'expectedResult' => true,
28+
'expectedValue' => new Int64(123),
29+
'actualValue' => 123,
30+
];
31+
32+
yield 'Expects Int64, Actual int string' => [
33+
'expectedResult' => true,
34+
'expectedValue' => new Int64(123),
35+
'actualValue' => '123',
36+
];
37+
38+
yield 'Expects Int64, Actual float' => [
39+
'expectedResult' => true,
40+
'expectedValue' => new Int64(123),
41+
'actualValue' => 123.0,
42+
];
43+
44+
yield 'Expects Int64, Actual float string' => [
45+
'expectedResult' => true,
46+
'expectedValue' => new Int64(123),
47+
'actualValue' => '123.0',
48+
];
49+
50+
yield 'Expects Int64, Actual non-numeric string' => [
51+
'expectedResult' => false,
52+
'expectedValue' => new Int64(123),
53+
'actualValue' => 'foo',
54+
];
55+
56+
yield 'Expects int, Actual Int64' => [
57+
'expectedResult' => true,
58+
'expectedValue' => 123,
59+
'actualValue' => new Int64(123),
60+
];
61+
62+
yield 'Expects int string, Actual Int64' => [
63+
'expectedResult' => true,
64+
'expectedValue' => '123',
65+
'actualValue' => new Int64(123),
66+
];
67+
68+
yield 'Expects float, Actual Int64' => [
69+
'expectedResult' => true,
70+
'expectedValue' => 123.0,
71+
'actualValue' => new Int64(123),
72+
];
73+
74+
yield 'Expects float string, Actual Int64' => [
75+
'expectedResult' => true,
76+
'expectedValue' => '123.0',
77+
'actualValue' => new Int64(123),
78+
];
79+
80+
yield 'Expects non-numeric string, Actual Int64' => [
81+
'expectedResult' => false,
82+
'expectedValue' => 'foo',
83+
'actualValue' => new Int64(123),
84+
];
85+
86+
yield 'Expects float, Actual float' => [
87+
'expectedResult' => false,
88+
'expectedValue' => 123.0,
89+
'actualValue' => 123.0,
90+
];
91+
92+
yield 'Expects numeric string, Actual numeric string' => [
93+
'expectedResult' => false,
94+
'expectedValue' => '123',
95+
'actualValue' => '123',
96+
];
97+
}
98+
99+
/**
100+
* @dataProvider provideMatchingAssertions
101+
* @doesNotPerformAssertions
102+
*/
103+
public function testMatchingAssertions($expected, $actual): void
104+
{
105+
(new Int64Comparator())->assertEquals($expected, $actual);
106+
}
107+
108+
public static function provideMatchingAssertions(): Generator
109+
{
110+
yield 'Expected Int64, Actual Int64' => [
111+
'expected' => new Int64(8589934592),
112+
'actual' => new Int64(8589934592),
113+
];
114+
115+
yield 'Expected Int64, Actual int' => [
116+
'expected' => new Int64(8589934592),
117+
'actual' => 8589934592,
118+
];
119+
120+
yield 'Expected Int64, Actual int string' => [
121+
'expected' => new Int64(8589934592),
122+
'actual' => '8589934592',
123+
];
124+
125+
yield 'Expected Int64, Actual float' => [
126+
'expected' => new Int64(8589934592),
127+
'actual' => 8589934592.0,
128+
];
129+
130+
yield 'Expected Int64, Actual float string' => [
131+
'expected' => new Int64(8589934592),
132+
'actual' => '8589934592.0',
133+
];
134+
135+
yield 'Expected int, Actual Int64' => [
136+
'expected' => 8589934592,
137+
'actual' => new Int64(8589934592),
138+
];
139+
140+
yield 'Expected int string, Actual Int64' => [
141+
'expected' => '8589934592',
142+
'actual' => new Int64(8589934592),
143+
];
144+
145+
yield 'Expected float, Actual Int64' => [
146+
'expected' => 8589934592.0,
147+
'actual' => new Int64(8589934592),
148+
];
149+
150+
yield 'Expected float string, Actual Int64' => [
151+
'expected' => '8589934592.0',
152+
'actual' => new Int64(8589934592),
153+
];
154+
}
155+
156+
/** @dataProvider provideFailingValues */
157+
public function testFailingAssertions($expected, $actual): void
158+
{
159+
$this->expectException(ComparisonFailure::class);
160+
161+
(new Int64Comparator())->assertEquals($expected, $actual);
162+
}
163+
164+
public static function provideFailingValues(): Generator
165+
{
166+
yield 'Expected Int64, Actual Int64' => [
167+
'expected' => new Int64(8589934592),
168+
'actual' => new Int64(456),
169+
];
170+
171+
yield 'Expected Int64, Actual int' => [
172+
'expected' => new Int64(8589934592),
173+
'actual' => 456,
174+
];
175+
176+
yield 'Expected Int64, Actual int string' => [
177+
'expected' => new Int64(8589934592),
178+
'actual' => '456',
179+
];
180+
181+
yield 'Expected Int64, Actual float' => [
182+
'expected' => new Int64(8589934592),
183+
'actual' => 8589934592.1,
184+
];
185+
186+
yield 'Expected Int64, Actual float string' => [
187+
'expected' => new Int64(8589934592),
188+
'actual' => '8589934592.1',
189+
];
190+
191+
yield 'Expected int, Actual Int64' => [
192+
'expected' => 8589934592,
193+
'actual' => new Int64(456),
194+
];
195+
196+
yield 'Expected int string, Actual Int64' => [
197+
'expected' => '8589934592',
198+
'actual' => new Int64(456),
199+
];
200+
201+
yield 'Expected float, Actual Int64' => [
202+
'expected' => 8589934592.1,
203+
'actual' => new Int64(456),
204+
];
205+
206+
yield 'Expected float string, Actual Int64' => [
207+
'expected' => '8589934592.1',
208+
'actual' => new Int64(456),
209+
];
210+
}
211+
}

tests/SpecTests/ClientSideEncryption/FunctionalTestCase.php

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
namespace MongoDB\Tests\SpecTests\ClientSideEncryption;
44

5-
use MongoDB\BSON\Int64;
65
use MongoDB\Client;
76
use MongoDB\Driver\WriteConcern;
87
use MongoDB\Tests\SpecTests\FunctionalTestCase as BaseFunctionalTestCase;
@@ -14,8 +13,6 @@
1413
use function is_executable;
1514
use function is_readable;
1615
use function sprintf;
17-
use function strlen;
18-
use function unserialize;
1916

2017
use const DIRECTORY_SEPARATOR;
2118
use const PATH_SEPARATOR;
@@ -69,14 +66,6 @@ protected static function insertKeyVaultData(Client $client, ?array $keyVaultDat
6966
$collection->insertMany($keyVaultData);
7067
}
7168

72-
protected static function createInt64(string $value): Int64
73-
{
74-
$array = sprintf('a:1:{s:7:"integer";s:%d:"%s";}', strlen($value), $value);
75-
$int64 = sprintf('C:%d:"%s":%d:{%s}', strlen(Int64::class), Int64::class, strlen($array), $array);
76-
77-
return unserialize($int64);
78-
}
79-
8069
private function createTestCollection(?stdClass $encryptedFields = null, ?stdClass $jsonSchema = null): void
8170
{
8271
$context = $this->getContext();

tests/SpecTests/ClientSideEncryption/Prose22_RangeExplicitEncryptionTest.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use MongoDB\BSON\Binary;
99
use MongoDB\BSON\Decimal128;
1010
use MongoDB\BSON\Document;
11+
use MongoDB\BSON\Int64;
1112
use MongoDB\BSON\UTCDateTime;
1213
use MongoDB\Driver\ClientEncryption;
1314
use MongoDB\Driver\Exception\EncryptionException;
@@ -168,8 +169,8 @@ public static function provideTypeAndRangeOpts(): Generator
168169
yield 'Long' => [
169170
'Long',
170171
[
171-
'min' => self::createInt64('0'),
172-
'max' => self::createInt64('200'),
172+
'min' => new Int64(0),
173+
'max' => new Int64(200),
173174
'sparsity' => 1,
174175
],
175176
];
@@ -467,7 +468,7 @@ private static function getCastCallableForType(string $type): callable
467468

468469
case 'Long':
469470
return function (int $value) {
470-
return self::createInt64((string) $value);
471+
return new Int64($value);
471472
};
472473

473474
default:

tests/SpecTests/ClientSideEncryptionSpecTest.php

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,7 @@
4343
use function json_decode;
4444
use function sprintf;
4545
use function str_repeat;
46-
use function strlen;
4746
use function substr;
48-
use function unserialize;
4947

5048
use const DIRECTORY_SEPARATOR;
5149
use const PATH_SEPARATOR;
@@ -1862,14 +1860,6 @@ public static function provideRewrapManyDataKeySrcAndDstProviders()
18621860
}
18631861
}
18641862

1865-
private function createInt64(string $value): Int64
1866-
{
1867-
$array = sprintf('a:1:{s:7:"integer";s:%d:"%s";}', strlen($value), $value);
1868-
$int64 = sprintf('C:%d:"%s":%d:{%s}', strlen(Int64::class), Int64::class, strlen($array), $array);
1869-
1870-
return unserialize($int64);
1871-
}
1872-
18731863
private function createTestCollection(?stdClass $encryptedFields = null, ?stdClass $jsonSchema = null): void
18741864
{
18751865
$context = $this->getContext();
@@ -1936,7 +1926,7 @@ private function encryptCorpusValue(string $fieldName, stdClass $data, ClientEnc
19361926
/* Note: workaround issue where mongocryptd refuses to encrypt
19371927
* 32-bit integers if schemaMap defines a "long" BSON type. */
19381928
$value = $data->type === 'long' && ! $data->value instanceof Int64
1939-
? $this->createInt64($data->value)
1929+
? new Int64($data->value)
19401930
: $data->value;
19411931

19421932
$encrypted = $clientEncryption->encrypt($value, $encryptionOptions);
@@ -1987,7 +1977,7 @@ private function prepareCorpusData(string $fieldName, stdClass $data, ClientEncr
19871977
/* Note: workaround issue where mongocryptd refuses to encrypt
19881978
* 32-bit integers if schemaMap defines a "long" BSON type. */
19891979
if ($data->type === 'long' && ! $data->value instanceof Int64) {
1990-
$data->value = $this->createInt64($data->value);
1980+
$data->value = new Int64($data->value);
19911981
}
19921982

19931983
return $data;

0 commit comments

Comments
 (0)