GenericMacroTest.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * This file is part of the Carbon package.
  5. *
  6. * (c) Brian Nesbitt <brian@nesbot.com>
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11. namespace Tests\CarbonImmutable;
  12. use BadMethodCallException;
  13. use Carbon\CarbonImmutable as Carbon;
  14. use Tests\AbstractTestCaseWithOldNow;
  15. use Throwable;
  16. class GenericMacroTest extends AbstractTestCaseWithOldNow
  17. {
  18. /**
  19. * @requires PHP < 8.0
  20. */
  21. public function testGenericMacroBinding()
  22. {
  23. Carbon::genericMacro(function ($method) {
  24. $time = preg_replace('/[A-Z]/', ' $0', $method);
  25. try {
  26. if (isset(${'this'})) {
  27. /** @var Carbon $date */
  28. $date = $this;
  29. return $date->modify($time);
  30. }
  31. return new static($time);
  32. } catch (Throwable $exception) {
  33. if (stripos($exception->getMessage(), 'Failed to parse') !== false) {
  34. throw new BadMethodCallException('Try next macro', 0, $exception);
  35. }
  36. throw $exception;
  37. }
  38. });
  39. /** @var mixed $now */
  40. $now = Carbon::now();
  41. $this->assertSame('2017-07-02', $now->nextSunday()->format('Y-m-d'));
  42. $this->assertSame('2017-06-26', Carbon::lastMonday()->format('Y-m-d'));
  43. $message = null;
  44. try {
  45. Carbon::fooBar();
  46. } catch (BadMethodCallException $exception) {
  47. $message = $exception->getMessage();
  48. }
  49. $this->assertSame('Method '.Carbon::class.'::fooBar does not exist.', $message);
  50. $message = null;
  51. try {
  52. $now->barBiz();
  53. } catch (BadMethodCallException $exception) {
  54. $message = $exception->getMessage();
  55. }
  56. $this->assertSame('Method barBiz does not exist.', $message);
  57. }
  58. public function testGenericMacro()
  59. {
  60. Carbon::genericMacro(function ($method) {
  61. $time = preg_replace('/[A-Z]/', ' $0', $method);
  62. try {
  63. return self::this()->modify($time);
  64. } catch (Throwable $exception) {
  65. if (stripos($exception->getMessage(), 'Failed to parse') !== false) {
  66. throw new BadMethodCallException('Try next macro', 0, $exception);
  67. }
  68. throw $exception;
  69. }
  70. });
  71. /** @var mixed $now */
  72. $now = Carbon::now();
  73. $this->assertSame('2017-07-02', $now->nextSunday()->format('Y-m-d'));
  74. $this->assertSame('2017-06-26', Carbon::lastMonday()->format('Y-m-d'));
  75. $message = null;
  76. try {
  77. Carbon::fooBar();
  78. } catch (BadMethodCallException $exception) {
  79. $message = $exception->getMessage();
  80. }
  81. $this->assertSame('Method '.Carbon::class.'::fooBar does not exist.', $message);
  82. $message = null;
  83. try {
  84. $now->barBiz();
  85. } catch (BadMethodCallException $exception) {
  86. $message = $exception->getMessage();
  87. }
  88. $this->assertSame('Method barBiz does not exist.', $message);
  89. }
  90. public function testGenericMacroPriority()
  91. {
  92. Carbon::genericMacro(function ($method) {
  93. if (!str_starts_with($method, 'myPrefix')) {
  94. throw new BadMethodCallException('Try next macro', 0);
  95. }
  96. return 'first';
  97. });
  98. Carbon::genericMacro(function ($method) {
  99. if (!str_starts_with($method, 'myPrefix')) {
  100. throw new BadMethodCallException('Try next macro', 0);
  101. }
  102. return 'second';
  103. }, 1);
  104. Carbon::genericMacro(function ($method) {
  105. if (!str_starts_with($method, 'myPrefix')) {
  106. throw new BadMethodCallException('Try next macro', 0);
  107. }
  108. return 'third';
  109. }, -1);
  110. Carbon::macro('myPrefixFooBar', function () {
  111. return 'myPrefixFooBar';
  112. });
  113. /** @var mixed $now */
  114. $now = Carbon::now();
  115. $this->assertSame('second', $now->myPrefixSomething());
  116. $this->assertSame('second', Carbon::myPrefixSomething());
  117. $this->assertSame('myPrefixFooBar', $now->myPrefixFooBar());
  118. $this->assertSame('myPrefixFooBar', Carbon::myPrefixFooBar());
  119. }
  120. public function testLocalGenericMacroPriority()
  121. {
  122. Carbon::genericMacro(function ($method) {
  123. if (!str_starts_with($method, 'mlp')) {
  124. throw new BadMethodCallException('Try next macro', 0);
  125. }
  126. return 'first';
  127. });
  128. Carbon::genericMacro(function ($method) {
  129. if (!str_starts_with($method, 'mlp')) {
  130. throw new BadMethodCallException('Try next macro', 0);
  131. }
  132. return 'second';
  133. }, 1);
  134. Carbon::genericMacro(function ($method) {
  135. if (!str_starts_with($method, 'mlp')) {
  136. throw new BadMethodCallException('Try next macro', 0);
  137. }
  138. return 'third';
  139. }, -1);
  140. Carbon::macro('mlpFooBar', function () {
  141. return 'mlpFooBar';
  142. });
  143. /** @var mixed $date */
  144. $date = Carbon::now()->settings([
  145. 'genericMacros' => [
  146. function ($method) {
  147. if (!str_starts_with($method, 'mlp')) {
  148. throw new BadMethodCallException('Try next macro', 0);
  149. }
  150. return 'local-first';
  151. },
  152. function ($method) {
  153. if (!str_starts_with($method, 'mlp')) {
  154. throw new BadMethodCallException('Try next macro', 0);
  155. }
  156. return 'local-second';
  157. },
  158. ],
  159. ]);
  160. /** @var mixed $now */
  161. $now = Carbon::now();
  162. $this->assertSame('local-first', $date->mlpSomething());
  163. $this->assertSame('second', $now->mlpSomething());
  164. $this->assertSame('second', Carbon::mlpSomething());
  165. $this->assertSame('mlpFooBar', $date->mlpFooBar());
  166. $this->assertSame('mlpFooBar', $now->mlpFooBar());
  167. $this->assertSame('mlpFooBar', Carbon::mlpFooBar());
  168. }
  169. }