diff --git a/src/Faker/Generator/IntegerGenerator.php b/src/Faker/Generator/IntegerGenerator.php new file mode 100644 index 0000000000..7504397774 --- /dev/null +++ b/src/Faker/Generator/IntegerGenerator.php @@ -0,0 +1,23 @@ + $maximum) { + throw new \InvalidArgumentException(sprintf( + 'Minimum value %d should not be greater than the maximum value %d.', + $minimum, + $maximum, + )); + } + + $largestInteger = mt_getrandmax(); + + if ($maximum > $largestInteger) { + throw new \InvalidArgumentException(sprintf( + 'Maximum value %d should not be greater than %d.', + $maximum, + $largestInteger, + )); + } + + return mt_rand($minimum, $maximum); + } + + public function seed(int $value): void + { + mt_srand($value); + } +} diff --git a/src/Faker/Generator/SeedableIntegerGenerator.php b/src/Faker/Generator/SeedableIntegerGenerator.php new file mode 100644 index 0000000000..c94be01112 --- /dev/null +++ b/src/Faker/Generator/SeedableIntegerGenerator.php @@ -0,0 +1,16 @@ +integerBetween( + $min, + $max, + ); + }, + 100, + ); + + self::assertValuesSatisfySpecification( + static function (int $value) use ($min, $max): bool { + return $value >= $min && $value <= $max; + }, + $values, + ); + } + + public function testSeedSeedsIntegerGenerator(): void + { + $value = 9001; + + $generator = new Generator\MersenneTwisterIntegerGenerator(); + + $generator->seed($value); + + $first = self::generateValues( + static function () use ($generator): int { + return $generator->integer(); + }, + 100, + ); + + $generator->seed($value); + + $second = self::generateValues( + static function () use ($generator): int { + return $generator->integer(); + }, + 100, + ); + + self::assertSame($first, $second); + } + + /** + * @param \Closure(): mixed $generator + * + * @throws \InvalidArgumentException + * + * @return list + */ + private static function generateValues( + \Closure $generator, + int $count + ): array { + if ($count < 1) { + throw new \InvalidArgumentException(sprintf( + 'Count needs to be greater than 0, got %d instead', + $count, + )); + } + + return array_map(static function () use ($generator) { + return $generator(); + }, range(0, $count - 1)); + } + + /** + * @param \Closure(mixed):bool $specification + * @param list $values + * + * @throws \InvalidArgumentException + */ + private static function assertValuesSatisfySpecification( + \Closure $specification, + array $values + ): void { + $invalidValues = array_filter($values, static function ($value) use ($specification): bool { + return $specification($value) === false; + }); + + self::assertCount(0, $invalidValues, 'Failed asserting that all generated values satisfy the specification.'); + } +}