Last active
March 31, 2020 11:21
-
-
Save jiromm/ba332a06d38fd621e54cc3735a90845c to your computer and use it in GitHub Desktop.
wget -O phpunit https://phar.phpunit.de/phpunit-9.phar && php phpunit UnitTest.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
function getNext( | |
int $alphaCount = 1, | |
int $minNumberCount = 0, | |
array $skippableAlpha = [], | |
array $skippableNumbers = [], | |
string $unitNumber = null): string { | |
if ($alphaCount < 1 || $minNumberCount < 0) throw new \Exception('Empty values'); | |
$skippableAlpha = array_map('strtoupper', $skippableAlpha); | |
asort($skippableAlpha); | |
if ($skippableAlpha == range('A', 'Z')) throw new \Exception('All alphabets are used'); | |
foreach ($skippableAlpha as $alpha) { | |
$alphaCode = ord($alpha); | |
if (mb_strlen($alpha) > 1) throw new \Exception('Wrong character length for skippable alphas'); | |
if ($alphaCode < 65 || $alphaCode > 90) throw new \Exception('Wrong character for skippable alphas'); | |
} | |
asort($skippableNumbers); | |
if ($skippableNumbers == range(0, 9)) throw new \Exception('All digits are used'); | |
foreach ($skippableNumbers as $num) { | |
if (!ctype_digit((string)$num)) throw new \Exception('Skippable numbers are not numbers'); | |
if ($num < 0 || $num > 9) throw new \Exception('Wrong character length for skippable numbers'); | |
} | |
if ($unitNumber === '') throw new \Exception('Unit number cannot be empty. Should be null or real unit number'); | |
if ($minNumberCount === 0) { | |
$minNumberCount = 1; | |
} | |
// Not most effective way to define default unit number in case it missed | |
// But this way code is flat and much readable | |
$fromScratch = false; | |
if ($unitNumber === null) { | |
$code = str_repeat('A', $alphaCount); | |
$number = str_repeat('0', $minNumberCount); | |
$unitNumber = $code . $number; | |
$fromScratch = true; | |
} | |
$splitUnit = function (string $unit) { | |
if (!preg_match('/^([A-Z]+)(\d+)$/', $unit, $matches)) { | |
throw new Exception('Given unit number format is wrong'); | |
} | |
if (count($matches) !== 3) throw new \RuntimeException('Something went wrong with unit number decode'); | |
array_shift($matches); | |
return $matches; | |
}; | |
[$code, $number] = $splitUnit($unitNumber); | |
$codeLen = strlen($code); | |
$numberLen = strlen($number); | |
if ($codeLen > $alphaCount) throw new \Exception('Given unit number\'s alpha number length cannot be less than requested'); | |
if ($codeLen < $alphaCount) { | |
$code = str_repeat('A', $alphaCount); | |
$number = str_repeat('0', $minNumberCount); | |
$unitNumber = $code . $number; | |
} else { | |
if (!$fromScratch) { | |
[$codeOld] = $splitUnit($unitNumber); | |
[$code] = $splitUnit(++$unitNumber); | |
if ($codeOld !== $code) { | |
$number = str_repeat('0', $numberLen); | |
$unitNumber = $code . $number; | |
} | |
} | |
} | |
// Convert to string to apply in_array function | |
foreach ($skippableNumbers as $i => $number) { | |
$skippableNumbers[$i] = (string)$number; | |
} | |
$isValid = function (string $unit) use ($skippableAlpha, $skippableNumbers) { | |
foreach (str_split($unit) as $char) { | |
if (in_array($char, $skippableAlpha) || in_array($char, $skippableNumbers)) { | |
return false; | |
} | |
} | |
return true; | |
}; | |
while (!$isValid($unitNumber)) { | |
if (strlen($code) > $alphaCount) { | |
$numberLen++; | |
$code = str_repeat('A', $alphaCount); | |
$number = str_repeat('0', $numberLen); | |
$unitNumber = $code . $number; | |
} else { | |
[$codeOld] = $splitUnit($unitNumber); | |
$unitNumber++; | |
[$code] = $splitUnit($unitNumber); | |
if ($codeOld !== $code) { | |
$number = str_repeat('0', $numberLen); | |
$unitNumber = $code . $number; | |
} | |
} | |
} | |
return $unitNumber; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use PHPUnit\Framework\TestCase; | |
include 'get_next.php'; | |
final class UnitTest extends TestCase | |
{ | |
/** | |
* @dataProvider invalidDataProvider | |
*/ | |
public function testEmptyValues($alpha, $num = 0, $eAlpha = [], $eNum = [], $unit = null) | |
{ | |
$this->expectException(\Throwable::class); | |
getNext($alpha, $num, $eAlpha, $eNum, $unit); | |
} | |
public function invalidDataProvider() | |
{ | |
return [ | |
[0], | |
[-1], | |
[-5021625], | |
[1, -1], | |
[1, 2, [1]], | |
[1, 2, ['AA']], | |
[1, 2, ['Ա']], | |
[1, 2, ['A', 2]], | |
[1, 2, ['A', 'B', 'C', 'D', '$', 'E']], | |
[1, 2, range('A', 'Z')], | |
[1, 2, [], ['A']], | |
[1, 2, [], [-1]], | |
[1, 2, [], [11]], | |
[1, 2, [], ['A', 1]], | |
[1, 2, [], [1, 2, 'a', 3]], | |
[1, 2, [], [1, 2, '%', 3]], | |
[1, 2, [], [-1]], | |
[1, 2, [], [1, -1, 3]], | |
[1, 2, [], range(0, 9)], | |
[1, 2, [], [], '$'], | |
[1, 2, [], [], 'A$'], | |
[1, 2, [], [], 'A1$'], | |
[1, 2, [], [], 'A1$1'], | |
[1, 2, [], [], '1'], | |
[1, 2, [], [], '1A'], | |
[2, 2, [], [], 'XYZ00'], | |
[1, 2, [], [], ''], | |
]; | |
} | |
/** | |
* @dataProvider validDataProvider | |
*/ | |
public function testValidValues($alpha, $num, $eAlpha, $eNum, $unit, $returnedResult) | |
{ | |
$result = getNext($alpha, $num, $eAlpha, $eNum, $unit); | |
$this->assertEquals($result, $returnedResult); | |
} | |
public function validDataProvider() | |
{ | |
return [ | |
[1, 0, [], [], null, 'A0'], | |
[1, 5, [], [], null, 'A00000'], | |
[2, 30, [], [], null, 'AA' . str_repeat('0', 30)], | |
[2, 2, [], [], 'AB233', 'AB234'], | |
[2, 2, [], [], 'AZ999', 'BA000'], | |
[2, 2, [], [], 'A456', 'AA00'], | |
[2, 2, ['A'], [], 'AC123', 'BB000'], | |
[2, 2, ['A', 'B'], [], 'AC123', 'CC000'], | |
[1, 0, [], [0], null, 'A1'], | |
[1, 0, [], [0, 1], null, 'A2'], | |
[1, 0, [], [0], 'Z9', 'A11'], | |
[2, 2, ['A', 'B'], [0, 1], 'AC123', 'CC222'], | |
[3, 2, ['A', 'B', 'C', 'D', 'E', 'F'], [0, 1, 2, 3, 4, 5], 'A1', 'GGG6'], | |
[2, 2, ['Z'], [0, 9], 'YY889', 'AA1111'], | |
]; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment