FieldsTest.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. <?php
  2. declare(strict_types=1);
  3. namespace Ramsey\Uuid\Test\Guid;
  4. use Ramsey\Uuid\Exception\InvalidArgumentException;
  5. use Ramsey\Uuid\Guid\Fields;
  6. use Ramsey\Uuid\Test\TestCase;
  7. use Ramsey\Uuid\Type\Hexadecimal;
  8. use function hex2bin;
  9. use function serialize;
  10. use function unserialize;
  11. class FieldsTest extends TestCase
  12. {
  13. public function testConstructorThrowsExceptionIfNotSixteenByteString(): void
  14. {
  15. $this->expectException(InvalidArgumentException::class);
  16. $this->expectExceptionMessage(
  17. 'The byte string must be 16 bytes long; received 6 bytes'
  18. );
  19. new Fields('foobar');
  20. }
  21. /**
  22. * @dataProvider nonRfc4122GuidVariantProvider
  23. */
  24. public function testConstructorThrowsExceptionIfNotRfc4122Variant(string $guid): void
  25. {
  26. $bytes = (string) hex2bin($guid);
  27. $this->expectException(InvalidArgumentException::class);
  28. $this->expectExceptionMessage(
  29. 'The byte string received does not conform to the RFC 4122 or '
  30. . 'Microsoft Corporation variants'
  31. );
  32. new Fields($bytes);
  33. }
  34. /**
  35. * These values are already in GUID byte order, for easy testing.
  36. *
  37. * @phpcsSuppress SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingTraversableTypeHintSpecification
  38. */
  39. public function nonRfc4122GuidVariantProvider(): array
  40. {
  41. // In string representation, the following IDs would begin as:
  42. // ff6f8cb0-c57d-11e1-...
  43. return [
  44. ['b08c6fff7dc5e1110b210800200c9a66'],
  45. ['b08c6fff7dc5e1111b210800200c9a66'],
  46. ['b08c6fff7dc5e1112b210800200c9a66'],
  47. ['b08c6fff7dc5e1113b210800200c9a66'],
  48. ['b08c6fff7dc5e1114b210800200c9a66'],
  49. ['b08c6fff7dc5e1115b210800200c9a66'],
  50. ['b08c6fff7dc5e1116b210800200c9a66'],
  51. ['b08c6fff7dc5e1117b210800200c9a66'],
  52. ['b08c6fff7dc5e111eb210800200c9a66'],
  53. ['b08c6fff7dc5e111fb210800200c9a66'],
  54. ];
  55. }
  56. /**
  57. * @dataProvider invalidVersionProvider
  58. */
  59. public function testConstructorThrowsExceptionIfInvalidVersion(string $guid): void
  60. {
  61. $bytes = (string) hex2bin($guid);
  62. $this->expectException(InvalidArgumentException::class);
  63. $this->expectExceptionMessage(
  64. 'The byte string received does not contain a valid version'
  65. );
  66. new Fields($bytes);
  67. }
  68. /**
  69. * @phpcsSuppress SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingTraversableTypeHintSpecification
  70. */
  71. public function invalidVersionProvider(): array
  72. {
  73. // The following UUIDs are in GUID byte order. Dashes have
  74. // been removed in the tests to distinguish these from string
  75. // representations, which are never in GUID byte order.
  76. return [
  77. ['b08c6fff7dc5e1018b210800200c9a66'],
  78. ['b08c6fff7dc5e191bb210800200c9a66'],
  79. ['b08c6fff7dc5e1a19b210800200c9a66'],
  80. ['b08c6fff7dc5e1b1ab210800200c9a66'],
  81. ['b08c6fff7dc5e1c1ab210800200c9a66'],
  82. ['b08c6fff7dc5e1d1ab210800200c9a66'],
  83. ['b08c6fff7dc5e1e1ab210800200c9a66'],
  84. ['b08c6fff7dc5e1f1ab210800200c9a66'],
  85. ];
  86. }
  87. /**
  88. * @param string|int $expectedValue
  89. *
  90. * @dataProvider fieldGetterMethodProvider
  91. */
  92. public function testFieldGetterMethods(string $bytes, string $methodName, $expectedValue): void
  93. {
  94. $bytes = (string) hex2bin($bytes);
  95. $fields = new Fields($bytes);
  96. $result = $fields->$methodName();
  97. if ($result instanceof Hexadecimal) {
  98. $this->assertSame($expectedValue, $result->toString());
  99. } else {
  100. $this->assertSame($expectedValue, $result);
  101. }
  102. }
  103. /**
  104. * @phpcsSuppress SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingTraversableTypeHintSpecification
  105. */
  106. public function fieldGetterMethodProvider(): array
  107. {
  108. // The following UUIDs are in GUID byte order. Dashes have
  109. // been removed in the tests to distinguish these from string
  110. // representations, which are never in GUID byte order.
  111. return [
  112. // For ff6f8cb0-c57d-11e1-cb21-0800200c9a66
  113. ['b08c6fff7dc5e111cb210800200c9a66', 'getClockSeq', '0b21'],
  114. ['b08c6fff7dc5e111cb210800200c9a66', 'getClockSeqHiAndReserved', 'cb'],
  115. ['b08c6fff7dc5e111cb210800200c9a66', 'getClockSeqLow', '21'],
  116. ['b08c6fff7dc5e111cb210800200c9a66', 'getNode', '0800200c9a66'],
  117. ['b08c6fff7dc5e111cb210800200c9a66', 'getTimeHiAndVersion', '11e1'],
  118. ['b08c6fff7dc5e111cb210800200c9a66', 'getTimeLow', 'ff6f8cb0'],
  119. ['b08c6fff7dc5e111cb210800200c9a66', 'getTimeMid', 'c57d'],
  120. ['b08c6fff7dc5e111cb210800200c9a66', 'getTimestamp', '1e1c57dff6f8cb0'],
  121. ['b08c6fff7dc5e111cb210800200c9a66', 'getVariant', 6],
  122. ['b08c6fff7dc5e111cb210800200c9a66', 'getVersion', 1],
  123. ['b08c6fff7dc5e111cb210800200c9a66', 'isNil', false],
  124. ['b08c6fff7dc5e111cb210800200c9a66', 'isMax', false],
  125. // For ff6f8cb0-c57d-41e1-db21-0800200c9a66
  126. ['b08c6fff7dc5e141db210800200c9a66', 'getClockSeq', '1b21'],
  127. ['b08c6fff7dc5e141db210800200c9a66', 'getClockSeqHiAndReserved', 'db'],
  128. ['b08c6fff7dc5e141db210800200c9a66', 'getClockSeqLow', '21'],
  129. ['b08c6fff7dc5e141db210800200c9a66', 'getNode', '0800200c9a66'],
  130. ['b08c6fff7dc5e141db210800200c9a66', 'getTimeHiAndVersion', '41e1'],
  131. ['b08c6fff7dc5e141db210800200c9a66', 'getTimeLow', 'ff6f8cb0'],
  132. ['b08c6fff7dc5e141db210800200c9a66', 'getTimeMid', 'c57d'],
  133. ['b08c6fff7dc5e141db210800200c9a66', 'getTimestamp', '1e1c57dff6f8cb0'],
  134. ['b08c6fff7dc5e141db210800200c9a66', 'getVariant', 6],
  135. ['b08c6fff7dc5e141db210800200c9a66', 'getVersion', 4],
  136. ['b08c6fff7dc5e141db210800200c9a66', 'isNil', false],
  137. ['b08c6fff7dc5e141db210800200c9a66', 'isMax', false],
  138. // For ff6f8cb0-c57d-31e1-8b21-0800200c9a66
  139. ['b08c6fff7dc5e1318b210800200c9a66', 'getClockSeq', '0b21'],
  140. ['b08c6fff7dc5e1318b210800200c9a66', 'getClockSeqHiAndReserved', '8b'],
  141. ['b08c6fff7dc5e1318b210800200c9a66', 'getClockSeqLow', '21'],
  142. ['b08c6fff7dc5e1318b210800200c9a66', 'getNode', '0800200c9a66'],
  143. ['b08c6fff7dc5e1318b210800200c9a66', 'getTimeHiAndVersion', '31e1'],
  144. ['b08c6fff7dc5e1318b210800200c9a66', 'getTimeLow', 'ff6f8cb0'],
  145. ['b08c6fff7dc5e1318b210800200c9a66', 'getTimeMid', 'c57d'],
  146. ['b08c6fff7dc5e1318b210800200c9a66', 'getTimestamp', '1e1c57dff6f8cb0'],
  147. ['b08c6fff7dc5e1318b210800200c9a66', 'getVariant', 2],
  148. ['b08c6fff7dc5e1318b210800200c9a66', 'getVersion', 3],
  149. ['b08c6fff7dc5e1318b210800200c9a66', 'isNil', false],
  150. ['b08c6fff7dc5e1318b210800200c9a66', 'isMax', false],
  151. // For ff6f8cb0-c57d-51e1-9b21-0800200c9a66
  152. ['b08c6fff7dc5e1519b210800200c9a66', 'getClockSeq', '1b21'],
  153. ['b08c6fff7dc5e1519b210800200c9a66', 'getClockSeqHiAndReserved', '9b'],
  154. ['b08c6fff7dc5e1519b210800200c9a66', 'getClockSeqLow', '21'],
  155. ['b08c6fff7dc5e1519b210800200c9a66', 'getNode', '0800200c9a66'],
  156. ['b08c6fff7dc5e1519b210800200c9a66', 'getTimeHiAndVersion', '51e1'],
  157. ['b08c6fff7dc5e1519b210800200c9a66', 'getTimeLow', 'ff6f8cb0'],
  158. ['b08c6fff7dc5e1519b210800200c9a66', 'getTimeMid', 'c57d'],
  159. ['b08c6fff7dc5e1519b210800200c9a66', 'getTimestamp', '1e1c57dff6f8cb0'],
  160. ['b08c6fff7dc5e1519b210800200c9a66', 'getVariant', 2],
  161. ['b08c6fff7dc5e1519b210800200c9a66', 'getVersion', 5],
  162. ['b08c6fff7dc5e1519b210800200c9a66', 'isNil', false],
  163. ['b08c6fff7dc5e1519b210800200c9a66', 'isMax', false],
  164. // For 00000000-0000-0000-0000-000000000000
  165. ['00000000000000000000000000000000', 'getClockSeq', '0000'],
  166. ['00000000000000000000000000000000', 'getClockSeqHiAndReserved', '00'],
  167. ['00000000000000000000000000000000', 'getClockSeqLow', '00'],
  168. ['00000000000000000000000000000000', 'getNode', '000000000000'],
  169. ['00000000000000000000000000000000', 'getTimeHiAndVersion', '0000'],
  170. ['00000000000000000000000000000000', 'getTimeLow', '00000000'],
  171. ['00000000000000000000000000000000', 'getTimeMid', '0000'],
  172. ['00000000000000000000000000000000', 'getTimestamp', '000000000000000'],
  173. ['00000000000000000000000000000000', 'getVariant', 2],
  174. ['00000000000000000000000000000000', 'getVersion', null],
  175. ['00000000000000000000000000000000', 'isNil', true],
  176. ['00000000000000000000000000000000', 'isMax', false],
  177. // For ffffffff-ffff-ffff-ffff-ffffffffffff
  178. ['ffffffffffffffffffffffffffffffff', 'getClockSeq', 'ffff'],
  179. ['ffffffffffffffffffffffffffffffff', 'getClockSeqHiAndReserved', 'ff'],
  180. ['ffffffffffffffffffffffffffffffff', 'getClockSeqLow', 'ff'],
  181. ['ffffffffffffffffffffffffffffffff', 'getNode', 'ffffffffffff'],
  182. ['ffffffffffffffffffffffffffffffff', 'getTimeHiAndVersion', 'ffff'],
  183. ['ffffffffffffffffffffffffffffffff', 'getTimeLow', 'ffffffff'],
  184. ['ffffffffffffffffffffffffffffffff', 'getTimeMid', 'ffff'],
  185. ['ffffffffffffffffffffffffffffffff', 'getTimestamp', 'fffffffffffffff'],
  186. ['ffffffffffffffffffffffffffffffff', 'getVariant', 2],
  187. ['ffffffffffffffffffffffffffffffff', 'getVersion', null],
  188. ['ffffffffffffffffffffffffffffffff', 'isNil', false],
  189. ['ffffffffffffffffffffffffffffffff', 'isMax', true],
  190. ];
  191. }
  192. public function testSerializingFields(): void
  193. {
  194. $bytes = (string) hex2bin('b08c6fff7dc5e111cb210800200c9a66');
  195. $fields = new Fields($bytes);
  196. $serializedFields = serialize($fields);
  197. /** @var Fields $unserializedFields */
  198. $unserializedFields = unserialize($serializedFields);
  199. $this->assertSame($fields->getBytes(), $unserializedFields->getBytes());
  200. }
  201. }