/*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2003 The Apache Software Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowledgement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgement may appear in the software itself,
* if and wherever such third-party acknowledgements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.commons.jrcs.diff;
import junit.framework.*;
public abstract class DiffTest
extends TestCase
{
static final int LARGE=2*1024;
protected DiffAlgorithm algorithm;
public DiffTest(String testName, DiffAlgorithm algorithm)
{
super(testName);
this.algorithm = algorithm;
}
public static Test suite()
{
return new TestSuite(DiffTest.class);
}
Object[] empty = new Object[]
{};
Object[] original = new String[]
{
"[1] one",
"[2] two",
"[3] three",
"[4] four",
"[5] five",
"[6] six",
"[7] seven",
"[8] eight",
"[9] nine"
};
// lines 3 and 9 deleted
Object[] rev1 = new String[]
{
"[1] one",
"[2] two",
"[4] four",
"[5] five",
"[6] six",
"[7] seven",
"[8] eight",
};
// lines 7 and 8 changed, 9 deleted
Object[] rev2 = new String[]
{
"[1] one",
"[2] two",
"[3] three",
"[4] four",
"[5] five",
"[6] six",
"[7] seven revised",
"[8] eight revised",
};
public void testCompare()
{
assertTrue(!Diff.compare(original, empty));
assertTrue(!Diff.compare(empty, original));
assertTrue(Diff.compare(empty, empty));
assertTrue(Diff.compare(original, original));
}
public void testEmptySequences()
throws DifferentiationFailedException
{
String[] emptyOrig = {};
String[] emptyRev = {};
Revision revision = Diff.diff(emptyOrig, emptyRev, algorithm);
assertEquals("revision size is not zero", 0, revision.size());
}
public void testOriginalEmpty()
throws DifferentiationFailedException
{
String[] emptyOrig = {};
String[] rev = {"1", "2", "3"};
Revision revision = Diff.diff(emptyOrig, rev, algorithm);
assertEquals("revision size should be one", 1, revision.size());
assertTrue(revision.getDelta(0) instanceof AddDelta);
}
public void testRevisedEmpty()
throws DifferentiationFailedException
{
String[] orig = {"1", "2", "3"};
String[] emptyRev = {};
Revision revision = Diff.diff(orig, emptyRev, algorithm);
assertEquals("revision size should be one", 1, revision.size());
assertTrue(revision.getDelta(0) instanceof DeleteDelta);
}
public void testDeleteAll()
throws DifferentiationFailedException, PatchFailedException
{
Revision revision = Diff.diff(original, empty, algorithm);
assertEquals(1, revision.size());
assertEquals(DeleteDelta.class, revision.getDelta(0).getClass());
assertTrue(Diff.compare(revision.patch(original), empty));
}
public void testTwoDeletes()
throws DifferentiationFailedException, PatchFailedException
{
Revision revision = Diff.diff(original, rev1, algorithm);
assertEquals(2, revision.size());
assertEquals(DeleteDelta.class, revision.getDelta(0).getClass());
assertEquals(DeleteDelta.class, revision.getDelta(1).getClass());
assertTrue(Diff.compare(revision.patch(original), rev1));
assertEquals("3d2" + Diff.NL +
"< [3] three" + Diff.NL +
"9d7" + Diff.NL +
"< [9] nine" + Diff.NL
, revision.toString());
}
public void testChangeAtTheEnd()
throws DifferentiationFailedException, PatchFailedException
{
Revision revision = Diff.diff(original, rev2, algorithm);
assertEquals(1, revision.size());
assertEquals(ChangeDelta.class, revision.getDelta(0).getClass());
assertTrue(Diff.compare(revision.patch(original), rev2));
assertEquals("d7 3" + Diff.NL +
"a9 2" + Diff.NL +
"[7] seven revised" + Diff.NL +
"[8] eight revised" + Diff.NL,
revision.toRCSString());
}
public void testPatchFailed()
throws DifferentiationFailedException
{
try
{
Revision revision = Diff.diff(original, rev2, algorithm);
assertTrue(!Diff.compare(revision.patch(rev1), rev2));
fail("PatchFailedException not thrown");
}
catch (PatchFailedException e)
{
}
}
public void testPreviouslyFailedShuffle()
throws DifferentiationFailedException, PatchFailedException
{
Object[] orig = new String[]
{
"[1] one",
"[2] two",
"[3] three",
"[4] four",
"[5] five",
"[6] six"
};
Object[] rev = new String[]
{
"[3] three",
"[1] one",
"[5] five",
"[2] two",
"[6] six",
"[4] four"
};
Revision revision = Diff.diff(orig, rev, algorithm);
Object[] patched = revision.patch(orig);
assertTrue(Diff.compare(patched, rev));
}
public void testEdit5()
throws DifferentiationFailedException, PatchFailedException
{
Object[] orig = new String[]
{
"[1] one",
"[2] two",
"[3] three",
"[4] four",
"[5] five",
"[6] six"
};
Object[] rev = new String[]
{
"one revised",
"two revised",
"[2] two",
"[3] three",
"five revised",
"six revised",
"[5] five"
};
Revision revision = Diff.diff(orig, rev, algorithm);
Object[] patched = revision.patch(orig);
assertTrue(Diff.compare(patched, rev));
}
public void testShuffle()
throws DifferentiationFailedException, PatchFailedException
{
Object[] orig = new String[]
{
"[1] one",
"[2] two",
"[3] three",
"[4] four",
"[5] five",
"[6] six"
};
for (int seed = 0; seed < 10; seed++)
{
Object[] shuffle = Diff.shuffle(orig);
Revision revision = Diff.diff(orig, shuffle, algorithm);
Object[] patched = revision.patch(orig);
if (!Diff.compare(patched, shuffle))
{
fail("iter " + seed + " revisions differ after patch");
}
}
}
public void testRandomEdit()
throws DifferentiationFailedException, PatchFailedException
{
Object[] orig = original;
for (int seed = 0; seed < 10; seed++)
{
Object[] random = Diff.randomEdit(orig, seed);
Revision revision = Diff.diff(orig, random, algorithm);
Object[] patched = revision.patch(orig);
if (!Diff.compare(patched, random))
{
fail("iter " + seed + " revisions differ after patch");
}
orig = random;
}
}
public void testVisitor()
{
Object[] orig = new String[]
{
"[1] one",
"[2] two",
"[3] three",
"[4] four",
"[5] five",
"[6] six"
};
Object[] rev = new String[]
{
"[1] one",
"[2] two revised",
"[3] three",
"[4] four revised",
"[5] five",
"[6] six"
};
class Visitor
implements RevisionVisitor
{
StringBuffer sb = new StringBuffer();
public void visit(Revision revision)
{
sb.append("visited Revision\n");
}
public void visit(DeleteDelta delta)
{
visit( (Delta) delta);
}
public void visit(ChangeDelta delta)
{
visit( (Delta) delta);
}
public void visit(AddDelta delta)
{
visit( (Delta) delta);
}
public void visit(Delta delta)
{
sb.append(delta.getRevised());
sb.append("\n");
}
public String toString()
{
return sb.toString();
}
}
Visitor visitor = new Visitor();
try
{
Diff.diff(orig, rev, algorithm).accept(visitor);
assertEquals(visitor.toString(),
"visited Revision\n" +
"[2] two revised\n" +
"[4] four revised\n");
}
catch (Exception e)
{
fail(e.toString());
}
}
public void testAlternativeAlgorithm()
throws DifferentiationFailedException, PatchFailedException
{
Revision revision = Diff.diff(original, rev2, new SimpleDiff());
assertEquals(1, revision.size());
assertEquals(ChangeDelta.class, revision.getDelta(0).getClass());
assertTrue(Diff.compare(revision.patch(original), rev2));
assertEquals("d7 3" + Diff.NL +
"a9 2" + Diff.NL +
"[7] seven revised" + Diff.NL +
"[8] eight revised" + Diff.NL,
revision.toRCSString());
}
public void testLargeShuffles()
throws DifferentiationFailedException, PatchFailedException
{
Object[] orig = Diff.randomSequence(LARGE);
for (int seed = 0; seed < 3; seed++)
{
Object[] rev = Diff.shuffle(orig);
Revision revision = Diff.diff(orig, rev, algorithm);
Object[] patched = revision.patch(orig);
if (!Diff.compare(patched, rev))
{
fail("iter " + seed + " revisions differ after patch");
}
orig = rev;
}
}
public void testLargeShuffleEdits()
throws DifferentiationFailedException, PatchFailedException
{
Object[] orig = Diff.randomSequence(LARGE);
for (int seed = 0; seed < 3; seed++)
{
Object[] rev = Diff.randomEdit(orig, seed);
Revision revision = Diff.diff(orig, rev, algorithm);
Object[] patched = revision.patch(orig);
if (!Diff.compare(patched, rev))
{
fail("iter " + seed + " revisions differ after patch");
}
}
}
public void testLargeAllEdited()
throws DifferentiationFailedException, PatchFailedException
{
Object[] orig = Diff.randomSequence(LARGE);
Object[] rev = Diff.editAll(orig);
Revision revision = Diff.diff(orig, rev, algorithm);
Object[] patched = revision.patch(orig);
if (!Diff.compare(patched, rev))
{
fail("revisions differ after patch");
}
}
}