From: <bo...@us...> - 2008-03-28 15:54:19
|
Revision: 258 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=258&view=rev Author: bodewig Date: 2008-03-28 08:53:54 -0700 (Fri, 28 Mar 2008) Log Message: ----------- provide a callback for successful matches Modified Paths: -------------- trunk/xmlunit/src/java/org/custommonkey/xmlunit/Diff.java trunk/xmlunit/src/java/org/custommonkey/xmlunit/DifferenceEngine.java trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DetailedDiff.java trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_Diff.java trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DifferenceEngine.java Added Paths: ----------- trunk/xmlunit/src/java/org/custommonkey/xmlunit/MatchTracker.java Modified: trunk/xmlunit/src/java/org/custommonkey/xmlunit/Diff.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/Diff.java 2008-03-27 14:05:06 UTC (rev 257) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/Diff.java 2008-03-28 15:53:54 UTC (rev 258) @@ -83,6 +83,7 @@ private DifferenceEngine differenceEngine; private DifferenceListener differenceListenerDelegate; private ElementQualifier elementQualifierDelegate; + private MatchTracker matchTrackerDelegate; /** * Construct a Diff that compares the XML in two Strings @@ -397,12 +398,25 @@ } /** + * Override the <code>MatchTracker</code> used to track + * successfully matched nodes. + * @param delegate the MatchTracker instance to delegate handling to. + */ + public void overrideMatchTracker(MatchTracker delegate) { + this.matchTrackerDelegate = delegate; + if (differenceEngine != null) { + differenceEngine.setMatchTracker(delegate); + } + } + + /** * Lazily initializes the difference engine if it hasn't been set * via a constructor. */ private DifferenceEngine getDifferenceEngine() { return differenceEngine == null - ? new DifferenceEngine(this) : differenceEngine; + ? new DifferenceEngine(this, matchTrackerDelegate) + : differenceEngine; } } Modified: trunk/xmlunit/src/java/org/custommonkey/xmlunit/DifferenceEngine.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/DifferenceEngine.java 2008-03-27 14:05:06 UTC (rev 257) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/DifferenceEngine.java 2008-03-28 15:53:54 UTC (rev 258) @@ -70,20 +70,44 @@ private static final String NOT_NULL_NODE = "not null"; private static final String ATTRIBUTE_ABSENT = "[attribute absent]"; private final ComparisonController controller; + private MatchTracker matchTracker; private final XpathNodeTracker controlTracker; private final XpathNodeTracker testTracker; /** + * Simple constructor that uses no MatchTracker at all. + * @param controller the instance used to determine whether a Difference + * detected by this class should halt further comparison or not + * @see ComparisonController#haltComparison(Difference) + */ + public DifferenceEngine(ComparisonController controller) { + this(controller, null); + } + + /** * Simple constructor * @param controller the instance used to determine whether a Difference * detected by this class should halt further comparison or not + * @param matchTracker the instance that is notified on each + * successful match. May be null. * @see ComparisonController#haltComparison(Difference) + * @see MatchTracker#matchFound(Difference) */ - public DifferenceEngine(ComparisonController controller) { + public DifferenceEngine(ComparisonController controller, + MatchTracker matchTracker) { this.controller = controller; + this.matchTracker = matchTracker; this.controlTracker = new XpathNodeTracker(); this.testTracker = new XpathNodeTracker(); } + + /** + * @param matchTracker the instance that is notified on each + * successful match. May be null. + */ + public void setMatchTracker(MatchTracker matchTracker) { + this.matchTracker = matchTracker; + } /** * Entry point for Node comparison testing. @@ -792,21 +816,23 @@ Difference difference, XpathNodeTracker controlLoc, XpathNodeTracker testLoc) throws DifferenceFoundException { + NodeDetail controlDetail = new NodeDetail(String.valueOf(expected), + control, + controlLoc == null ? null + : controlLoc.toXpathString()); + NodeDetail testDetail = new NodeDetail(String.valueOf(actual), + test, + testLoc == null ? null + : testLoc.toXpathString()); + Difference differenceInstance = new Difference(difference, + controlDetail, testDetail); if (unequal(expected, actual)) { - NodeDetail controlDetail = new NodeDetail(String.valueOf(expected), - control, - controlLoc == null ? null - : controlLoc.toXpathString()); - NodeDetail testDetail = new NodeDetail(String.valueOf(actual), - test, - testLoc == null ? null - : testLoc.toXpathString()); - Difference differenceInstance = new Difference(difference, - controlDetail, testDetail); listener.differenceFound(differenceInstance); if (controller.haltComparison(differenceInstance)) { throw flowControlException; } + } else if (matchTracker != null) { + matchTracker.matchFound(differenceInstance); } } Added: trunk/xmlunit/src/java/org/custommonkey/xmlunit/MatchTracker.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/MatchTracker.java (rev 0) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/MatchTracker.java 2008-03-28 15:53:54 UTC (rev 258) @@ -0,0 +1,53 @@ +/* +****************************************************************** +Copyright (c) 2008, Stefan Bodewig +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the xmlunit.sourceforge.net nor the names + of its contributors may be used to endorse or promote products + derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS 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 +COPYRIGHT OWNER OR 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. + +****************************************************************** +*/ + +package org.custommonkey.xmlunit; + +/** + * Listener for callbacks from a {@link DifferenceEngine#compare + * DifferenceEngine comparison} that is notified on each and every + * comparision that resulted in a match. + */ +public interface MatchTracker { + /** + * Receive notification that 2 match. + * @param match a Difference instance as defined in {@link + * DifferenceConstants DifferenceConstants} describing the test + * that matched and containing the detail of the nodes that have + * been compared + */ + void matchFound(Difference difference); +} \ No newline at end of file Property changes on: trunk/xmlunit/src/java/org/custommonkey/xmlunit/MatchTracker.java ___________________________________________________________________ Name: svn:eol-style + native Modified: trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DetailedDiff.java =================================================================== --- trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DetailedDiff.java 2008-03-27 14:05:06 UTC (rev 257) +++ trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DetailedDiff.java 2008-03-28 15:53:54 UTC (rev 258) @@ -311,6 +311,11 @@ return new DetailedDiff(super.buildDiff(control, test)); } + protected Diff buildDiff(String control, String test, + DifferenceEngine engine) throws Exception { + return new DetailedDiff(super.buildDiff(control, test, engine)); + } + public test_DetailedDiff(String name) { super(name); firstForecast = "<weather><today icon=\"clouds\" temp=\"17\">" Modified: trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_Diff.java =================================================================== --- trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_Diff.java 2008-03-27 14:05:06 UTC (rev 257) +++ trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_Diff.java 2008-03-28 15:53:54 UTC (rev 258) @@ -487,6 +487,12 @@ return new Diff(control, test); } + protected Diff buildDiff(String control, String test, + DifferenceEngine engine) throws Exception { + return new Diff(XMLUnit.buildControlDocument(control), + XMLUnit.buildTestDocument(test), engine); + } + /** * Construct a test * @param name Test name @@ -764,4 +770,77 @@ assertFalse(diff.toString(), diff.identical()); assertFalse(diff.toString(), diff.similar()); } + + public void testMatchTrackerSetViaOverride() throws Exception { + Diff diff = buildDiff("<foo/>", "<foo/>"); + final int[] count = new int[1]; + diff.overrideMatchTracker(new MatchTracker() { + public void matchFound(Difference d) { + count[0]++; + } + }); + assertTrue(diff.identical()); + // NODE_TYPE (not null), NODE_TYPE(Document), NAMESPACE_URI(none), + // NAMESPACE_PREFIX(none), HAS_DOCTYPE_DECLARATION(no), + // HAS_CHILD_NODES(true) + // + // NODE_TYPE(Element), NAMESPACE_URI(none), + // NAMESPACE_PREFIX(none), ELEMENT_TAG_NAME(foo), + // ELEMENT_NUM_ATTRIBUTE(none), HAS_CHILD_NODES(false) + assertEquals(12, count[0]); + } + + public void testMatchTrackerSetViaEngine() throws Exception { + final int[] count = new int[1]; + DifferenceEngine engine = + new DifferenceEngine(new ComparisonController() { + public boolean haltComparison(Difference afterDifference) { + fail("haltComparison invoked"); + // NOTREACHED + return false; + } + }, new MatchTracker() { + public void matchFound(Difference d) { + count[0]++; + } + }); + Diff diff = buildDiff("<foo/>", "<foo/>", engine); + assertTrue(diff.identical()); + // NODE_TYPE (not null), NODE_TYPE(Document), NAMESPACE_URI(none), + // NAMESPACE_PREFIX(none), HAS_DOCTYPE_DECLARATION(no), + // HAS_CHILD_NODES(true) + // + // NODE_TYPE(Element), NAMESPACE_URI(none), + // NAMESPACE_PREFIX(none), ELEMENT_TAG_NAME(foo), + // ELEMENT_NUM_ATTRIBUTE(none), HAS_CHILD_NODES(false) + assertEquals(12, count[0]); + } + + public void testMatchTrackerSetViaOverrideOnEngine() throws Exception { + DifferenceEngine engine = + new DifferenceEngine(new ComparisonController() { + public boolean haltComparison(Difference afterDifference) { + fail("haltComparison invoked"); + // NOTREACHED + return false; + } + }); + Diff diff = buildDiff("<foo/>", "<foo/>", engine); + final int[] count = new int[1]; + diff.overrideMatchTracker(new MatchTracker() { + public void matchFound(Difference d) { + count[0]++; + } + }); + assertTrue(diff.identical()); + // NODE_TYPE (not null), NODE_TYPE(Document), NAMESPACE_URI(none), + // NAMESPACE_PREFIX(none), HAS_DOCTYPE_DECLARATION(no), + // HAS_CHILD_NODES(true) + // + // NODE_TYPE(Element), NAMESPACE_URI(none), + // NAMESPACE_PREFIX(none), ELEMENT_TAG_NAME(foo), + // ELEMENT_NUM_ATTRIBUTE(none), HAS_CHILD_NODES(false) + assertEquals(12, count[0]); + } + } Modified: trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DifferenceEngine.java =================================================================== --- trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DifferenceEngine.java 2008-03-27 14:05:06 UTC (rev 257) +++ trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DifferenceEngine.java 2008-03-28 15:53:54 UTC (rev 258) @@ -843,6 +843,40 @@ assertEquals(ATTR_NAME_NOT_FOUND_ID, listener.comparingWhat); } + public void testMatchTrackerSetViaConstructor() throws Exception { + Element control = document.createElement("foo"); + Element test = document.createElement("foo"); + final int[] count = new int[1]; + DifferenceEngine d = + new DifferenceEngine(new SimpleComparisonController(), + new MatchTracker() { + public void matchFound(Difference d) { + count[0]++; + } + }); + d.compare(control, test, listener, null); + // NODE_TYPE (not null), NODE_TYPE(Element), NAMESPACE_URI(none), + // NAMESPACE_PREFIX(none), ELEMENT_TAG_NAME(foo), + // ELEMENT_NUM_ATTRIBUTE(none), HAS_CHILD_NODES(false) + assertEquals(7, count[0]); + } + + public void testMatchTrackerSetViaSetter() throws Exception { + Element control = document.createElement("foo"); + Element test = document.createElement("foo"); + final int[] count = new int[1]; + engine.setMatchTracker(new MatchTracker() { + public void matchFound(Difference d) { + count[0]++; + } + }); + engine.compare(control, test, listener, null); + // NODE_TYPE (not null), NODE_TYPE(Element), NAMESPACE_URI(none), + // NAMESPACE_PREFIX(none), ELEMENT_TAG_NAME(foo), + // ELEMENT_NUM_ATTRIBUTE(none), HAS_CHILD_NODES(false) + assertEquals(7, count[0]); + } + private void listenToDifferences(String control, String test) throws SAXException, IOException { Document controlDoc = XMLUnit.buildControlDocument(control); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |