GenericMacroTest.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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\Carbon;
  12. use BadMethodCallException;
  13. use Carbon\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. if (version_compare(PHP_VERSION, '8.0.0-dev', '>=')) {
  24. $this->markTestSkipped('Use of $this in macros is deprecated and may not work in PHP 8.');
  25. }
  26. Carbon::genericMacro(function ($method) {
  27. $time = preg_replace('/[A-Z]/', ' $0', $method);
  28. try {
  29. if (isset(${'this'})) {
  30. /** @var Carbon $date */
  31. $date = $this;
  32. return $date->modify($time);
  33. }
  34. return new static($time);
  35. } catch (Throwable $exception) {
  36. if (stripos($exception->getMessage(), 'Failed to parse') !== false) {
  37. throw new BadMethodCallException('Try next macro', 0, $exception);
  38. }
  39. throw $exception;
  40. }
  41. });
  42. /** @var mixed $now */
  43. $now = Carbon::now();
  44. $this->assertSame('2017-07-02', $now->nextSunday()->format('Y-m-d'));
  45. $this->assertSame('2017-06-26', Carbon::lastMonday()->format('Y-m-d'));
  46. $message = null;
  47. try {
  48. Carbon::fooBar();
  49. } catch (BadMethodCallException $exception) {
  50. $message = $exception->getMessage();
  51. }
  52. $this->assertSame('Method '.Carbon::class.'::fooBar does not exist.', $message);
  53. $message = null;
  54. try {
  55. $now->barBiz();
  56. } catch (BadMethodCallException $exception) {
  57. $message = $exception->getMessage();
  58. }
  59. $this->assertSame('Method barBiz does not exist.', $message);
  60. }
  61. public function testGenericMacro()
  62. {
  63. Carbon::genericMacro(function ($method) {
  64. $time = preg_replace('/[A-Z]/', ' $0', $method);
  65. try {
  66. return self::this()->modify($time);
  67. } catch (Throwable $exception) {
  68. if (stripos($exception->getMessage(), 'Failed to parse') !== false) {
  69. throw new BadMethodCallException('Try next macro', 0, $exception);
  70. }
  71. throw $exception;
  72. }
  73. });
  74. /** @var mixed $now */
  75. $now = Carbon::now();
  76. $this->assertSame('2017-07-02', $now->nextSunday()->format('Y-m-d'));
  77. $this->assertSame('2017-06-26', Carbon::lastMonday()->format('Y-m-d'));
  78. $message = null;
  79. try {
  80. Carbon::fooBar();
  81. } catch (BadMethodCallException $exception) {
  82. $message = $exception->getMessage();
  83. }
  84. $this->assertSame('Method '.Carbon::class.'::fooBar does not exist.', $message);
  85. $message = null;
  86. try {
  87. $now->barBiz();
  88. } catch (BadMethodCallException $exception) {
  89. $message = $exception->getMessage();
  90. }
  91. $this->assertSame('Method barBiz does not exist.', $message);
  92. }
  93. public function testGenericMacroPriority()
  94. {
  95. Carbon::genericMacro(function ($method) {
  96. if (!str_starts_with($method, 'myPrefix')) {
  97. throw new BadMethodCallException('Try next macro', 0);
  98. }
  99. return 'first';
  100. });
  101. Carbon::genericMacro(function ($method) {
  102. if (!str_starts_with($method, 'myPrefix')) {
  103. throw new BadMethodCallException('Try next macro', 0);
  104. }
  105. return 'second';
  106. }, 1);
  107. Carbon::genericMacro(function ($method) {
  108. if (!str_starts_with($method, 'myPrefix')) {
  109. throw new BadMethodCallException('Try next macro', 0);
  110. }
  111. return 'third';
  112. }, -1);
  113. Carbon::macro('myPrefixFooBar', function () {
  114. return 'myPrefixFooBar';
  115. });
  116. /** @var mixed $now */
  117. $now = Carbon::now();
  118. $this->assertSame('second', $now->myPrefixSomething());
  119. $this->assertSame('second', Carbon::myPrefixSomething());
  120. $this->assertSame('myPrefixFooBar', $now->myPrefixFooBar());
  121. $this->assertSame('myPrefixFooBar', Carbon::myPrefixFooBar());
  122. }
  123. public function testLocalGenericMacroPriority()
  124. {
  125. Carbon::genericMacro(function ($method) {
  126. if (!str_starts_with($method, 'mlp')) {
  127. throw new BadMethodCallException('Try next macro', 0);
  128. }
  129. return 'first';
  130. });
  131. Carbon::genericMacro(function ($method) {
  132. if (!str_starts_with($method, 'mlp')) {
  133. throw new BadMethodCallException('Try next macro', 0);
  134. }
  135. return 'second';
  136. }, 1);
  137. Carbon::genericMacro(function ($method) {
  138. if (!str_starts_with($method, 'mlp')) {
  139. throw new BadMethodCallException('Try next macro', 0);
  140. }
  141. return 'third';
  142. }, -1);
  143. Carbon::macro('mlpFooBar', function () {
  144. return 'mlpFooBar';
  145. });
  146. /** @var mixed $date */
  147. $date = Carbon::now()->settings([
  148. 'genericMacros' => [
  149. function ($method) {
  150. if (!str_starts_with($method, 'mlp')) {
  151. throw new BadMethodCallException('Try next macro', 0);
  152. }
  153. return 'local-first';
  154. },
  155. function ($method) {
  156. if (!str_starts_with($method, 'mlp')) {
  157. throw new BadMethodCallException('Try next macro', 0);
  158. }
  159. return 'local-second';
  160. },
  161. ],
  162. ]);
  163. /** @var mixed $now */
  164. $now = Carbon::now();
  165. $this->assertSame('local-first', $date->mlpSomething());
  166. $this->assertSame('second', $now->mlpSomething());
  167. $this->assertSame('second', Carbon::mlpSomething());
  168. $this->assertSame('mlpFooBar', $date->mlpFooBar());
  169. $this->assertSame('mlpFooBar', $now->mlpFooBar());
  170. $this->assertSame('mlpFooBar', Carbon::mlpFooBar());
  171. }
  172. }