Skip to content
This repository was archived by the owner on Sep 1, 2023. It is now read-only.

Commit ede976d

Browse files
lexidorfredemmott
authored andcommitted
Bugfix/negative intspec (#29)
* Write a failing test for allowing negaive ints * Update the IntSpec to use the same intish check as HH\Lib\Str\to_int. * Document regression of nolonger allowing leading zeroes. * Document the regression that ints that exceed uint64 will nolonger return 2^63-1 * Allow 007 to be cast to int(7) * Write a failing test for a the string /0{2,}/ * The string with just zeroes previously cast to 0. * Add big-number tests * Declare that intspec does not convert hex * Typo
1 parent c82e3cc commit ede976d

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

src/TypeSpec/__Private/IntSpec.hack

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ namespace Facebook\TypeSpec\__Private;
1212

1313
use type Facebook\TypeAssert\{IncorrectTypeException, TypeCoercionException};
1414
use type Facebook\TypeSpec\TypeSpec;
15+
use namespace HH\Lib\Str;
1516

1617
final class IntSpec extends TypeSpec<int> {
1718
<<__Override>>
@@ -22,8 +23,25 @@ final class IntSpec extends TypeSpec<int> {
2223
if ($value instanceof \Stringish) {
2324
/* HH_FIXME[4281] Stringish is going */
2425
$str = (string)$value;
25-
if ($str !== '' && \ctype_digit($str)) {
26-
return (int)$str;
26+
$int = (int)$str;
27+
28+
// "1234" -(int)-> 1234 -(string)-> "1234"
29+
// "-1234" -(int)-> -1234 -(string)-> "-1234"
30+
// ^^ are the same ^^
31+
if ($str === (string)$int) {
32+
return $int;
33+
}
34+
35+
// "0001234" -(trim)-> "1234" -(int)-> 1234 -(string)-> "1234"
36+
// ^^ are the same ^^
37+
$str = Str\trim_left($str, '0');
38+
if ($str === (string)$int) {
39+
return $int;
40+
}
41+
42+
// Exceptional case "000" -(trim)-> "", but we want to return 0
43+
if ($str === '' && $value !== '') {
44+
return 0;
2745
}
2846
}
2947
throw TypeCoercionException::withValue($this->getTrace(), 'int', $value);

tests/IntSpecTest.hack

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ namespace Facebook\TypeAssert;
1212

1313
use namespace Facebook\TypeSpec;
1414
use type Facebook\TypeSpec\TypeSpec;
15+
use namespace HH\Lib\Math;
1516

1617
final class IntSpecTest extends TypeSpecTest<int> {
1718
<<__Override>>
@@ -27,6 +28,12 @@ final class IntSpecTest extends TypeSpecTest<int> {
2728
tuple('0', 0),
2829
tuple('123', 123),
2930
tuple(new TestStringable('123'), 123),
31+
tuple((string)Math\INT64_MAX, Math\INT64_MAX),
32+
tuple('-321', -321),
33+
tuple((string)Math\INT64_MIN, Math\INT64_MIN),
34+
tuple(new TestStringable('-321'), -321),
35+
tuple('007', 7),
36+
tuple('000', 0),
3037
];
3138
}
3239

@@ -44,6 +51,11 @@ final class IntSpecTest extends TypeSpecTest<int> {
4451
[null],
4552
[false],
4653
[new TestStringable('1.23')],
54+
['-007'],
55+
[new TestStringable('-007')],
56+
['9223372036854775808'], //Math\INT64_MAX+1
57+
['-9223372036854775809'], //Math\INT64_MIN-1
58+
['0xFF'],
4759
];
4860
}
4961
}

0 commit comments

Comments
 (0)