/* * ==================================================================== * * 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"); } } }