Skip to content

Commit 0afc0ed

Browse files
author
Guillaume Crico
committed
Add some tests for LCS TimeEfficientImplementation.
1 parent 3e22c89 commit 0afc0ed

File tree

1 file changed

+217
-0
lines changed

1 file changed

+217
-0
lines changed
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
<?php
2+
/**
3+
* Diff
4+
*
5+
* Copyright (c) 2001-2014, Sebastian Bergmann <[email protected]>.
6+
* All rights reserved.
7+
*
8+
* Redistribution and use in source and binary forms, with or without
9+
* modification, are permitted provided that the following conditions
10+
* are met:
11+
*
12+
* * Redistributions of source code must retain the above copyright
13+
* notice, this list of conditions and the following disclaimer.
14+
*
15+
* * Redistributions in binary form must reproduce the above copyright
16+
* notice, this list of conditions and the following disclaimer in
17+
* the documentation and/or other materials provided with the
18+
* distribution.
19+
*
20+
* * Neither the name of Sebastian Bergmann nor the names of his
21+
* contributors may be used to endorse or promote products derived
22+
* from this software without specific prior written permission.
23+
*
24+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27+
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28+
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30+
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34+
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35+
* POSSIBILITY OF SUCH DAMAGE.
36+
*
37+
* @package Diff
38+
* @author Guillaume Crico <[email protected]>
39+
* @copyright 2001-2014 Sebastian Bergmann <[email protected]>
40+
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
41+
* @link http://www.github.com/sebastianbergmann/diff
42+
*/
43+
44+
namespace SebastianBergmann\Diff\LCS;
45+
46+
use PHPUnit_Framework_TestCase;
47+
48+
/**
49+
* Some of these tests are volontary stressfull, in order to give some approximative benchmark hints.
50+
*/
51+
class TimeEfficientImplementationTest extends PHPUnit_Framework_TestCase
52+
{
53+
private $implementation;
54+
private $memory_limit;
55+
private $stress_sizes = array(1, 2, 3, 100, 500, 1000, 2000);
56+
57+
protected function setUp()
58+
{
59+
$this->memory_limit = ini_get('memory_limit');
60+
ini_set('memory_limit', '256M');
61+
62+
$this->implementation = new TimeEfficientImplementation;
63+
}
64+
65+
protected function tearDown()
66+
{
67+
ini_set('memory_limit', $this->memory_limit);
68+
}
69+
70+
public function testBothEmpty()
71+
{
72+
$from = array();
73+
$to = array();
74+
$common = $this->implementation->calculate($from, $to);
75+
76+
$this->assertEquals(array(), $common);
77+
}
78+
79+
public function testIsStrictComparison()
80+
{
81+
$from = array(
82+
false, 0, 0.0, '', null, array(),
83+
true, 1, 1.0, 'foo', array('foo', 'bar'), array('foo' => 'bar')
84+
);
85+
$to = $from;
86+
$common = $this->implementation->calculate($from, $to);
87+
88+
$this->assertEquals($from, $common);
89+
90+
$to = array(
91+
false, false, false, false, false, false,
92+
true, true, true, true, true, true
93+
);
94+
$expected = array(
95+
false,
96+
true,
97+
);
98+
$common = $this->implementation->calculate($from, $to);
99+
100+
$this->assertEquals($expected, $common);
101+
}
102+
103+
public function testEqualSequences()
104+
{
105+
foreach ($this->stress_sizes as $size) {
106+
$range = range(1, $size);
107+
$from = $range;
108+
$to = $range;
109+
$common = $this->implementation->calculate($from, $to);
110+
111+
$this->assertEquals($range, $common);
112+
}
113+
}
114+
115+
public function testDistinctSequences()
116+
{
117+
$from = array('A');
118+
$to = array('B');
119+
$common = $this->implementation->calculate($from, $to);
120+
$this->assertEquals(array(), $common);
121+
122+
$from = array('A', 'B', 'C');
123+
$to = array('D', 'E', 'F');
124+
$common = $this->implementation->calculate($from, $to);
125+
$this->assertEquals(array(), $common);
126+
127+
foreach ($this->stress_sizes as $size) {
128+
$from = range(1, $size);
129+
$to = range($size + 1, $size * 2);
130+
$common = $this->implementation->calculate($from, $to);
131+
$this->assertEquals(array(), $common);
132+
}
133+
}
134+
135+
public function testCommonSubsequence()
136+
{
137+
$from = array('A', 'C', 'E', 'F', 'G' );
138+
$to = array('A', 'B', 'D', 'E', 'H');
139+
$expected = array('A', 'E' );
140+
$common = $this->implementation->calculate($from, $to);
141+
$this->assertEquals($expected, $common);
142+
143+
$from = array('A', 'C', 'E', 'F', 'G' );
144+
$to = array( 'B', 'C', 'D', 'E', 'F', 'H');
145+
$expected = array('C', 'E', 'F' );
146+
$common = $this->implementation->calculate($from, $to);
147+
$this->assertEquals($expected, $common);
148+
149+
foreach ($this->stress_sizes as $size) {
150+
$from = $size < 2 ? array(1) : range(1, $size + 1, 2);
151+
$to = $size < 3 ? array(1) : range(1, $size + 1, 3);
152+
$expected = $size < 6 ? array(1) : range(1, $size + 1, 6);
153+
$common = $this->implementation->calculate($from, $to);
154+
155+
$this->assertEquals($expected, $common);
156+
}
157+
}
158+
159+
public function testSingleElementSubsequenceAtStart()
160+
{
161+
foreach ($this->stress_sizes as $size) {
162+
$from = range(1, $size);
163+
$to = array_slice($from, 0, 1);
164+
$common = $this->implementation->calculate($from, $to);
165+
166+
$this->assertEquals($to, $common);
167+
}
168+
}
169+
170+
public function testSingleElementSubsequenceAtMiddle()
171+
{
172+
foreach ($this->stress_sizes as $size) {
173+
$from = range(1, $size);
174+
$to = array_slice($from, (int) $size / 2, 1);
175+
$common = $this->implementation->calculate($from, $to);
176+
177+
$this->assertEquals($to, $common);
178+
}
179+
}
180+
181+
public function testSingleElementSubsequenceAtEnd()
182+
{
183+
foreach ($this->stress_sizes as $size) {
184+
$from = range(1, $size);
185+
$to = array_slice($from, $size - 1, 1);
186+
$common = $this->implementation->calculate($from, $to);
187+
188+
$this->assertEquals($to, $common);
189+
}
190+
}
191+
192+
public function testReversedSequences()
193+
{
194+
// The values are unique and the second sequence is the reverse
195+
// of the first sequence.
196+
// The LCS must return a single value: the first value of the
197+
// first sequence (which is the same than the last value of the
198+
// second sequence).
199+
//
200+
// I don't know --yet-- if it is really important!
201+
// As the values are unique, both results are "longest common
202+
// sequence"! In fact, any value from teh set would be valid!
203+
//
204+
// And that too bad, because if we were allowed to return the
205+
// first value of the first sequence, it would be much faster!
206+
// (by building the matrix backward and gathering the common
207+
// items in the original direction.)
208+
//
209+
foreach ($this->stress_sizes as $size) {
210+
$from = range(1, $size);
211+
$to = array_reverse($from);
212+
$common = $this->implementation->calculate($from, $to);
213+
214+
$this->assertEquals(array(1), $common);
215+
}
216+
}
217+
}

0 commit comments

Comments
 (0)