FieldsTest.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. <?php
  2. declare(strict_types=1);
  3. namespace Ramsey\Uuid\Test\Rfc4122;
  4. use Ramsey\Uuid\Exception\InvalidArgumentException;
  5. use Ramsey\Uuid\Rfc4122\Fields;
  6. use Ramsey\Uuid\Test\TestCase;
  7. use Ramsey\Uuid\Type\Hexadecimal;
  8. use function hex2bin;
  9. use function serialize;
  10. use function str_replace;
  11. use function unserialize;
  12. class FieldsTest extends TestCase
  13. {
  14. public function testConstructorThrowsExceptionIfNotSixteenByteString(): void
  15. {
  16. $this->expectException(InvalidArgumentException::class);
  17. $this->expectExceptionMessage(
  18. 'The byte string must be 16 bytes long; received 6 bytes'
  19. );
  20. new Fields('foobar');
  21. }
  22. /**
  23. * @dataProvider nonRfc4122VariantProvider
  24. */
  25. public function testConstructorThrowsExceptionIfNotRfc4122Variant(string $uuid): void
  26. {
  27. $bytes = (string) hex2bin(str_replace('-', '', $uuid));
  28. $this->expectException(InvalidArgumentException::class);
  29. $this->expectExceptionMessage(
  30. 'The byte string received does not conform to the RFC 4122 variant'
  31. );
  32. new Fields($bytes);
  33. }
  34. /**
  35. * @phpcsSuppress SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingTraversableTypeHintSpecification
  36. */
  37. public function nonRfc4122VariantProvider(): array
  38. {
  39. return [
  40. ['ff6f8cb0-c57d-11e1-0b21-0800200c9a66'],
  41. ['ff6f8cb0-c57d-11e1-1b21-0800200c9a66'],
  42. ['ff6f8cb0-c57d-11e1-2b21-0800200c9a66'],
  43. ['ff6f8cb0-c57d-11e1-3b21-0800200c9a66'],
  44. ['ff6f8cb0-c57d-11e1-4b21-0800200c9a66'],
  45. ['ff6f8cb0-c57d-11e1-5b21-0800200c9a66'],
  46. ['ff6f8cb0-c57d-11e1-6b21-0800200c9a66'],
  47. ['ff6f8cb0-c57d-11e1-7b21-0800200c9a66'],
  48. ['ff6f8cb0-c57d-11e1-cb21-0800200c9a66'],
  49. ['ff6f8cb0-c57d-11e1-db21-0800200c9a66'],
  50. ['ff6f8cb0-c57d-11e1-eb21-0800200c9a66'],
  51. ['ff6f8cb0-c57d-11e1-fb21-0800200c9a66'],
  52. ];
  53. }
  54. /**
  55. * @dataProvider invalidVersionProvider
  56. */
  57. public function testConstructorThrowsExceptionIfInvalidVersion(string $uuid): void
  58. {
  59. $bytes = (string) hex2bin(str_replace('-', '', $uuid));
  60. $this->expectException(InvalidArgumentException::class);
  61. $this->expectExceptionMessage(
  62. 'The byte string received does not contain a valid RFC 4122 version'
  63. );
  64. new Fields($bytes);
  65. }
  66. /**
  67. * @phpcsSuppress SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingTraversableTypeHintSpecification
  68. */
  69. public function invalidVersionProvider(): array
  70. {
  71. return [
  72. ['ff6f8cb0-c57d-01e1-8b21-0800200c9a66'],
  73. ['ff6f8cb0-c57d-91e1-bb21-0800200c9a66'],
  74. ['ff6f8cb0-c57d-a1e1-9b21-0800200c9a66'],
  75. ['ff6f8cb0-c57d-b1e1-ab21-0800200c9a66'],
  76. ['ff6f8cb0-c57d-c1e1-ab21-0800200c9a66'],
  77. ['ff6f8cb0-c57d-d1e1-ab21-0800200c9a66'],
  78. ['ff6f8cb0-c57d-e1e1-ab21-0800200c9a66'],
  79. ['ff6f8cb0-c57d-f1e1-ab21-0800200c9a66'],
  80. ];
  81. }
  82. /**
  83. * @param string|int $expectedValue
  84. *
  85. * @dataProvider fieldGetterMethodProvider
  86. */
  87. public function testFieldGetterMethods(string $uuid, string $methodName, $expectedValue): void
  88. {
  89. $bytes = (string) hex2bin(str_replace('-', '', $uuid));
  90. $fields = new Fields($bytes);
  91. $result = $fields->$methodName();
  92. if ($result instanceof Hexadecimal) {
  93. $this->assertSame($expectedValue, $result->toString());
  94. } else {
  95. $this->assertSame($expectedValue, $result);
  96. }
  97. }
  98. /**
  99. * @phpcsSuppress SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingTraversableTypeHintSpecification
  100. */
  101. public function fieldGetterMethodProvider(): array
  102. {
  103. return [
  104. ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getClockSeq', '1b21'],
  105. ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getClockSeqHiAndReserved', '9b'],
  106. ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getClockSeqLow', '21'],
  107. ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getNode', '0800200c9a66'],
  108. ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getTimeHiAndVersion', '11e1'],
  109. ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getTimeLow', 'ff6f8cb0'],
  110. ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getTimeMid', 'c57d'],
  111. ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getTimestamp', '1e1c57dff6f8cb0'],
  112. ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getVariant', 2],
  113. ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getVersion', 1],
  114. ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'isNil', false],
  115. ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'isMax', false],
  116. ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getClockSeq', '2b21'],
  117. ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getClockSeqHiAndReserved', 'ab'],
  118. ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getClockSeqLow', '21'],
  119. ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getNode', '0800200c9a66'],
  120. ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getTimeHiAndVersion', '41e1'],
  121. ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getTimeLow', 'ff6f8cb0'],
  122. ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getTimeMid', 'c57d'],
  123. ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getTimestamp', '1e1c57dff6f8cb0'],
  124. ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getVariant', 2],
  125. ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getVersion', 4],
  126. ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'isNil', false],
  127. ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'isMax', false],
  128. ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getClockSeq', '3b21'],
  129. ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getClockSeqHiAndReserved', 'bb'],
  130. ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getClockSeqLow', '21'],
  131. ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getNode', '0800200c9a66'],
  132. ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getTimeHiAndVersion', '31e1'],
  133. ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getTimeLow', 'ff6f8cb0'],
  134. ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getTimeMid', 'c57d'],
  135. ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getTimestamp', '1e1c57dff6f8cb0'],
  136. ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getVariant', 2],
  137. ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getVersion', 3],
  138. ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'isNil', false],
  139. ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'isMax', false],
  140. ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getClockSeq', '0b21'],
  141. ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getClockSeqHiAndReserved', '8b'],
  142. ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getClockSeqLow', '21'],
  143. ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getNode', '0800200c9a66'],
  144. ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getTimeHiAndVersion', '51e1'],
  145. ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getTimeLow', 'ff6f8cb0'],
  146. ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getTimeMid', 'c57d'],
  147. ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getTimestamp', '1e1c57dff6f8cb0'],
  148. ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getVariant', 2],
  149. ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getVersion', 5],
  150. ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'isNil', false],
  151. ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'isMax', false],
  152. ['ff6f8cb0-c57d-61e1-8b21-0800200c9a66', 'getClockSeq', '0b21'],
  153. ['ff6f8cb0-c57d-61e1-8b21-0800200c9a66', 'getClockSeqHiAndReserved', '8b'],
  154. ['ff6f8cb0-c57d-61e1-8b21-0800200c9a66', 'getClockSeqLow', '21'],
  155. ['ff6f8cb0-c57d-61e1-8b21-0800200c9a66', 'getNode', '0800200c9a66'],
  156. ['ff6f8cb0-c57d-61e1-8b21-0800200c9a66', 'getTimeHiAndVersion', '61e1'],
  157. ['ff6f8cb0-c57d-61e1-8b21-0800200c9a66', 'getTimeLow', 'ff6f8cb0'],
  158. ['ff6f8cb0-c57d-61e1-8b21-0800200c9a66', 'getTimeMid', 'c57d'],
  159. ['ff6f8cb0-c57d-61e1-8b21-0800200c9a66', 'getTimestamp', 'ff6f8cb0c57d1e1'],
  160. ['ff6f8cb0-c57d-61e1-8b21-0800200c9a66', 'getVariant', 2],
  161. ['ff6f8cb0-c57d-61e1-8b21-0800200c9a66', 'getVersion', 6],
  162. ['ff6f8cb0-c57d-61e1-8b21-0800200c9a66', 'isNil', false],
  163. ['ff6f8cb0-c57d-61e1-8b21-0800200c9a66', 'isMax', false],
  164. ['00000000-0000-0000-0000-000000000000', 'getClockSeq', '0000'],
  165. ['00000000-0000-0000-0000-000000000000', 'getClockSeqHiAndReserved', '00'],
  166. ['00000000-0000-0000-0000-000000000000', 'getClockSeqLow', '00'],
  167. ['00000000-0000-0000-0000-000000000000', 'getNode', '000000000000'],
  168. ['00000000-0000-0000-0000-000000000000', 'getTimeHiAndVersion', '0000'],
  169. ['00000000-0000-0000-0000-000000000000', 'getTimeLow', '00000000'],
  170. ['00000000-0000-0000-0000-000000000000', 'getTimeMid', '0000'],
  171. ['00000000-0000-0000-0000-000000000000', 'getTimestamp', '000000000000000'],
  172. ['00000000-0000-0000-0000-000000000000', 'getVariant', 2],
  173. ['00000000-0000-0000-0000-000000000000', 'getVersion', null],
  174. ['00000000-0000-0000-0000-000000000000', 'isNil', true],
  175. ['00000000-0000-0000-0000-000000000000', 'isMax', false],
  176. ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getClockSeq', 'ffff'],
  177. ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getClockSeqHiAndReserved', 'ff'],
  178. ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getClockSeqLow', 'ff'],
  179. ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getNode', 'ffffffffffff'],
  180. ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getTimeHiAndVersion', 'ffff'],
  181. ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getTimeLow', 'ffffffff'],
  182. ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getTimeMid', 'ffff'],
  183. ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getTimestamp', 'fffffffffffffff'],
  184. ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getVariant', 2],
  185. ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getVersion', null],
  186. ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'isNil', false],
  187. ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'isMax', true],
  188. ['000001f5-5cde-21ea-8400-0242ac130003', 'getClockSeq', '0400'],
  189. ['000001f5-5cde-21ea-8400-0242ac130003', 'getClockSeqHiAndReserved', '84'],
  190. ['000001f5-5cde-21ea-8400-0242ac130003', 'getClockSeqLow', '00'],
  191. ['000001f5-5cde-21ea-8400-0242ac130003', 'getNode', '0242ac130003'],
  192. ['000001f5-5cde-21ea-8400-0242ac130003', 'getTimeHiAndVersion', '21ea'],
  193. ['000001f5-5cde-21ea-8400-0242ac130003', 'getTimeLow', '000001f5'],
  194. ['000001f5-5cde-21ea-8400-0242ac130003', 'getTimeMid', '5cde'],
  195. ['000001f5-5cde-21ea-8400-0242ac130003', 'getTimestamp', '1ea5cde00000000'],
  196. ['000001f5-5cde-21ea-8400-0242ac130003', 'getVariant', 2],
  197. ['000001f5-5cde-21ea-8400-0242ac130003', 'getVersion', 2],
  198. ['000001f5-5cde-21ea-8400-0242ac130003', 'isNil', false],
  199. ['000001f5-5cde-21ea-8400-0242ac130003', 'isMax', false],
  200. ['018339f0-1b83-71e1-9b21-0800200c9a66', 'getClockSeq', '1b21'],
  201. ['018339f0-1b83-71e1-9b21-0800200c9a66', 'getClockSeqHiAndReserved', '9b'],
  202. ['018339f0-1b83-71e1-9b21-0800200c9a66', 'getClockSeqLow', '21'],
  203. ['018339f0-1b83-71e1-9b21-0800200c9a66', 'getNode', '0800200c9a66'],
  204. ['018339f0-1b83-71e1-9b21-0800200c9a66', 'getTimeHiAndVersion', '71e1'],
  205. ['018339f0-1b83-71e1-9b21-0800200c9a66', 'getTimeLow', '018339f0'],
  206. ['018339f0-1b83-71e1-9b21-0800200c9a66', 'getTimeMid', '1b83'],
  207. ['018339f0-1b83-71e1-9b21-0800200c9a66', 'getTimestamp', '000018339f01b83'],
  208. ['018339f0-1b83-71e1-9b21-0800200c9a66', 'getVariant', 2],
  209. ['018339f0-1b83-71e1-9b21-0800200c9a66', 'getVersion', 7],
  210. ['018339f0-1b83-71e1-9b21-0800200c9a66', 'isNil', false],
  211. ['018339f0-1b83-71e1-9b21-0800200c9a66', 'isMax', false],
  212. ];
  213. }
  214. public function testSerializingFields(): void
  215. {
  216. $bytes = (string) hex2bin(str_replace('-', '', 'ff6f8cb0-c57d-11e1-9b21-0800200c9a66'));
  217. $fields = new Fields($bytes);
  218. $serializedFields = serialize($fields);
  219. /** @var Fields $unserializedFields */
  220. $unserializedFields = unserialize($serializedFields);
  221. $this->assertSame($fields->getBytes(), $unserializedFields->getBytes());
  222. }
  223. public function testSerializingFieldsWithOldFormat(): void
  224. {
  225. $fields = new Fields("\xb3\xcd\x58\x6a\xe3\xca\x44\xf3\x98\x8c\xf4\xd6\x66\xc1\xbf\x4d");
  226. $serializedFields = 'C:26:"Ramsey\Uuid\Rfc4122\Fields":24:{s81YauPKRPOYjPTWZsG/TQ==}';
  227. /** @var Fields $unserializedFields */
  228. $unserializedFields = unserialize($serializedFields);
  229. $this->assertSame($fields->getBytes(), $unserializedFields->getBytes());
  230. }
  231. }