Skip to content

Commit 1f03fa6

Browse files
authored
Bugfix for numbers larger than PHP_INT_MAX (#10)
* Add unit tests that should pass * Travis fix * Bugfix, numbers larger then INT_MAX. * Add test for int max. * Test new invalid argument exception. * Fixes
1 parent 235b559 commit 1f03fa6

File tree

5 files changed

+64
-17
lines changed

5 files changed

+64
-17
lines changed

.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ php:
66

77
install: composer install --no-interaction --classmap-authoritative
88

9-
script: vendor/bin/phpunit
9+
script: vendor/bin/phpunit --configuration phpunit.xml
1010

1111
notifications:
1212
email: false

src/Contract/NumberInterface.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ interface NumberInterface
3535
/**
3636
* Get the number, without check digit.
3737
*
38-
* @return int
38+
* @return string
3939
*/
40-
public function getNumber(): int;
40+
public function getNumber(): string;
4141

4242
/**
4343
* Get the check digit for the number.

src/Number.php

+14-6
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,15 @@ class Number implements NumberInterface
4646

4747
/**
4848
* Input constructor.
49-
* @param int $number The number.
49+
* @param string $number The number.
5050
* @param int|null $checkDigit [Optional] The check digit for the number.
5151
*/
52-
public function __construct(int $number, ?int $checkDigit = null)
52+
public function __construct(string $number, ?int $checkDigit = null)
5353
{
54+
if (!is_numeric($number)) {
55+
throw new \InvalidArgumentException("Expects \$number to be a number, \"{$number}\" given.");
56+
}
57+
5458
$this->number = $number;
5559
$this->checkDigit = $checkDigit;
5660
}
@@ -65,21 +69,25 @@ public function __construct(int $number, ?int $checkDigit = null)
6569
*/
6670
public static function fromString(string $input): self
6771
{
68-
$input = (int) preg_replace("/[^\d]/", "", $input);
72+
$input = preg_replace('/[^\d]/', '', $input);
73+
74+
if (!is_numeric($input)) {
75+
throw new \InvalidArgumentException("Expects \$input to be a number, \"{$input}\" given.");
76+
}
6977

7078
// Get the last digit.
71-
$checkDigit = $input % 10;
79+
$checkDigit = (int) $input[strlen($input) - 1];
7280

7381
// Remove the last digit.
74-
$number = (int) ($input / 10);
82+
$number = substr($input, 0, strlen($input) - 1);
7583

7684
return new self($number, $checkDigit);
7785
}
7886

7987
/**
8088
* {@inheritdoc}
8189
*/
82-
public function getNumber(): int
90+
public function getNumber(): string
8391
{
8492
return $this->number;
8593
}

tests/LuhnAlgorithmTest.php

+4-3
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,10 @@ public function testIsValid_success($number, $expected)
5454
public function provideIsValid_success()
5555
{
5656
return [
57-
[new Number(12345, 5), true],
58-
[new Number(410321920, 2), true],
59-
[new Number(3199723370002, 0), true],
57+
[new Number('12345', 5), true],
58+
[new Number('410321920', 2), true],
59+
[new Number('3199723370002', 0), true],
60+
[new Number('8914800000397416568', 5), true],
6061
];
6162
}
6263

tests/NumberTest.php

+43-5
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,39 @@
3131
class NumberTest extends TestCase
3232
{
3333
/**
34-
* @dataProvider provideWithCheckDigit_success
34+
* @dataProvider provideFromString_success
3535
*/
36-
public function testWithCheckDigit_success($number, $expected)
36+
public function testFromString_success($number, $expected)
3737
{
3838
$this->assertEquals($expected, Number::fromString($number));
3939
}
4040

41-
public function provideWithCheckDigit_success()
41+
public function provideFromString_success()
4242
{
4343
return [
44-
["410321-9202", new Number(410321920, 2)],
45-
[4103219202, new Number(410321920, 2)]
44+
["410321-9202", new Number('410321920', 2)],
45+
[4103219202, new Number('410321920', 2)],
46+
['89148000003974165685', new Number('8914800000397416568', 5)],
47+
['abc123', new Number('12', 3)],
48+
// Use any number that is larger then PHP_INT_MAX.
49+
[((string) PHP_INT_MAX).'21', new Number(((string) PHP_INT_MAX).'2', 1)],
50+
];
51+
}
52+
53+
/**
54+
* @dataProvider provideFromString_fail
55+
*/
56+
public function testFromString_fail($number, $checkDigit, $expected)
57+
{
58+
$this->expectException($expected);
59+
new Number($number, $checkDigit);
60+
}
61+
62+
public function provideFromString_fail()
63+
{
64+
return [
65+
['', 1, \InvalidArgumentException::class],
66+
['xyz ', null, \InvalidArgumentException::class],
4667
];
4768
}
4869

@@ -60,4 +81,21 @@ public function provideToString_success()
6081
[new Number(12345, 5), "123455"]
6182
];
6283
}
84+
85+
/**
86+
* @dataProvider provideNew_fail
87+
*/
88+
public function testNew_fail($number, $checkDigit, $expected)
89+
{
90+
$this->expectException($expected);
91+
new Number($number, $checkDigit);
92+
}
93+
94+
public function provideNew_fail()
95+
{
96+
return [
97+
['abc123', 1, \InvalidArgumentException::class],
98+
['123 ', null, \InvalidArgumentException::class],
99+
];
100+
}
63101
}

0 commit comments

Comments
 (0)