GeneratorTest.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. <?php
  2. /*
  3. * The RandomLib library for securely generating random numbers and strings in PHP
  4. *
  5. * @author Anthony Ferrara <ircmaxell@ircmaxell.com>
  6. * @copyright 2011 The Authors
  7. * @license http://www.opensource.org/licenses/mit-license.html MIT License
  8. * @version Build @@version@@
  9. */
  10. namespace RandomLib;
  11. class GeneratorTest extends \PHPUnit_Framework_TestCase
  12. {
  13. protected $generator = null;
  14. protected $mixer = null;
  15. protected $sources = array();
  16. public static function provideGenerate()
  17. {
  18. return array(
  19. array(0, ''),
  20. array(1, chr(0)),
  21. array(2, chr(1) . chr(1)),
  22. array(3, chr(2) . chr(0) . chr(2)),
  23. array(4, chr(3) . chr(3) . chr(3) . chr(3)),
  24. );
  25. }
  26. public static function provideGenerateInt()
  27. {
  28. return array(
  29. array(1, 1, 1),
  30. array(0, 1, 0),
  31. array(0, 255, 0),
  32. array(400, 655, 400),
  33. array(0, 65535, 257),
  34. array(65535, 131070, 65792),
  35. array(0, 16777215, (2<<16) + 2),
  36. array(-10, 0, -10),
  37. array(-655, -400, -655),
  38. array(-131070, -65535, -130813),
  39. );
  40. }
  41. public static function provideGenerateIntRangeTest()
  42. {
  43. return array(
  44. array(0, 0),
  45. array(0, 1),
  46. array(1, 10000),
  47. array(100000, \PHP_INT_MAX),
  48. );
  49. }
  50. public static function provideGenerateStringTest()
  51. {
  52. return array(
  53. array(0, 'ab', ''),
  54. array(1, 'ab', 'a'),
  55. array(1, 'a', ''),
  56. array(2, 'ab', 'bb'),
  57. array(3, 'abc', 'cac'),
  58. array(8, '0123456789abcdef', '77777777'),
  59. array(16, '0123456789abcdef', 'ffffffffffffffff'),
  60. array(16, '', 'DDDDDDDDDDDDDDDD'),
  61. );
  62. }
  63. public function setUp()
  64. {
  65. $source1 = $this->getMock('RandomLib\Source');
  66. $source1->expects($this->any())
  67. ->method('generate')
  68. ->will($this->returnCallback(function ($size) {
  69. $r = '';
  70. for ($i = 0; $i < $size; $i++) {
  71. $r .= chr($i);
  72. }
  73. return $r;
  74. }
  75. ));
  76. $source2 = $this->getMock('RandomLib\Source');
  77. $source2->expects($this->any())
  78. ->method('generate')
  79. ->will($this->returnCallback(function ($size) {
  80. $r = '';
  81. for ($i = $size - 1; $i >= 0; $i--) {
  82. $r .= chr($i);
  83. }
  84. return $r;
  85. }
  86. ));
  87. $this->mixer = $this->getMock('RandomLib\Mixer');
  88. $this->mixer->expects($this->any())
  89. ->method('mix')
  90. ->will($this->returnCallback(function (array $sources) {
  91. if (empty($sources)) {
  92. return '';
  93. }
  94. $start = array_pop($sources);
  95. return array_reduce(
  96. $sources,
  97. function ($el1, $el2) {
  98. return $el1 ^ $el2;
  99. },
  100. $start
  101. );
  102. }));
  103. $this->sources = array($source1, $source2);
  104. $this->generator = new Generator($this->sources, $this->mixer);
  105. }
  106. public function testConstruct()
  107. {
  108. $this->assertTrue($this->generator instanceof Generator);
  109. }
  110. public function testGetMixer()
  111. {
  112. $this->assertSame($this->mixer, $this->generator->getMixer());
  113. }
  114. public function testGetSources()
  115. {
  116. $this->assertSame($this->sources, $this->generator->getSources());
  117. }
  118. /**
  119. * @dataProvider provideGenerate
  120. */
  121. public function testGenerate($size, $expect)
  122. {
  123. $this->assertEquals($expect, $this->generator->generate($size));
  124. }
  125. /**
  126. * @dataProvider provideGenerateInt
  127. */
  128. public function testGenerateInt($min, $max, $expect)
  129. {
  130. $this->assertEquals($expect, $this->generator->generateInt($min, $max));
  131. }
  132. /**
  133. * @dataProvider provideGenerateIntRangeTest
  134. */
  135. public function testGenerateIntRange($min, $max)
  136. {
  137. $n = $this->generator->generateInt($min, $max);
  138. $this->assertTrue($min <= $n);
  139. $this->assertTrue($max >= $n);
  140. }
  141. /**
  142. * @expectedException RangeException
  143. */
  144. public function testGenerateIntFail()
  145. {
  146. $n = $this->generator->generateInt(-1, PHP_INT_MAX);
  147. }
  148. public function testGenerateIntLargeTest()
  149. {
  150. $bits = 30;
  151. $expected = 50529027;
  152. if (PHP_INT_MAX > 4000000000) {
  153. $bits = 55;
  154. $expected = 1693273676973062;
  155. }
  156. $n = $this->generator->generateInt(0, (int) pow(2, $bits));
  157. $this->assertEquals($expected, $n);
  158. }
  159. /**
  160. * @dataProvider provideGenerateStringTest
  161. */
  162. public function testGenerateString($length, $chars, $expected)
  163. {
  164. $n = $this->generator->generateString($length, $chars);
  165. $this->assertEquals($expected, $n);
  166. }
  167. /**
  168. * This test checks for issue #22:
  169. *
  170. * @see https://github.com/ircmaxell/RandomLib/issues/22
  171. */
  172. public function testGenerateLargeRange()
  173. {
  174. if (PHP_INT_MAX < pow(2, 32)) {
  175. $this->markTestSkipped("Only test on 64 bit platforms");
  176. }
  177. $this->assertEquals(506381209866536711, $this->generator->generateInt(0, PHP_INT_MAX));
  178. }
  179. }