LongestCommonSubsequenceTest.php 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. <?php declare(strict_types=1);
  2. /*
  3. * This file is part of sebastian/diff.
  4. *
  5. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace SebastianBergmann\Diff;
  11. use PHPUnit\Framework\TestCase;
  12. /**
  13. * @coversNothing
  14. */
  15. abstract class LongestCommonSubsequenceTest extends TestCase
  16. {
  17. /**
  18. * @var LongestCommonSubsequenceCalculator
  19. */
  20. private $implementation;
  21. /**
  22. * @var string
  23. */
  24. private $memoryLimit;
  25. /**
  26. * @var int[]
  27. */
  28. private $stress_sizes = [1, 2, 3, 100, 500, 1000, 2000];
  29. protected function setUp()
  30. {
  31. $this->memoryLimit = \ini_get('memory_limit');
  32. \ini_set('memory_limit', '256M');
  33. $this->implementation = $this->createImplementation();
  34. }
  35. /**
  36. * @return LongestCommonSubsequenceCalculator
  37. */
  38. abstract protected function createImplementation();
  39. protected function tearDown()
  40. {
  41. \ini_set('memory_limit', $this->memoryLimit);
  42. }
  43. public function testBothEmpty()
  44. {
  45. $from = [];
  46. $to = [];
  47. $common = $this->implementation->calculate($from, $to);
  48. $this->assertSame([], $common);
  49. }
  50. public function testIsStrictComparison()
  51. {
  52. $from = [
  53. false, 0, 0.0, '', null, [],
  54. true, 1, 1.0, 'foo', ['foo', 'bar'], ['foo' => 'bar']
  55. ];
  56. $to = $from;
  57. $common = $this->implementation->calculate($from, $to);
  58. $this->assertSame($from, $common);
  59. $to = [
  60. false, false, false, false, false, false,
  61. true, true, true, true, true, true
  62. ];
  63. $expected = [
  64. false,
  65. true,
  66. ];
  67. $common = $this->implementation->calculate($from, $to);
  68. $this->assertSame($expected, $common);
  69. }
  70. public function testEqualSequences()
  71. {
  72. foreach ($this->stress_sizes as $size) {
  73. $range = \range(1, $size);
  74. $from = $range;
  75. $to = $range;
  76. $common = $this->implementation->calculate($from, $to);
  77. $this->assertSame($range, $common);
  78. }
  79. }
  80. public function testDistinctSequences()
  81. {
  82. $from = ['A'];
  83. $to = ['B'];
  84. $common = $this->implementation->calculate($from, $to);
  85. $this->assertSame([], $common);
  86. $from = ['A', 'B', 'C'];
  87. $to = ['D', 'E', 'F'];
  88. $common = $this->implementation->calculate($from, $to);
  89. $this->assertSame([], $common);
  90. foreach ($this->stress_sizes as $size) {
  91. $from = \range(1, $size);
  92. $to = \range($size + 1, $size * 2);
  93. $common = $this->implementation->calculate($from, $to);
  94. $this->assertSame([], $common);
  95. }
  96. }
  97. public function testCommonSubsequence()
  98. {
  99. $from = ['A', 'C', 'E', 'F', 'G'];
  100. $to = ['A', 'B', 'D', 'E', 'H'];
  101. $expected = ['A', 'E'];
  102. $common = $this->implementation->calculate($from, $to);
  103. $this->assertSame($expected, $common);
  104. $from = ['A', 'C', 'E', 'F', 'G'];
  105. $to = ['B', 'C', 'D', 'E', 'F', 'H'];
  106. $expected = ['C', 'E', 'F'];
  107. $common = $this->implementation->calculate($from, $to);
  108. $this->assertSame($expected, $common);
  109. foreach ($this->stress_sizes as $size) {
  110. $from = $size < 2 ? [1] : \range(1, $size + 1, 2);
  111. $to = $size < 3 ? [1] : \range(1, $size + 1, 3);
  112. $expected = $size < 6 ? [1] : \range(1, $size + 1, 6);
  113. $common = $this->implementation->calculate($from, $to);
  114. $this->assertSame($expected, $common);
  115. }
  116. }
  117. public function testSingleElementSubsequenceAtStart()
  118. {
  119. foreach ($this->stress_sizes as $size) {
  120. $from = \range(1, $size);
  121. $to = \array_slice($from, 0, 1);
  122. $common = $this->implementation->calculate($from, $to);
  123. $this->assertSame($to, $common);
  124. }
  125. }
  126. public function testSingleElementSubsequenceAtMiddle()
  127. {
  128. foreach ($this->stress_sizes as $size) {
  129. $from = \range(1, $size);
  130. $to = \array_slice($from, (int) ($size / 2), 1);
  131. $common = $this->implementation->calculate($from, $to);
  132. $this->assertSame($to, $common);
  133. }
  134. }
  135. public function testSingleElementSubsequenceAtEnd()
  136. {
  137. foreach ($this->stress_sizes as $size) {
  138. $from = \range(1, $size);
  139. $to = \array_slice($from, $size - 1, 1);
  140. $common = $this->implementation->calculate($from, $to);
  141. $this->assertSame($to, $common);
  142. }
  143. }
  144. public function testReversedSequences()
  145. {
  146. $from = ['A', 'B'];
  147. $to = ['B', 'A'];
  148. $expected = ['A'];
  149. $common = $this->implementation->calculate($from, $to);
  150. $this->assertSame($expected, $common);
  151. foreach ($this->stress_sizes as $size) {
  152. $from = \range(1, $size);
  153. $to = \array_reverse($from);
  154. $common = $this->implementation->calculate($from, $to);
  155. $this->assertSame([1], $common);
  156. }
  157. }
  158. public function testStrictTypeCalculate()
  159. {
  160. $diff = $this->implementation->calculate(['5'], ['05']);
  161. $this->assertInternalType('array', $diff);
  162. $this->assertCount(0, $diff);
  163. }
  164. }