You can subscribe to this list here.
2007 |
Jan
|
Feb
(3) |
Mar
(18) |
Apr
(39) |
May
(15) |
Jun
(12) |
Jul
(3) |
Aug
(23) |
Sep
|
Oct
(1) |
Nov
(1) |
Dec
(3) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2008 |
Jan
(21) |
Feb
(23) |
Mar
(33) |
Apr
(8) |
May
(1) |
Jun
(22) |
Jul
|
Aug
(1) |
Sep
(1) |
Oct
(6) |
Nov
|
Dec
(11) |
2009 |
Jan
(5) |
Feb
|
Mar
(2) |
Apr
(24) |
May
(36) |
Jun
(18) |
Jul
(2) |
Aug
(3) |
Sep
(9) |
Oct
(3) |
Nov
(1) |
Dec
|
2010 |
Jan
(5) |
Feb
(3) |
Mar
|
Apr
(15) |
May
(24) |
Jun
(11) |
Jul
(8) |
Aug
(34) |
Sep
(42) |
Oct
|
Nov
|
Dec
|
2011 |
Jan
(13) |
Feb
(32) |
Mar
(35) |
Apr
(31) |
May
(33) |
Jun
(30) |
Jul
(32) |
Aug
(31) |
Sep
(30) |
Oct
(31) |
Nov
(32) |
Dec
(31) |
2012 |
Jan
(35) |
Feb
(31) |
Mar
(31) |
Apr
(30) |
May
(31) |
Jun
(34) |
Jul
(23) |
Aug
(30) |
Sep
(30) |
Oct
(29) |
Nov
(30) |
Dec
(32) |
2013 |
Jan
(25) |
Feb
(39) |
Mar
(1) |
Apr
(18) |
May
(1) |
Jun
|
Jul
(1) |
Aug
(20) |
Sep
(41) |
Oct
(32) |
Nov
(9) |
Dec
(31) |
2014 |
Jan
(31) |
Feb
(30) |
Mar
(34) |
Apr
(60) |
May
(31) |
Jun
(28) |
Jul
(32) |
Aug
(28) |
Sep
(26) |
Oct
(32) |
Nov
(43) |
Dec
(115) |
2015 |
Jan
(106) |
Feb
(101) |
Mar
(51) |
Apr
(32) |
May
(63) |
Jun
(18) |
Jul
|
Aug
(18) |
Sep
|
Oct
(1) |
Nov
(84) |
Dec
(63) |
2016 |
Jan
(26) |
Feb
(17) |
Mar
(104) |
Apr
(30) |
May
(6) |
Jun
(30) |
Jul
|
Aug
|
Sep
|
Oct
(3) |
Nov
(48) |
Dec
(22) |
2017 |
Jan
(15) |
Feb
(29) |
Mar
(43) |
Apr
(29) |
May
(25) |
Jun
(28) |
Jul
(62) |
Aug
(35) |
Sep
(35) |
Oct
(72) |
Nov
(10) |
Dec
(4) |
2018 |
Jan
(7) |
Feb
(4) |
Mar
|
Apr
(46) |
May
(20) |
Jun
(12) |
Jul
(9) |
Aug
(42) |
Sep
(4) |
Oct
(17) |
Nov
(32) |
Dec
(31) |
2019 |
Jan
(21) |
Feb
(14) |
Mar
|
Apr
(74) |
May
(25) |
Jun
(43) |
Jul
(2) |
Aug
(1) |
Sep
|
Oct
(2) |
Nov
|
Dec
(10) |
2020 |
Jan
(1) |
Feb
|
Mar
(26) |
Apr
(8) |
May
(62) |
Jun
(4) |
Jul
(25) |
Aug
|
Sep
(21) |
Oct
(24) |
Nov
(26) |
Dec
(9) |
2021 |
Jan
|
Feb
(4) |
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
(1) |
Sep
(1) |
Oct
(11) |
Nov
(1) |
Dec
(12) |
2022 |
Jan
(47) |
Feb
|
Mar
(2) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(14) |
2023 |
Jan
(3) |
Feb
|
Mar
(60) |
Apr
(9) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2024 |
Jan
(5) |
Feb
|
Mar
|
Apr
(10) |
May
(1) |
Jun
|
Jul
|
Aug
(17) |
Sep
(2) |
Oct
|
Nov
|
Dec
(1) |
2025 |
Jan
|
Feb
|
Mar
(88) |
Apr
(64) |
May
(47) |
Jun
(20) |
Jul
|
Aug
(14) |
Sep
(8) |
Oct
|
Nov
|
Dec
|
From: <bo...@us...> - 2007-04-13 13:07:56
|
Revision: 181 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=181&view=rev Author: bodewig Date: 2007-04-13 06:07:54 -0700 (Fri, 13 Apr 2007) Log Message: ----------- directory for example code from user-guide Added Paths: ----------- trunk/xmlunit/src/site/org/ trunk/xmlunit/src/site/org/custommonkey/ trunk/xmlunit/src/site/org/custommonkey/xmlunit/ trunk/xmlunit/src/site/org/custommonkey/xmlunit/examples/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2007-04-13 11:31:16
|
Revision: 180 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=180&view=rev Author: bodewig Date: 2007-04-13 04:31:15 -0700 (Fri, 13 Apr 2007) Log Message: ----------- Make ignoreComments work at the DifferenceEngine level Modified Paths: -------------- trunk/xmlunit/src/java/org/custommonkey/xmlunit/DifferenceEngine.java trunk/xmlunit/src/java/org/custommonkey/xmlunit/XpathNodeTracker.java trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DifferenceEngine.java Modified: trunk/xmlunit/src/java/org/custommonkey/xmlunit/DifferenceEngine.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/DifferenceEngine.java 2007-04-13 08:11:02 UTC (rev 179) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/DifferenceEngine.java 2007-04-13 11:31:15 UTC (rev 180) @@ -1,6 +1,6 @@ /* ****************************************************************** -Copyright (c) 2001, Jeff Martin, Tim Bacon +Copyright (c) 2001-2007, Jeff Martin, Tim Bacon All rights reserved. Redistribution and use in source and binary forms, with or without @@ -36,8 +36,10 @@ package org.custommonkey.xmlunit; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.List; import org.w3c.dom.Attr; import org.w3c.dom.CharacterData; @@ -246,15 +248,42 @@ */ protected void compareHasChildNodes(Node control, Node test, DifferenceListener listener) throws DifferenceFoundException { - Boolean controlHasChildren = control.hasChildNodes() - ? Boolean.TRUE : Boolean.FALSE; - Boolean testHasChildren = test.hasChildNodes() - ? Boolean.TRUE : Boolean.FALSE; + Boolean controlHasChildren = hasChildNodes(control); + Boolean testHasChildren = hasChildNodes(test); compare(controlHasChildren, testHasChildren, control, test, listener, HAS_CHILD_NODES); } /** + * Tests whether a Node has children, taking ignoreComments + * setting into account. + */ + private Boolean hasChildNodes(Node n) { + boolean flag = n.hasChildNodes(); + if (flag && XMLUnit.getIgnoreComments()) { + List nl = nodeList2List(n.getChildNodes()); + flag = nl.size() > 0; + } + return flag ? Boolean.TRUE : Boolean.FALSE; + } + + /** + * Returns the NodeList's Nodes as List, taking ignoreComments + * into account. + */ + static List nodeList2List(NodeList nl) { + int len = nl.getLength(); + ArrayList l = new ArrayList(len); + for (int i = 0; i < len; i++) { + Node n = nl.item(i); + if (!XMLUnit.getIgnoreComments() || !(n instanceof Comment)) { + l.add(n); + } + } + return l; + } + + /** * Compare the number of children, and if the same, compare the actual * children via their NodeLists. * @param control @@ -267,11 +296,11 @@ DifferenceListener listener, ElementQualifier elementQualifier) throws DifferenceFoundException { if (control.hasChildNodes() && test.hasChildNodes()) { - NodeList controlChildren = control.getChildNodes(); - NodeList testChildren = test.getChildNodes(); + List controlChildren = nodeList2List(control.getChildNodes()); + List testChildren = nodeList2List(test.getChildNodes()); - Integer controlLength = new Integer(controlChildren.getLength()); - Integer testLength = new Integer(testChildren.getLength()); + Integer controlLength = new Integer(controlChildren.size()); + Integer testLength = new Integer(testChildren.size()); compare(controlLength, testLength, control, test, listener, CHILD_NODELIST_LENGTH); compareNodeList(controlChildren, testChildren, @@ -292,23 +321,48 @@ * the test NodeList should be compared to the current child element in the * control NodeList. * @throws DifferenceFoundException + * @deprecated Use the version with List arguments instead */ protected void compareNodeList(final NodeList control, final NodeList test, final int numNodes, final DifferenceListener listener, final ElementQualifier elementQualifier) throws DifferenceFoundException { + compareNodeList(nodeList2List(control), nodeList2List(test), + numNodes, listener, elementQualifier); + } + /** + * Compare the contents of two node list one by one, assuming that order + * of children is NOT important: matching begins at same position in test + * list as control list. + * @param control + * @param test + * @param numNodes convenience parameter because the calling method should + * know the value already + * @param listener + * @param elementQualifier used to determine which of the child elements in + * the test NodeList should be compared to the current child element in the + * control NodeList. + * @throws DifferenceFoundException + */ + protected void compareNodeList(final List controlChildren, + final List testChildren, + final int numNodes, + final DifferenceListener listener, + final ElementQualifier elementQualifier) + throws DifferenceFoundException { + int j = 0; - final int lastTestNode = test.getLength() - 1; - testTracker.preloadNodeList(test); + final int lastTestNode = testChildren.size() - 1; + testTracker.preloadChildList(testChildren); HashMap/*<Node, Node>*/ matchingNodes = new HashMap(); HashMap/*<Node, Integer>*/ matchingNodeIndexes = new HashMap(); // first pass to find the matching nodes in control and test docs for (int i=0; i < numNodes; ++i) { - Node nextControl = control.item(i); + Node nextControl = (Node) controlChildren.get(i); boolean matchOnElement = nextControl instanceof Element; short findNodeType = nextControl.getNodeType(); int startAt = ( i > lastTestNode ? lastTestNode : i); @@ -317,12 +371,12 @@ boolean matchFound = false; while (!matchFound) { - if (findNodeType == test.item(j).getNodeType()) { + if (findNodeType == ((Node)testChildren.get(j)).getNodeType()) { matchFound = !matchOnElement || elementQualifier == null || elementQualifier - .qualifyForComparison((Element)nextControl, - (Element)test.item(j)); + .qualifyForComparison((Element) nextControl, + (Element) testChildren.get(j)); } if (!matchFound) { ++j; @@ -336,7 +390,7 @@ } } if (matchFound) { - matchingNodes.put(nextControl, test.item(j)); + matchingNodes.put(nextControl, testChildren.get(j)); matchingNodeIndexes.put(nextControl, new Integer(j)); } } @@ -346,7 +400,7 @@ // any other control nodes Collection matchingTestNodes = matchingNodes.values(); for (int i=0; i < numNodes; ++i) { - Node nextControl = control.item(i); + Node nextControl = (Node) controlChildren.get(i); Node nextTest = (Node) matchingNodes.get(nextControl); Integer testIndex = (Integer) matchingNodeIndexes.get(nextControl); if (nextTest == null) { @@ -357,8 +411,9 @@ boolean matchFound = false; while (!matchFound) { - if (test.item(j).getNodeType() == findNodeType - && !matchingTestNodes.contains(test.item(j))) { + if (((Node) testChildren.get(j)) + .getNodeType() == findNodeType + && !matchingTestNodes.contains(testChildren.get(j))) { matchFound = true; } else { ++j; @@ -371,7 +426,7 @@ } } } - nextTest = test.item(j); + nextTest = (Node) testChildren.get(j); testIndex = new Integer(j); } compareNode(nextControl, nextTest, listener, elementQualifier); @@ -531,7 +586,9 @@ */ protected void compareComment(Comment control, Comment test, DifferenceListener listener) throws DifferenceFoundException { - compareCharacterData(control, test, listener, COMMENT_VALUE); + if (!XMLUnit.getIgnoreComments()) { + compareCharacterData(control, test, listener, COMMENT_VALUE); + } } /** Modified: trunk/xmlunit/src/java/org/custommonkey/xmlunit/XpathNodeTracker.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/XpathNodeTracker.java 2007-04-13 08:11:02 UTC (rev 179) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/XpathNodeTracker.java 2007-04-13 11:31:15 UTC (rev 180) @@ -1,6 +1,6 @@ /* ****************************************************************** -Copyright (c) 2001, Jeff Martin, Tim Bacon +Copyright (c) 2001-2007, Jeff Martin, Tim Bacon All rights reserved. Redistribution and use in source and binary forms, with or without @@ -35,10 +35,10 @@ */ package org.custommonkey.xmlunit; +import java.util.ArrayList; +import java.util.HashMap; import java.util.Iterator; import java.util.List; -import java.util.ArrayList; -import java.util.HashMap; import java.util.Map; import org.w3c.dom.Attr; @@ -167,6 +167,21 @@ } /** + * Preload the items in a List by visiting each in turn + * Required for pieces of test XML whose node children can be visited + * out of sequence by a DifferenceEngine comparison + * @param nodeList the items to preload + */ + public void preloadChildList(List nodeList) { + currentEntry.trackNodesAsWellAsValues(true); + int length = nodeList.size(); + for (int i=0; i < length; ++i) { + visited((Node) nodeList.get(i)); + } + currentEntry.trackNodesAsWellAsValues(false); + } + + /** * @return the last visited node as an xpath-location String */ public String toXpathString() { Modified: trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DifferenceEngine.java =================================================================== --- trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DifferenceEngine.java 2007-04-13 08:11:02 UTC (rev 179) +++ trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DifferenceEngine.java 2007-04-13 11:31:15 UTC (rev 180) @@ -1,6 +1,6 @@ /* ****************************************************************** -Copyright (c) 200, Jeff Martin, Tim Bacon +Copyright (c) 2001-2007, Jeff Martin, Tim Bacon All rights reserved. Redistribution and use in source and binary forms, with or without @@ -731,6 +731,55 @@ assertEquals(expected, listener.comparingWhat); } + public void testExtraComment() { + testExtraComment(true); + resetListener(); + XMLUnit.setIgnoreComments(true); + try { + testExtraComment(false); + } finally { + XMLUnit.setIgnoreComments(false); + } + } + + private void testExtraComment(boolean expectDifference) { + Element control = document.createElement("foo"); + Element test = document.createElement("foo"); + Comment c = document.createComment("bar"); + control.appendChild(c); + Element cChild = document.createElement("baz"); + control.appendChild(cChild); + Element tChild = document.createElement("baz"); + test.appendChild(tChild); + engine.compare(control, test, listener, null); + assertEquals(expectDifference, listener.different); + resetListener(); + engine.compare(test, control, listener, null); + assertEquals(expectDifference, listener.different); + } + + public void testCommentContent() { + testCommentContent(true); + resetListener(); + XMLUnit.setIgnoreComments(true); + try { + testCommentContent(false); + } finally { + XMLUnit.setIgnoreComments(false); + } + } + + private void testCommentContent(boolean expectDifference) { + Element control = document.createElement("foo"); + Element test = document.createElement("foo"); + Comment c = document.createComment("bar"); + control.appendChild(c); + Comment c2 = document.createComment("baz"); + test.appendChild(c2); + engine.compare(control, test, listener, null); + assertEquals(expectDifference, listener.different); + } + 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. |
From: <bo...@us...> - 2007-04-13 08:11:04
|
Revision: 179 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=179&view=rev Author: bodewig Date: 2007-04-13 01:11:02 -0700 (Fri, 13 Apr 2007) Log Message: ----------- fix a few javadocs, remove redundant public identifiers from interfaces Modified Paths: -------------- trunk/xmlunit/src/java/org/custommonkey/xmlunit/ComparisonController.java trunk/xmlunit/src/java/org/custommonkey/xmlunit/DifferenceListener.java trunk/xmlunit/src/java/org/custommonkey/xmlunit/NodeTester.java trunk/xmlunit/src/java/org/custommonkey/xmlunit/examples/MultiLevelElementNameAndTextQualifier.java Modified: trunk/xmlunit/src/java/org/custommonkey/xmlunit/ComparisonController.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/ComparisonController.java 2007-04-12 09:07:12 UTC (rev 178) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/ComparisonController.java 2007-04-13 08:11:02 UTC (rev 179) @@ -41,13 +41,13 @@ */ public interface ComparisonController { /** - * Determine whether a Difference that this listener has been notified of + * Determine whether a Difference that the listener has been notified of * should halt further XML comparison. Default behaviour for a Diff * instance is to halt if the Difference is not recoverable. * @see Difference#isRecoverable * @param afterDifference the last Difference passed to <code>differenceFound</code> * @return true to halt further comparison, false otherwise */ - public boolean haltComparison(Difference afterDifference); + boolean haltComparison(Difference afterDifference); } Modified: trunk/xmlunit/src/java/org/custommonkey/xmlunit/DifferenceListener.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/DifferenceListener.java 2007-04-12 09:07:12 UTC (rev 178) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/DifferenceListener.java 2007-04-13 08:11:02 UTC (rev 179) @@ -49,28 +49,29 @@ * Indicates that the <code>Difference</code> is interpreted as defined * in {@link DifferenceConstants DifferenceConstants}. */ - public final int RETURN_ACCEPT_DIFFERENCE = 0; + int RETURN_ACCEPT_DIFFERENCE = 0; /** * Override return value for the <code>differenceFound</code> method. * Indicates that the nodes identified as being different should be * interpreted as being identical. */ - public final int RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL = 1; + int RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL = 1; /** * Override return value for the <code>differenceFound</code> method. * Indicates that the nodes identified as being different should be * interpreted as being similar. */ - public final int RETURN_IGNORE_DIFFERENCE_NODES_SIMILAR = 2; + int RETURN_IGNORE_DIFFERENCE_NODES_SIMILAR = 2; /** * Receive notification that 2 nodes are different. - * @param difference a Difference instance as defined in - * {@link DifferenceConstants DifferenceConstants} describing the - * cause of the difference and containing the detail of the nodes that differ - * @return int one of the RETURN_... constants describing how this difference - * was interpreted + * @param difference a Difference instance as defined in {@link + * DifferenceConstants DifferenceConstants} describing the cause + * of the difference and containing the detail of the nodes that + * differ + * @return int one of the RETURN_... constants describing how this + * difference was interpreted */ - public int differenceFound(Difference difference); + int differenceFound(Difference difference); /** * Receive notification that a comparison between 2 nodes has been skipped @@ -79,6 +80,6 @@ * @param test the test node being compared * @see DifferenceEngine */ - public void skippedComparison(Node control, Node test); + void skippedComparison(Node control, Node test); } \ No newline at end of file Modified: trunk/xmlunit/src/java/org/custommonkey/xmlunit/NodeTester.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/NodeTester.java 2007-04-12 09:07:12 UTC (rev 178) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/NodeTester.java 2007-04-13 08:11:02 UTC (rev 179) @@ -53,7 +53,7 @@ * @param forTest * @exception NodeTestException if the node fails the test */ - public void testNode(Node aNode, NodeTest forTest) throws NodeTestException ; + void testNode(Node aNode, NodeTest forTest) throws NodeTestException ; /** * Validate that the Nodes passed one-by-one to the <code>testNode</code> @@ -61,5 +61,5 @@ * @param forTest * @exception NodeTestException if this instance was expecting more nodes */ - public void noMoreNodes(NodeTest forTest) throws NodeTestException ; + void noMoreNodes(NodeTest forTest) throws NodeTestException ; } \ No newline at end of file Modified: trunk/xmlunit/src/java/org/custommonkey/xmlunit/examples/MultiLevelElementNameAndTextQualifier.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/examples/MultiLevelElementNameAndTextQualifier.java 2007-04-12 09:07:12 UTC (rev 178) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/examples/MultiLevelElementNameAndTextQualifier.java 2007-04-13 08:11:02 UTC (rev 179) @@ -1,6 +1,6 @@ /* ****************************************************************** -Copyright (c) 2001, Jeff Martin, Tim Bacon +Copyright (c) 2006-2007, Jeff Martin, Tim Bacon All rights reserved. Redistribution and use in source and binary forms, with or without This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2007-04-12 09:07:11
|
Revision: 178 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=178&view=rev Author: bodewig Date: 2007-04-12 02:07:12 -0700 (Thu, 12 Apr 2007) Log Message: ----------- whitespace changes only Modified Paths: -------------- trunk/xmlunit/src/java/org/custommonkey/xmlunit/DifferenceEngine.java Modified: trunk/xmlunit/src/java/org/custommonkey/xmlunit/DifferenceEngine.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/DifferenceEngine.java 2007-04-12 04:43:38 UTC (rev 177) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/DifferenceEngine.java 2007-04-12 09:07:12 UTC (rev 178) @@ -447,14 +447,15 @@ compareAttribute(nextAttr, compareTo, listener); if (!XMLUnit.getIgnoreAttributeOrder()) { - Attr attributeItem = (Attr) testAttr.item(i); - String testAttrName = "[attribute absent]"; - if (attributeItem != null) { - testAttrName = getUnNamespacedNodeName(attributeItem); + Attr attributeItem = (Attr) testAttr.item(i); + String testAttrName = "[attribute absent]"; + if (attributeItem != null) { + testAttrName = + getUnNamespacedNodeName(attributeItem); + } + compare(attrName, testAttrName, + nextAttr, compareTo, listener, ATTR_SEQUENCE); } - compare(attrName, testAttrName, - nextAttr, compareTo, listener, ATTR_SEQUENCE); - } } else { compare(attrName, null, control, test, listener, ATTR_NAME_NOT_FOUND); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2007-04-12 04:43:36
|
Revision: 177 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=177&view=rev Author: bodewig Date: 2007-04-11 21:43:38 -0700 (Wed, 11 Apr 2007) Log Message: ----------- Add a configuration option to ignore differences in attribute order Modified Paths: -------------- trunk/xmlunit/src/java/org/custommonkey/xmlunit/DifferenceEngine.java trunk/xmlunit/src/java/org/custommonkey/xmlunit/XMLUnit.java trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DifferenceEngine.java Modified: trunk/xmlunit/src/java/org/custommonkey/xmlunit/DifferenceEngine.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/DifferenceEngine.java 2007-04-12 04:41:45 UTC (rev 176) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/DifferenceEngine.java 2007-04-12 04:43:38 UTC (rev 177) @@ -445,7 +445,8 @@ if (compareTo != null) { compareAttribute(nextAttr, compareTo, listener); - + + if (!XMLUnit.getIgnoreAttributeOrder()) { Attr attributeItem = (Attr) testAttr.item(i); String testAttrName = "[attribute absent]"; if (attributeItem != null) { @@ -453,6 +454,7 @@ } compare(attrName, testAttrName, nextAttr, compareTo, listener, ATTR_SEQUENCE); + } } else { compare(attrName, null, control, test, listener, ATTR_NAME_NOT_FOUND); Modified: trunk/xmlunit/src/java/org/custommonkey/xmlunit/XMLUnit.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/XMLUnit.java 2007-04-12 04:41:45 UTC (rev 176) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/XMLUnit.java 2007-04-12 04:43:38 UTC (rev 177) @@ -71,6 +71,7 @@ private static boolean ignoreComments = false; private static boolean normalize = false; private static boolean normalizeWhitespace = false; + private static boolean ignoreAttributeOrder = false; private static final String STRIP_WHITESPACE_STYLESHEET = new StringBuffer(XMLConstants.XML_DECLARATION) @@ -724,5 +725,35 @@ public static boolean getNormalizeWhitespace() { return normalizeWhitespace; } + + /** + * Whether to ignore the order of attributes on an element. + * + * <p>The order of attributes has never been relevant for XML + * documents, still XMLUnit will consider two pieces of XML + * not-identical (but similar) if they differ in order of + * attributes. Set this option to false to ignore the order.</p> + * + * <p>The default value is false for backwards compatibility + * reasons.</p> + */ + public static void setIgnoreAttributeOrder(boolean b) { + ignoreAttributeOrder = b; + } + + /** + * Whether to ignore the order of attributes on an element. + * + * <p>The order of attributes has never been relevant for XML + * documents, still XMLUnit will consider two pieces of XML + * not-identical (but similar) if they differ in order of + * attributes. Set this option to false to ignore the order.</p> + * + * <p>The default value is false for backwards compatibility + * reasons.</p> + */ + public static boolean getIgnoreAttributeOrder() { + return ignoreAttributeOrder; + } } Modified: trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DifferenceEngine.java =================================================================== --- trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DifferenceEngine.java 2007-04-12 04:41:45 UTC (rev 176) +++ trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DifferenceEngine.java 2007-04-12 04:43:38 UTC (rev 177) @@ -664,6 +664,17 @@ } public void testAttributeSequence() throws Exception { + testAttributeSequence(ATTR_SEQUENCE_ID); + resetListener(); + XMLUnit.setIgnoreAttributeOrder(true); + try { + testAttributeSequence(-1); + } finally { + XMLUnit.setIgnoreAttributeOrder(false); + } + } + + private void testAttributeSequence(int expected) throws Exception { Element control = document.createElement("foo"); Element test = document.createElement("foo"); OrderPreservingNamedNodeMap controlMap = @@ -683,10 +694,21 @@ } engine.compareElementAttributes(control, test, controlMap, testMap, listener); - assertEquals(ATTR_SEQUENCE_ID, listener.comparingWhat); + assertEquals(expected, listener.comparingWhat); } public void testAttributeSequenceNS() throws Exception { + testAttributeSequenceNS(ATTR_SEQUENCE_ID); + resetListener(); + XMLUnit.setIgnoreAttributeOrder(true); + try { + testAttributeSequenceNS(-1); + } finally { + XMLUnit.setIgnoreAttributeOrder(false); + } + } + + private void testAttributeSequenceNS(int expected) throws Exception { Element control = document.createElementNS("ns", "foo"); Element test = document.createElementNS("ns", "foo"); OrderPreservingNamedNodeMap controlMap = @@ -706,7 +728,7 @@ } engine.compareElementAttributes(control, test, controlMap, testMap, listener); - assertEquals(ATTR_SEQUENCE_ID, listener.comparingWhat); + assertEquals(expected, listener.comparingWhat); } private void listenToDifferences(String control, String test) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2007-04-12 04:41:46
|
Revision: 176 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=176&view=rev Author: bodewig Date: 2007-04-11 21:41:45 -0700 (Wed, 11 Apr 2007) Log Message: ----------- Part of the comparing section Modified Paths: -------------- trunk/xmlunit/src/site/XMLUnit-Java.xml Modified: trunk/xmlunit/src/site/XMLUnit-Java.xml =================================================================== --- trunk/xmlunit/src/site/XMLUnit-Java.xml 2007-04-11 12:19:25 UTC (rev 175) +++ trunk/xmlunit/src/site/XMLUnit-Java.xml 2007-04-12 04:41:45 UTC (rev 176) @@ -994,14 +994,313 @@ <section id="comparing-basics"> <title>The Difference Engine</title> - </section> - <section id="comparing-junit3"> - <title>JUnit 3.x Convenience Methods</title> + <para>At the center of XMLUnit's support for comparisons is the + <literal>DifferenceEngine</literal> class. In practice you + rarely deal with it directly but rather use it via instances of + <literal>Diff</literal> or <literal>DetailedDiff</literal> + classes (see <xref linkend="Diff"/>).</para> + + <para>The <literal>DifferenceEngine</literal> walks two trees of + DOM <literal>Node</literal>s, the control and the test tree and + compares the nodes. Whenever it detects a difference, it sends + a message to a configured <literal>DifferenceListener</literal> + (see <xref linkend="DifferenceListener"/>) and asks a + <literal>ComparisonController</literal> (see <xref + linkend="ComparisonController"/>) whether the current comparison + should be halted.</para> + + <para>In some cases the order of elements in two pieces of XML + may not be significant. If this is true, the + <literal>DifferenceEngine</literal> needs help to determine + which <literal>Element</literal>s to compare. This is the job + of an <literal>ElementQualifier</literal> (see <xref + linkend="ElementQualifier"/>).</para> + + <para>The types of differences + <literal>DifferenceEngine</literal> can detect are enumerated in + the <literal>DifferenceConstants</literal> interface and + represented by instances of the <literal>Difference</literal> + class.</para> + + <para>A <literal>Difference</literal> can be recoverable; + recoverable <literal>Difference</literal>s make the + <literal>Diff</literal> class consider the two pieces of XML + similar while non-recoverable <literal>Difference</literal>s + render the two pieces different.</para> + + <para>The following types of <literal>Difference</literal>s are + currently detected (the first two columns refer to the + <literal>DifferenceConstants</literal> class):</para> + + <table frame="all" rules="all" pgwide="1"> + <title>Document level <literal>Difference</literal>s detected by + <literal>DifferenceEngine</literal></title> + <tgroup cols="4"> + <colspec colname="id" align="center"/> + <colspec colname="constant" align="center"/> + <colspec colname="recoverable" align="center"/> + <colspec colname="description" align="left"/> + + <thead> + <row> + <entry><literal>ID</literal></entry> + <entry><literal>Constant</literal></entry> + <entry><literal>revoverable</literal></entry> + <entry align="center">Description</entry> + </row> + </thead> + + <tbody> + <row> + <entry><literal>HAS_DOCTYPE_DECLARATION_ID</literal></entry> + <entry><literal>HAS_DOCTYPE_DECLARATION</literal></entry> + <entry><literal>true</literal></entry> + <entry>One piece of XML has a DOCTYPE declaration while + the other one has not.</entry> + </row> + <row> + <entry><literal>DOCTYPE_NAME_ID</literal></entry> + <entry><literal>DOCTYPE_NAME</literal></entry> + <entry><literal>false</literal></entry> + <entry>Both pieces of XML contain a DOCTYPE declaration + but the declarations specify different names for the + root element.</entry> + </row> + <row> + <entry><literal>DOCTYPE_PUBLIC_ID</literal></entry> + <entry><literal>DOCTYPE_PUBLIC_ID</literal></entry> + <entry><literal>false</literal></entry> + <entry>Both pieces of XML contain a DOCTYPE declaration + but the declarations specify different PUBLIC + identifiers.</entry> + </row> + <row> + <entry><literal>DOCTYPE_SYSTEM_ID</literal></entry> + <entry><literal>DOCTYPE_SYSTEM_ID</literal></entry> + <entry><literal>true</literal></entry> + <entry>Both pieces of XML contain a DOCTYPE declaration + but the declarations specify different SYSTEM + identifiers.</entry> + </row> + <row> + <entry><literal>NODE_TYPE_ID</literal></entry> + <entry><literal>NODE_TYPE</literal></entry> + <entry><literal>false</literal></entry> + <entry>The test piece of XML contains a different type + of node than was expected.</entry> + </row> + <row> + <entry><literal>NAMESPACE_PREFIX_ID</literal></entry> + <entry><literal>NAMESPACE_PREFIX</literal></entry> + <entry><literal>true</literal></entry> + <entry>Two nodes use different prefixes for the same + XML Namespace URI in the two pieces of XML.</entry> + </row> + <row> + <entry><literal>NAMESPACE_URI_ID</literal></entry> + <entry><literal>NAMESPACE_URI</literal></entry> + <entry><literal>false</literal></entry> + <entry>Two nodes in the two pieces of XML share the same + local name but use different XML Namespace URIs.</entry> + </row> + </tbody> + </tgroup> + </table> + + <table frame="all" rules="all" pgwide="1"> + <title>Element level <literal>Difference</literal>s detected by + <literal>DifferenceEngine</literal></title> + <tgroup cols="4"> + <colspec colname="id" align="center"/> + <colspec colname="constant" align="center"/> + <colspec colname="recoverable" align="center"/> + <colspec colname="description" align="left"/> + + <thead> + <row> + <entry><literal>ID</literal></entry> + <entry><literal>Constant</literal></entry> + <entry><literal>revoverable</literal></entry> + <entry align="center">Description</entry> + </row> + </thead> + + <tbody> + <row> + <entry><literal>ELEMENT_TAG_NAME_ID</literal></entry> + <entry><literal>ELEMENT_TAG_NAME</literal></entry> + <entry><literal>false</literal></entry> + <entry>The two pieces of XML contain elements with + different tag names.</entry> + </row> + <row> + <entry><literal>ELEMENT_NUM_ATTRIBUTES_ID</literal></entry> + <entry><literal>ELEMENT_NUM_ATTRIBUTES</literal></entry> + <entry><literal>false</literal></entry> + <entry>The two pieces of XML contain a common element, + but the number of attributes on the element is + different.</entry> + </row> + <row> + <entry><literal>HAS_CHILD_NODES_ID</literal></entry> + <entry><literal>HAS_CHILD_NODES</literal></entry> + <entry><literal>false</literal></entry> + <entry>An element in one piece of XML has child nodes + while the corresponding one in the other has not.</entry> + </row> + <row> + <entry><literal>CHILD_NODELIST_LENGTH_ID</literal></entry> + <entry><literal>CHILD_NODELIST_LENGTH</literal></entry> + <entry><literal>false</literal></entry> + <entry>Two elements in the two pieces of XML differ by + their number of child nodes.</entry> + </row> + <row> + <entry><literal>CHILD_NODELIST_SEQUENCE_ID</literal></entry> + <entry><literal>CHILD_NODELIST_SEQUENCE</literal></entry> + <entry><literal>true</literal></entry> + <entry>Two elements in the two pieces of XML contain the + same child nodes but in a different order.</entry> + </row> + <row> + <entry><literal>ATTR_SEQUENCE_ID</literal></entry> + <entry><literal>ATTR_SEQUENCE</literal></entry> + <entry><literal>true</literal></entry> + <entry>The attributes on an element appear in different + order in the two pieces of XML.</entry> + </row> + </tbody> + </tgroup> + </table> + + <table frame="all" rules="all" pgwide="1"> + <title>Attribute level <literal>Difference</literal>s detected by + <literal>DifferenceEngine</literal></title> + + <tgroup cols="4"> + <colspec colname="id" align="center"/> + <colspec colname="constant" align="center"/> + <colspec colname="recoverable" align="center"/> + <colspec colname="description" align="left"/> + + <thead> + <row> + <entry><literal>ID</literal></entry> + <entry><literal>Constant</literal></entry> + <entry><literal>revoverable</literal></entry> + <entry align="center">Description</entry> + </row> + </thead> + + <tbody> + <row> + <entry><literal>ATTR_VALUE_EXPLICITLY_SPECIFIED_ID</literal></entry> + <entry><literal>ATTR_VALUE_EXPLICITLY_SPECIFIED</literal></entry> + <entry><literal>true</literal></entry> + <entry>An attribute that is not required and has a + default value according to the content model of the + element in question has been specified explicitly in one + piece of XML but not in the other.</entry> + </row> + <row> + <entry><literal>ATTR_NAME_NOT_FOUND_ID</literal></entry> + <entry><literal>ATTR_NAME_NOT_FOUND</literal></entry> + <entry><literal>false</literal></entry> + <entry>One piece of XML contains an attribute on an + element that is missing in the other.</entry> + </row> + <row> + <entry><literal>ATTR_VALUE_ID</literal></entry> + <entry><literal>ATTR_VALUE</literal></entry> + <entry><literal>false</literal></entry> + <entry>The value of an element's attribute is different + in the two pieces of XML.</entry> + </row> + </tbody> + </tgroup> + </table> + + <table frame="all" rules="all" pgwide="1"> + <title>Other <literal>Difference</literal>s detected by + <literal>DifferenceEngine</literal></title> + + <tgroup cols="4"> + <colspec colname="id" align="center"/> + <colspec colname="constant" align="center"/> + <colspec colname="recoverable" align="center"/> + <colspec colname="description" align="left"/> + + <thead> + <row> + <entry><literal>ID</literal></entry> + <entry><literal>Constant</literal></entry> + <entry><literal>revoverable</literal></entry> + <entry align="center">Description</entry> + </row> + </thead> + + <tbody> + <row> + <entry><literal>COMMENT_VALUE_ID</literal></entry> + <entry><literal>COMMENT_VALUE</literal></entry> + <entry><literal>false</literal></entry> + <entry>The content of two comments is different in the + two pieces of XML.</entry> + </row> + <row> + <entry><literal>PROCESSING_INSTRUCTION_TARGET_ID</literal></entry> + <entry><literal>PROCESSING_INSTRUCTION_TARGET</literal></entry> + <entry><literal>false</literal></entry> + <entry>The target of two processing instructions is + different in the two pieces of XML.</entry> + </row> + <row> + <entry><literal>PROCESSING_INSTRUCTION_DATA_ID</literal></entry> + <entry><literal>PROCESSING_INSTRUCTION_DATA</literal></entry> + <entry><literal>false</literal></entry> + <entry>The data of two processing instructions is + different in the two pieces of XML.</entry> + </row> + + <row> + <entry><literal>CDATA_VALUE_ID</literal></entry> + <entry><literal>CDATA_VALUE</literal></entry> + <entry><literal>false</literal></entry> + <entry>The content of two CDATA sections is different in + the two pieces of XML.</entry> + </row> + <row> + <entry><literal>TEXT_VALUE_ID</literal></entry> + <entry><literal>TEXT_VALUE</literal></entry> + <entry><literal>false</literal></entry> + <entry>The value of two texts is different in the two + pieces of XML.</entry> + </row> + </tbody> + </tgroup> + </table> + + <para>Note that some of the listed differences may be ignored by + the <literal>DifferenceEngine</literal> if certain configuration + options have been specified. See <xref + linkend="comparing-config"/> for details.</para> </section> - <section id="comparing-config"> - <title>Configuration Options</title> + <section id="Diff"> + <title><literal>Diff</literal> and + <literal>DetailedDiff</literal></title> + + <para><literal>Diff</literal> and + <literal>DetailedDiff</literal> provide simplified access to + <literal>DifferenceEngine</literal> by implementing the + <literal>ComparisonController</literal> and + <literal>DifferenceListener</literal> interfaces themselves. + They cover the two most common use cases for comparing two + pieces of XML: checking whether the pieces are different (this + is what <literal>Diff</literal> does) and finding all + differences between them (this is what + <literal>DetailedDiff</literal> does).</para> </section> <section id="ElementQualifier"> @@ -1015,6 +1314,15 @@ <section id="ComparisonController"> <title><literal>ComparisonController</literal></title> </section> + + <section id="comparing-junit3"> + <title>JUnit 3.x Convenience Methods</title> + </section> + + <section id="comparing-config"> + <title>Configuration Options</title> + </section> + </section> <section id="Validating"><title>Validating XML documents</title> @@ -1472,7 +1780,9 @@ <literal>XMLAssert</literal> you have several options to specify the input; XMLUnit will use the control or test parser that has been configured (see <xref linkend="JAXP"/>) to create a DOM - document from the given piece of XML in that case.</para> + document from the given piece of XML in that case - using the + configured <literal>EntityResolver</literal>(s) (see <xref + linkend="entityresolver"/>) if any.</para> <para>If JAXP 1.3 is not available, <literal>SimpleXpathEngine</literal> will use the configured @@ -1695,8 +2005,9 @@ will have been replaced by their replacement text if it is available, which means <literal>testEntityReference</literal> will not be called for them either. Instead the replacement - text will show up as (part of) a <literal>Text</literal> - node.</para> + text will show up as (part of) a <literal>Text</literal> node + or as <literal>Element</literal> node, depending on the + entity's definition.</para> </section> <section> @@ -1746,6 +2057,10 @@ <literal>NodeTest</literal> will use the "control" parser that has been configured - see <xref linkend="JAXP"/> for details.</para> + + <para>It will also use the <literal>EntityResolver</literal> + configured for the control parser if one has been set - see + <xref linkend="entityresolver"/>.</para> </section> </section> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2007-04-11 12:19:25
|
Revision: 175 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=175&view=rev Author: bodewig Date: 2007-04-11 05:19:25 -0700 (Wed, 11 Apr 2007) Log Message: ----------- Unit tests for difference in attribute sequence Modified Paths: -------------- trunk/xmlunit/src/java/org/custommonkey/xmlunit/DifferenceEngine.java trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DifferenceEngine.java Modified: trunk/xmlunit/src/java/org/custommonkey/xmlunit/DifferenceEngine.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/DifferenceEngine.java 2007-04-04 18:59:11 UTC (rev 174) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/DifferenceEngine.java 2007-04-11 12:19:25 UTC (rev 175) @@ -422,9 +422,11 @@ return new Integer(length); } - private void compareElementAttributes(Element control, Element test, - NamedNodeMap controlAttr, NamedNodeMap testAttr, - DifferenceListener listener) throws DifferenceFoundException { + void compareElementAttributes(Element control, Element test, + NamedNodeMap controlAttr, + NamedNodeMap testAttr, + DifferenceListener listener) + throws DifferenceFoundException { for (int i=0; i < controlAttr.getLength(); ++i) { Attr nextAttr = (Attr) controlAttr.item(i); if (isXMLNSAttribute(nextAttr)) { Modified: trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DifferenceEngine.java =================================================================== --- trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DifferenceEngine.java 2007-04-04 18:59:11 UTC (rev 174) +++ trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DifferenceEngine.java 2007-04-11 12:19:25 UTC (rev 175) @@ -39,6 +39,8 @@ import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; import javax.xml.parsers.DocumentBuilder; import junit.framework.TestCase; @@ -50,6 +52,7 @@ import org.w3c.dom.Document; import org.w3c.dom.DocumentType; import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.ProcessingInstruction; import org.w3c.dom.Text; @@ -660,6 +663,52 @@ .normalizeWhitespace("a\rb c\nd\te\r\n \tf")); } + public void testAttributeSequence() throws Exception { + Element control = document.createElement("foo"); + Element test = document.createElement("foo"); + OrderPreservingNamedNodeMap controlMap = + new OrderPreservingNamedNodeMap(); + OrderPreservingNamedNodeMap testMap = new OrderPreservingNamedNodeMap(); + for (int i = 0; i < 2; i++) { + int j = 1 - i; + Attr attrI = document.createAttribute("attr" + i); + attrI.setValue(String.valueOf(i)); + Attr attrJ = document.createAttribute("attr" + j); + attrJ.setValue(String.valueOf(j)); + + control.setAttributeNode(attrI); + controlMap.add(attrI); + test.setAttributeNode(attrJ); + testMap.add(attrJ); + } + engine.compareElementAttributes(control, test, controlMap, testMap, + listener); + assertEquals(ATTR_SEQUENCE_ID, listener.comparingWhat); + } + + public void testAttributeSequenceNS() throws Exception { + Element control = document.createElementNS("ns", "foo"); + Element test = document.createElementNS("ns", "foo"); + OrderPreservingNamedNodeMap controlMap = + new OrderPreservingNamedNodeMap(); + OrderPreservingNamedNodeMap testMap = new OrderPreservingNamedNodeMap(); + for (int i = 0; i < 2; i++) { + int j = 1 - i; + Attr attrI = document.createAttributeNS("ns", "attr" + i); + attrI.setValue(String.valueOf(i)); + Attr attrJ = document.createAttributeNS("ns", "attr" + j); + attrJ.setValue(String.valueOf(j)); + + control.setAttributeNode(attrI); + controlMap.add(attrI); + test.setAttributeNode(attrJ); + testMap.add(attrJ); + } + engine.compareElementAttributes(control, test, controlMap, testMap, + listener); + assertEquals(ATTR_SEQUENCE_ID, listener.comparingWhat); + } + private void listenToDifferences(String control, String test) throws SAXException, IOException { Document controlDoc = XMLUnit.buildControlDocument(control); @@ -679,14 +728,6 @@ document = documentBuilder.newDocument(); } - public test_DifferenceEngine(String name) { - super(name); - } - - public static TestSuite suite() { - return new TestSuite(test_DifferenceEngine.class); - } - private class SimpleComparisonController implements ComparisonController { public boolean haltComparison(Difference afterDifference) { return !afterDifference.isRecoverable(); @@ -734,5 +775,54 @@ tracing = active; } } + + private class OrderPreservingNamedNodeMap implements NamedNodeMap { + private ArrayList/* Attr */ nodes = new ArrayList(); + + void add(Attr attr) { + nodes.add(attr); + } + + public int getLength() { return nodes.size(); } + public Node item(int index) { return (Node) nodes.get(index); } + + public Node getNamedItem(String name) { + for (Iterator iter = nodes.iterator(); iter.hasNext(); ) { + Attr a = (Attr) iter.next(); + if (a.getName().equals(name)) { + return a; + } + } + return null; + } + + public Node getNamedItemNS(String ns, String localName) { + for (Iterator iter = nodes.iterator(); iter.hasNext(); ) { + Attr a = (Attr) iter.next(); + if (a.getLocalName().equals(localName) + && a.getNamespaceURI().equals(ns)) { + return a; + } + } + return null; + } + + // not implemented, not needed in our case + public Node removeNamedItem(String n) { + return fail(); + } + public Node removeNamedItemNS(String n1, String n2) { + return fail(); + } + public Node setNamedItem(Node n) { + return fail(); + } + public Node setNamedItemNS(Node n) { + return fail(); + } + private Node fail() { + throw new RuntimeException("not implemented"); + } + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2007-04-04 18:59:14
|
Revision: 174 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=174&view=rev Author: bodewig Date: 2007-04-04 11:59:11 -0700 (Wed, 04 Apr 2007) Log Message: ----------- Complete DOM Traversal section Modified Paths: -------------- trunk/xmlunit/src/site/XMLUnit-Java.xml Modified: trunk/xmlunit/src/site/XMLUnit-Java.xml =================================================================== --- trunk/xmlunit/src/site/XMLUnit-Java.xml 2007-04-04 18:57:10 UTC (rev 173) +++ trunk/xmlunit/src/site/XMLUnit-Java.xml 2007-04-04 18:59:11 UTC (rev 174) @@ -557,7 +557,8 @@ </section> - <section><title>Testing by Tree Walking</title> + <section id="intro-nodetest"> + <title>Testing by Tree Walking</title> <para>The DOM specification allows a <literal>Document</literal> to optionally implement the <literal>DocumentTraversal</literal> @@ -1457,9 +1458,9 @@ <literal>assertXpathNotExists</literal>.</listitem> </itemizedlist> - <para>Neither of these methods provides any control over the - message of the <literal>AssertionFailedError</literal> if the - expectation fails.</para> + <para>Neither method provides any control over the message of + the <literal>AssertionFailedError</literal> in case of a + failure.</para> </section> <section id="xpath-config"> @@ -1493,6 +1494,260 @@ <section id="NodeTest"> <title>DOM Tree Walking</title> + + <para>Sometimes it is easier to test a piece of XML's validity by + traversing the whole document node by node and test each node + individually. Maybe there is no control XML to validate against + or the expected value of an element's content has to be + calculated. There may be several reasons.</para> + + <para>XMLUnit supports this approach of testing via the + <literal>NodeTest</literal> class. In order to use it, you need a + DOM implementation that generates <literal>Document</literal> + instances that implement the optional + <literal>org.w3c.traversal.DocumentTraversal</literal> interface, + which is not part of JAXP's standardized DOM support.</para> + + <section> + <title><literal>DocumentTraversal</literal></title> + + <para>As of the release of XMLUnit 1.1 the + <literal>Document</literal> instances created by most parsers + implement <literal>DocumentTraversal</literal>, this includes + but is not limited to Apache Xerces, the parser shipping with + Sun's JDK 5 and later or GNU JAXP. One notable exception is + Apache Crimson, which also means the parser shipping with Sun's + JDK 1.4 does not support traversal; you need to specify a + different parser when using JDK 1.4 (see <xref + linkend="JAXP"/>).</para> + + <para>You can test whether your XML parser supports + <literal>DocumentTraversal</literal> by invoking + <literal>org.w3c.dom.DOMImplementation</literal>'s + <literal>hasFeature</literal> method with the feature + <literal>"Traversal"</literal>.</para> + </section> + + <section> + <title><literal>NodeTest</literal></title> + + <para>The <literal>NodeTest</literal> is instantiated with a + piece of XML to traverse. It offers two + <literal>performTest</literal> methods:</para> + + <programlisting language="Java"><![CDATA[ + /** + * Does this NodeTest pass using the specified NodeTester instance? + * @param tester + * @param singleNodeType note <code>Node.ATTRIBUTE_NODE</code> is not + * exposed by the DocumentTraversal node iterator unless the root node + * is itself an attribute - so a NodeTester that needs to test attributes + * should obtain those attributes from <code>Node.ELEMENT_NODE</code> + * nodes + * @exception NodeTestException if test fails + */ + public void performTest(NodeTester tester, short singleNodeType); + + /** + * Does this NodeTest pass using the specified NodeTester instance? + * @param tester + * @param nodeTypes note <code>Node.ATTRIBUTE_NODE</code> is not + * exposed by the DocumentTraversal node iterator unless the root node + * is itself an attribute - so a NodeTester that needs to test attributes + * should obtain those attributes from <code>Node.ELEMENT_NODE</code> + * nodes instead + * @exception NodeTestException if test fails + */ + public void performTest(NodeTester tester, short[] nodeTypes); +]]></programlisting> + + <para><literal>NodeTester</literal> is the class testing each + node and is described in the next section.</para> + + <para>The second argument limits the tests on DOM + <literal>Node</literal>s of (a) specific type(s). + <literal>Node</literal> types are specified via the + <literal>static</literal> fields of the <literal>Node</literal> + class. Any <element>Node</element> of a type not specified as + the second argument to <literal>performTest</literal> will be + ignored.</para> + + <para>Unfortunately XML attributes are not exposed as + <literal>Node</literal>s during traversal. If you need access + to attributes you must add <literal>Node.ELEMENT_NODE</literal> + to the second argument of <literal>performTest</literal> and + access the attributes from their parent + <literal>Element</literal>.</para> + + <example id="nodetest-attributes"> + <title>Accessing Attributes in a + <literal>NodeTest</literal></title> + <programlisting language="Java"><![CDATA[ + ... + NodeTest nt = new NodeTest(myXML); + NodeTester tester = new MyNodeTester(); + nt.performTest(tester, Node.ELEMENT_NODE); + ... + +class MyNodeTester implements NodeTester { + public void testNode(Node aNode, NodeTest test) { + Element anElement = (Element) aNode; + Attr attributeToTest = anElement.getAttributeNode(ATTRIBUTE_NAME); + ... + } + ... +} +]]></programlisting></example> + + <para>Any entities that appear as part of the + <literal>Document</literal> are expanded before the traversal + starts.</para> + + </section> + + <section> + <title>NodeTester</title> + + <para>Implementations of the <literal>NodeTester</literal> + interface are responsible for the actual test:</para> + + <programlisting language="Java"><![CDATA[ +public interface NodeTester { + void testNode(Node aNode, NodeTest forTest) throws NodeTestException ; + void noMoreNodes(NodeTest forTest) throws NodeTestException ; +} +]]></programlisting> + + <para><literal>NodeTest</literal> invokes + <literal>testNode</literal> for each <literal>Node</literal> as + soon as it is reached on the traversal. This means + <literal>NodeTester</literal> "sees" the + <literal>Node</literal>s in the same order they appear within + the tree.</para> + + <para><literal>noMoreNodes</literal> is invoked when the + traversal is finished. It will also be invoked if the tree didn't + contain any matched <literal>Node</literal>s at all.</para> + + <para>Implementations of <literal>NodeTester</literal> are + expected to throw a <literal>NodeTestException</literal> if the + current not doesn't match the test's expectations or more nodes + have been expected when <literal>noMoreNodes</literal> is + called.</para> + + <para>XMLUnit ships with two implementations of + <literal>NodeTest</literal> that are described in the following + to sections.</para> + + <section> + <title><literal>AbstractNodeTester</literal></title> + + <para><literal>AbstractNodeTester</literal> implements + <literal>testNode</literal> by testing the passed in + <literal>Node</literal> for its type and delegating to one of + the more specific <literal>test...</literal> Methods it adds. + By default the new <literal>test...</literal> methods all + throw a <literal>NodeTestException</literal> because of an + unexpected <literal>Node</literal>.</para> + + <para>It further implements <literal>noModeNodes</literal> + with an empty method - i.e. it does nothing.</para> + + <para>If you are only testing for specific types of + <literal>Node</literal> it may be more convenient to subclass + <literal>AbstractNodeTester</literal>. For example <xref + linkend="nodetest-attributes"/> could be re-written as:</para> + + <example> + <title>Accessing Attributes in a + <literal>NodeTest</literal> - + <literal>AbstractNodeTester</literal> version</title> + <programlisting language="Java"><![CDATA[ + ... + NodeTest nt = new NodeTest(myXML); + NodeTester tester = new AbstractNodeTester() { + public void testElement(Element element) throws NodeTestException { + Attr attributeToTest = element.getAttributeNode(ATTRIBUTE_NAME); + ... + } + }; + nt.performTest(tester, Node.ELEMENT_NODE); + ... +]]></programlisting></example> + + <para>Note that even though + <literal>AbstractNodeTester</literal> contains a + <literal>testAttribute</literal> method it will never be + called by default and you still need to access attributes via + their parent elements.</para> + + <para>Note also that the root of the test is the document's + root element, so any <literal>Node</literal>s preceeding the + document's root <literal>Element</literal> won't be visited + either. For this reason the + <literal>testDocumentType</literal>, + <literal>testEntity</literal> and + <literal>testNotation</literal> methods are probably never + called either.</para> + + <para>Finally, all entity references have been expanded before + the traversal started. <literal>EntityReference</literal>s + will have been replaced by their replacement text if it is + available, which means <literal>testEntityReference</literal> + will not be called for them either. Instead the replacement + text will show up as (part of) a <literal>Text</literal> + node.</para> + </section> + + <section> + <title><literal>CountingNodeTester</literal></title> + + <para><literal>org.custommonkey.xmlunit.examples.CountingNodeTester</literal> + is a simple example <literal>NodeTester</literal> that asserts + that a given number of <literal>Node</literal>s have been + traversed. It will throw a + <literal>NodeTestException</literal> when + <literal>noMoreNodes</literal> is called before the expected + number of <literal>Node</literal>s has been visited or the + actual number of nodes exceeded the expected count.</para> + </section> + </section> + + <section> + <title>JUnit 3.x Convenience Methods</title> + + <para><literal>XMLAssert</literal> and + <literal>XMLTestCase</literal> contain overloads of + <literal>assertNodeTestPasses</literal> methods.</para> + + <para>The most general form of it expects you to create a + <literal>NodeTest</literal> instance yourself and lets you + specify whether you expect the test to fail or to <literal>NodeTest</literal>pass.</para> + + <para>The other two overloads create a + <literal>NodeTest</literal> instance from either + <literal>String</literal> or a SAX + <literal>InputSource</literal> and are specialized for the case + where you are only interested in a single <literal>Node</literal> + type and expect the test to pass.</para> + + <para>Neither method provides any control over the message of + the <literal>AssertionFailedError</literal> in case of a + failure.</para> + </section> + + <section> + <title>Configuration Options</title> + + <para>The only configurable option for + <literal>NodeTest</literal> is the XML parser used if the piece + of XML is not specified as a <literal>Document</literal> or + <literal>DocumentTraversal</literal>. + <literal>NodeTest</literal> will use the "control" parser that + has been configured - see <xref linkend="JAXP"/> for + details.</para> + </section> + </section> <appendix id="changes"> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2007-04-04 18:57:10
|
Revision: 173 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=173&view=rev Author: bodewig Date: 2007-04-04 11:57:10 -0700 (Wed, 04 Apr 2007) Log Message: ----------- Add test for AbstractNodeTester Added Paths: ----------- trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_AbstractNodeTester.java Added: trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_AbstractNodeTester.java =================================================================== --- trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_AbstractNodeTester.java (rev 0) +++ trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_AbstractNodeTester.java 2007-04-04 18:57:10 UTC (rev 173) @@ -0,0 +1,147 @@ +/* +****************************************************************** +Copyright (c) 2007, Jeff Martin, Tim Bacon +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; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import org.w3c.dom.CDATASection; +import org.w3c.dom.Comment; +import org.w3c.dom.DocumentType; +import org.w3c.dom.Element; +import org.w3c.dom.Entity; +import org.w3c.dom.EntityReference; +import org.w3c.dom.Node; +import org.w3c.dom.Notation; +import org.w3c.dom.ProcessingInstruction; +import org.w3c.dom.Text; + +/** + * JUnit test for AbstractNodeTester + */ +public class test_AbstractNodeTester extends TestCase { + + public void testExactlyOncePerMethod() throws Exception { + String testXml = "<!DOCTYPE foo [" + + "<!ELEMENT foo (#PCDATA)>" + + "<!ATTLIST foo attr CDATA #IMPLIED>" + + "<!ENTITY my \"hello\">" + + "<!NOTATION notation PUBLIC \"pub\">" + + "]>" + + "<foo attr=\"value\">" + + "<!--comment-->" + + "<?target processing-instruction?>" + + "bar" + + "&my;" + + "<![CDATA[baz]]>" + + "</foo>"; + NodeTest nt = new NodeTest(testXml); + ExactlyOncePerMethod tester = new ExactlyOncePerMethod(); + nt.performTest(tester, new short[] { + Node.ATTRIBUTE_NODE, + Node.CDATA_SECTION_NODE, + Node.COMMENT_NODE, + Node.DOCUMENT_FRAGMENT_NODE, + Node.DOCUMENT_NODE, + Node.DOCUMENT_TYPE_NODE, + Node.ELEMENT_NODE, + Node.ENTITY_NODE, + Node.ENTITY_REFERENCE_NODE, + Node.NOTATION_NODE, + Node.PROCESSING_INSTRUCTION_NODE, + Node.TEXT_NODE, + }); + tester.verify(); + } + + private class ExactlyOncePerMethod extends AbstractNodeTester { + + private boolean cdataCalled; + private boolean commentCalled; + private boolean elementCalled; + private boolean piCalled; + private boolean textCalled; + private boolean noMoreNodesCalled; + + public void testCDATASection(CDATASection cdata) { + Assert.assertFalse("testCDATASection called", cdataCalled); + cdataCalled = true; + Assert.assertEquals("baz", cdata.getNodeValue()); + } + + public void testComment(Comment comment) { + Assert.assertFalse("testComment called", commentCalled); + commentCalled = true; + Assert.assertEquals("comment", comment.getNodeValue()); + } + + public void testElement(Element element) { + Assert.assertFalse("testElement called", elementCalled); + elementCalled = true; + Assert.assertEquals("foo", element.getNodeName()); + Assert.assertEquals("value", element.getAttribute("attr")); + } + + public void testProcessingInstruction(ProcessingInstruction instr) { + Assert.assertFalse("testProcessingInstruction called", piCalled); + piCalled = true; + Assert.assertEquals("target", instr.getTarget()); + Assert.assertEquals("processing-instruction", instr.getData()); + } + + public void testText(Text text) { + Assert.assertFalse("testText called", textCalled); + textCalled = true; + Assert.assertEquals("barhello", text.getNodeValue()); + } + + public void noMoreNodes(NodeTest t) { + Assert.assertFalse("noMoreNodes called", noMoreNodesCalled); + noMoreNodesCalled = true; + } + + void verify() { + Assert.assertTrue("testCDATASection not called", cdataCalled); + Assert.assertTrue("testComment not called", commentCalled); + Assert.assertTrue("testElement not called", elementCalled); + Assert.assertTrue("testProcessingInstruction not called", + piCalled); + Assert.assertTrue("testText not called", textCalled); + Assert.assertTrue("noMoreNodes not called", noMoreNodesCalled); + } + } +} \ No newline at end of file Property changes on: trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_AbstractNodeTester.java ___________________________________________________________________ Name: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2007-04-04 12:01:52
|
Revision: 172 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=172&view=rev Author: bodewig Date: 2007-04-04 05:01:51 -0700 (Wed, 04 Apr 2007) Log Message: ----------- Move CountingNodeTester to examples Modified Paths: -------------- trunk/xmlunit/src/java/org/custommonkey/xmlunit/CountingNodeTester.java Added Paths: ----------- trunk/xmlunit/src/java/org/custommonkey/xmlunit/examples/CountingNodeTester.java trunk/xmlunit/tests/java/org/custommonkey/xmlunit/examples/test_CountingNodeTester.java Removed Paths: ------------- trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_CountingNodeTester.java Modified: trunk/xmlunit/src/java/org/custommonkey/xmlunit/CountingNodeTester.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/CountingNodeTester.java 2007-04-03 04:44:20 UTC (rev 171) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/CountingNodeTester.java 2007-04-04 12:01:51 UTC (rev 172) @@ -1,6 +1,6 @@ /* ****************************************************************** -Copyright (c) 2001, Jeff Martin, Tim Bacon +Copyright (c) 2001-2007, Jeff Martin, Tim Bacon All rights reserved. Redistribution and use in source and binary forms, with or without @@ -36,53 +36,19 @@ package org.custommonkey.xmlunit; -import org.w3c.dom.Node; - /** * Counts the number of nodes in a document to allow assertions to be made * using a NodeTest. * <br />Examples and more at <a href="http://xmlunit.sourceforge.net"/>xmlunit.sourceforge.net</a> * @see NodeTest + * @deprecated Use {@link + * org.custommonkey.xmlunit.examples.CountingNodeTester + * CountingNodeTester} instead. */ -public class CountingNodeTester implements NodeTester { - private final int expectedNumNodes; - private int actualNumNodes; +public class CountingNodeTester + extends org.custommonkey.xmlunit.examples.CountingNodeTester { public CountingNodeTester(int expectedNumNodes) { - this.expectedNumNodes = expectedNumNodes; + super(expectedNumNodes); } - - /** - * A single Node is always valid - * @param aNode - * @param forTest - */ - public void testNode(Node aNode, NodeTest forTest) { - actualNumNodes++; - } - - /** - * Called by NodeTest when all nodes have been iterated over: time to see - * if all the nodes that were expected were found. - * Note that this method also invokes {@link #resetCounter resetCounter} - * so that the instance can be reused. - * @exception true if expected num nodes == actual num nodes, - * false otherwise - */ - public void noMoreNodes(NodeTest forTest) throws NodeTestException { - int testedNodes = actualNumNodes; - resetCounter(); - if (testedNodes != expectedNumNodes) { - throw new NodeTestException("Counted " + testedNodes - + " node(s) but expected " + expectedNumNodes); - } - } - - /** - * Reset the counter so that an instance can be reused for another - * <code>NodeTest</code> - */ - public void resetCounter() { - actualNumNodes = 0; - } } \ No newline at end of file Copied: trunk/xmlunit/src/java/org/custommonkey/xmlunit/examples/CountingNodeTester.java (from rev 171, trunk/xmlunit/src/java/org/custommonkey/xmlunit/CountingNodeTester.java) =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/examples/CountingNodeTester.java (rev 0) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/examples/CountingNodeTester.java 2007-04-04 12:01:51 UTC (rev 172) @@ -0,0 +1,91 @@ +/* +****************************************************************** +Copyright (c) 2001-2007, Jeff Martin, Tim Bacon +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.examples; + +import org.custommonkey.xmlunit.NodeTest; +import org.custommonkey.xmlunit.NodeTestException; +import org.custommonkey.xmlunit.NodeTester; +import org.w3c.dom.Node; + +/** + * Counts the number of nodes in a document to allow assertions to be made + * using a NodeTest. + * <br />Examples and more at <a href="http://xmlunit.sourceforge.net"/>xmlunit.sourceforge.net</a> + * @see NodeTest + */ +public class CountingNodeTester implements NodeTester { + private final int expectedNumNodes; + private int actualNumNodes; + + public CountingNodeTester(int expectedNumNodes) { + this.expectedNumNodes = expectedNumNodes; + } + + /** + * A single Node is always valid + * @param aNode + * @param forTest + */ + public void testNode(Node aNode, NodeTest forTest) { + actualNumNodes++; + } + + /** + * Called by NodeTest when all nodes have been iterated over: time to see + * if all the nodes that were expected were found. + * Note that this method also invokes {@link #resetCounter resetCounter} + * so that the instance can be reused. + * @exception true if expected num nodes == actual num nodes, + * false otherwise + */ + public void noMoreNodes(NodeTest forTest) throws NodeTestException { + int testedNodes = actualNumNodes; + resetCounter(); + if (testedNodes != expectedNumNodes) { + throw new NodeTestException("Counted " + testedNodes + + " node(s) but expected " + expectedNumNodes); + } + } + + /** + * Reset the counter so that an instance can be reused for another + * <code>NodeTest</code> + */ + public void resetCounter() { + actualNumNodes = 0; + } +} \ No newline at end of file Copied: trunk/xmlunit/tests/java/org/custommonkey/xmlunit/examples/test_CountingNodeTester.java (from rev 171, trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_CountingNodeTester.java) =================================================================== --- trunk/xmlunit/tests/java/org/custommonkey/xmlunit/examples/test_CountingNodeTester.java (rev 0) +++ trunk/xmlunit/tests/java/org/custommonkey/xmlunit/examples/test_CountingNodeTester.java 2007-04-04 12:01:51 UTC (rev 172) @@ -0,0 +1,119 @@ +/* +****************************************************************** +Copyright (c) 2001-2007, Jeff Martin, Tim Bacon +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.examples; + +import java.io.StringReader; + +import junit.framework.TestCase; + +import org.custommonkey.xmlunit.NodeTest; +import org.custommonkey.xmlunit.NodeTestException; +import org.w3c.dom.Node; + +/** + * JUnit test for CountingNodeTester + */ +public class test_CountingNodeTester extends TestCase { + private NodeTest test; + private CountingNodeTester tester; + + public void testPositivePath() throws Exception { + test = new NodeTest(new StringReader("<a><b>c</b></a>")); + tester = new CountingNodeTester(2); + test.performTest(tester, Node.ELEMENT_NODE); + + tester = new CountingNodeTester(1); + test.performTest(tester, Node.TEXT_NODE); + + tester = new CountingNodeTester(3); + test.performTest(tester, + new short[] {Node.TEXT_NODE, Node.ELEMENT_NODE}); + + tester = new CountingNodeTester(0); + test.performTest(tester, Node.COMMENT_NODE); + } + + public void testNegativePath() throws Exception { + test = new NodeTest(new StringReader("<a><b>c</b></a>")); + try { + tester = new CountingNodeTester(2); + test.performTest(tester, Node.TEXT_NODE); + fail("Expected NodeTestException"); + } catch (NodeTestException e) { + // failure, as expected + } + + try { + tester = new CountingNodeTester(1); + test.performTest(tester, Node.ELEMENT_NODE); + fail("Expected NodeTestException"); + } catch (NodeTestException e) { + // failure, as expected + } + + try { + tester = new CountingNodeTester(2); + test.performTest(tester, + new short[] {Node.TEXT_NODE, Node.ELEMENT_NODE}); + fail("Expected NodeTestException"); + } catch (NodeTestException e) { + // failure, as expected + } + + try { + tester = new CountingNodeTester(1); + test.performTest(tester, Node.COMMENT_NODE); + fail("Expected NodeTestException"); + } catch (NodeTestException e) { + // failure, as expected + } + + try { + tester = new CountingNodeTester(0); + test.performTest(tester, Node.TEXT_NODE); + fail("Expected NodeTestException"); + } catch (NodeTestException e) { + // failure, as expected + } + } + + public test_CountingNodeTester(String name) { + super(name); + } + +} + Deleted: trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_CountingNodeTester.java =================================================================== --- trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_CountingNodeTester.java 2007-04-03 04:44:20 UTC (rev 171) +++ trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_CountingNodeTester.java 2007-04-04 12:01:51 UTC (rev 172) @@ -1,117 +0,0 @@ -/* -****************************************************************** -Copyright (c) 200, Jeff Martin, Tim Bacon -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; - -import java.io.StringReader; - -import junit.framework.TestCase; - -import org.w3c.dom.Node; - -/** - * JUnit test for CountingNodeTester - */ -public class test_CountingNodeTester extends TestCase { - private NodeTest test; - private CountingNodeTester tester; - - public void testPositivePath() throws Exception { - test = new NodeTest(new StringReader("<a><b>c</b></a>")); - tester = new CountingNodeTester(2); - test.performTest(tester, Node.ELEMENT_NODE); - - tester = new CountingNodeTester(1); - test.performTest(tester, Node.TEXT_NODE); - - tester = new CountingNodeTester(3); - test.performTest(tester, - new short[] {Node.TEXT_NODE, Node.ELEMENT_NODE}); - - tester = new CountingNodeTester(0); - test.performTest(tester, Node.COMMENT_NODE); - } - - public void testNegativePath() throws Exception { - test = new NodeTest(new StringReader("<a><b>c</b></a>")); - try { - tester = new CountingNodeTester(2); - test.performTest(tester, Node.TEXT_NODE); - fail("Expected NodeTestException"); - } catch (NodeTestException e) { - // failure, as expected - } - - try { - tester = new CountingNodeTester(1); - test.performTest(tester, Node.ELEMENT_NODE); - fail("Expected NodeTestException"); - } catch (NodeTestException e) { - // failure, as expected - } - - try { - tester = new CountingNodeTester(2); - test.performTest(tester, - new short[] {Node.TEXT_NODE, Node.ELEMENT_NODE}); - fail("Expected NodeTestException"); - } catch (NodeTestException e) { - // failure, as expected - } - - try { - tester = new CountingNodeTester(1); - test.performTest(tester, Node.COMMENT_NODE); - fail("Expected NodeTestException"); - } catch (NodeTestException e) { - // failure, as expected - } - - try { - tester = new CountingNodeTester(0); - test.performTest(tester, Node.TEXT_NODE); - fail("Expected NodeTestException"); - } catch (NodeTestException e) { - // failure, as expected - } - } - - public test_CountingNodeTester(String name) { - super(name); - } - -} - This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: SourceForge.net <no...@so...> - 2007-04-03 06:58:33
|
Feature Requests item #953441, was opened at 2004-05-13 18:52 Message generated for change (Comment added) made by bodewig You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=377771&aid=953441&group_id=23187 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None >Status: Closed >Resolution: Fixed Priority: 1 Private: No Submitted By: Matthew L Daniel (mdaniel) Assigned to: Nobody/Anonymous (nobody) Summary: Adds support for building using Maven Initial Comment: Maven adds a great deal of value to Java projects, in my opinion, and the reporting is 2nd to none. The attached patch enables xmlunit to be built using maven (tested on my machine using 1.1-SNAPSHOT, from CVS). This patch was created against xmlunit-1.0. ---------------------------------------------------------------------- >Comment By: Stefan Bodewig (bodewig) Date: 2007-04-03 08:58 Message: Logged In: YES user_id=113148 Originator: NO XMLUnit 1.1 will ship with a Maven2 POM as well as an ivy.xml for those using either to for dependency resolution. XMLUnit itself won't use these files itself, though. ---------------------------------------------------------------------- Comment By: Stefan Bodewig (bodewig) Date: 2006-12-22 06:11 Message: Logged In: YES user_id=113148 Originator: NO While dealing with the issues here, I always feel a little strange when answering reports that are more than two years old, sorry. Currently I don't see any major issues with the Ant build so I see very little reason to switch. I'll probably add a POM so we can have it alongside the jar inside of the Maven repo and might accept changes to the POM that would allow anybody to use Maven2 to build - just don't tell me I'd have to move files around. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=377771&aid=953441&group_id=23187 |
From: <bo...@us...> - 2007-04-03 04:44:19
|
Revision: 171 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=171&view=rev Author: bodewig Date: 2007-04-02 21:44:20 -0700 (Mon, 02 Apr 2007) Log Message: ----------- Ensure native lineends Property Changed: ---------------- trunk/xmlunit/src/etc/xmlunit.pom Property changes on: trunk/xmlunit/src/etc/xmlunit.pom ___________________________________________________________________ Name: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2007-04-03 04:28:28
|
Revision: 170 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=170&view=rev Author: bodewig Date: 2007-04-02 21:28:28 -0700 (Mon, 02 Apr 2007) Log Message: ----------- Refactor XPath tests a little Modified Paths: -------------- trunk/xmlunit/src/java/org/custommonkey/xmlunit/XpathEngine.java trunk/xmlunit/tests/java/org/custommonkey/xmlunit/jaxp13/test_Jaxp13XpathEngine.java trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_SimpleXpathEngine.java Added Paths: ----------- trunk/xmlunit/tests/java/org/custommonkey/xmlunit/AbstractXpathEngineTests.java Modified: trunk/xmlunit/src/java/org/custommonkey/xmlunit/XpathEngine.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/XpathEngine.java 2007-04-03 04:12:54 UTC (rev 169) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/XpathEngine.java 2007-04-03 04:28:28 UTC (rev 170) @@ -55,10 +55,9 @@ * @param select * @param document * @return list of matching nodes - * @throws TransformerException */ NodeList getMatchingNodes(String select, Document document) - throws ConfigurationException, XpathException; + throws XpathException; /** * Evaluate the result of executing the specified xpath syntax @@ -66,10 +65,9 @@ * @param select * @param document * @return evaluated result - * @throws TransformerException */ String evaluate(String select, Document document) - throws ConfigurationException, XpathException; + throws XpathException; /** * Establish a namespace context. Added: trunk/xmlunit/tests/java/org/custommonkey/xmlunit/AbstractXpathEngineTests.java =================================================================== --- trunk/xmlunit/tests/java/org/custommonkey/xmlunit/AbstractXpathEngineTests.java (rev 0) +++ trunk/xmlunit/tests/java/org/custommonkey/xmlunit/AbstractXpathEngineTests.java 2007-04-03 04:28:28 UTC (rev 170) @@ -0,0 +1,149 @@ +/* +****************************************************************** +Copyright (c) 2007, Jeff Martin, Tim Bacon +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; + +import java.util.HashMap; +import junit.framework.TestCase; +import org.w3c.dom.Document; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +public abstract class AbstractXpathEngineTests extends TestCase { + + protected static final String[] testAttrNames = {"attrOne", "attrTwo"}; + + protected static final String testString = + "<test><nodeWithoutAttributes>intellectual property rights" + + " </nodeWithoutAttributes>" + + "<nodeWithoutAttributes>make us all poorer </nodeWithoutAttributes>" + + "<nodeWithAttributes " + testAttrNames[0] + "=\"open source \" " + + testAttrNames[1] + + "=\"is the answer \">free your code from its chains" + + "</nodeWithAttributes></test>"; + protected Document testDocument; + + protected abstract XpathEngine newXpathEngine(); + + public void testGetMatchingNodesNoMatches() throws Exception { + NodeList nodeList = newXpathEngine().getMatchingNodes("toast", + testDocument); + assertEquals(0, nodeList.getLength()); + } + + public void testGetMatchingNodesMatchRootElement() throws Exception { + NodeList nodeList = newXpathEngine().getMatchingNodes("test", + testDocument); + assertEquals(1, nodeList.getLength()); + assertEquals(Node.ELEMENT_NODE, nodeList.item(0).getNodeType()); + } + + public void testGetMatchingNodesMatchElement() throws Exception { + NodeList nodeList = newXpathEngine() + .getMatchingNodes("test/nodeWithoutAttributes", testDocument); + assertEquals(2, nodeList.getLength()); + assertEquals(Node.ELEMENT_NODE, nodeList.item(0).getNodeType()); + } + + public void testGetMatchingNodesMatchText() throws Exception { + NodeList nodeList = newXpathEngine().getMatchingNodes("test//text()", + testDocument); + assertEquals(3, nodeList.getLength()); + assertEquals(Node.TEXT_NODE, nodeList.item(0).getNodeType()); + } + + public void testGetMatchingNodesCheckSubNodes() throws Exception { + NodeList nodeList = newXpathEngine() + .getMatchingNodes("test/nodeWithAttributes", testDocument); + assertEquals(1, nodeList.getLength()); + Node aNode; + + aNode = nodeList.item(0); + assertEquals(Node.ELEMENT_NODE, aNode.getNodeType()); + assertEquals(true, aNode.hasAttributes()); + assertEquals(true, aNode.hasChildNodes()); + + NodeList children = aNode.getChildNodes(); + int length = children.getLength(); + assertEquals(1, length); + for (int i=0; i < length; ++i) { + assertEquals(Node.TEXT_NODE, children.item(i).getNodeType()); + } + + NamedNodeMap attributes = aNode.getAttributes(); + int numAttrs = attributes.getLength(); + assertEquals(testAttrNames.length, numAttrs); + for (int i=0; i < testAttrNames.length; ++i) { + Node attrNode = attributes.getNamedItem(testAttrNames[i]); + assertNotNull(attrNode); + assertEquals(Node.ATTRIBUTE_NODE, attrNode.getNodeType()); + } + } + + public void testEvaluate() throws Exception { + String result = newXpathEngine().evaluate("count(test//node())", + testDocument); + assertEquals("3 elements and 3 text nodes", "6", result); + } + + public void testXpathPrefixChange() throws Exception { + String testDoc = "<t:test xmlns:t=\"urn:foo\"><t:bar/></t:test>"; + Document d = XMLUnit.buildControlDocument(testDoc); + HashMap m = new HashMap(); + m.put("foo", "urn:foo"); + NamespaceContext ctx = new SimpleNamespaceContext(m); + XpathEngine engine = newXpathEngine(); + engine.setNamespaceContext(ctx); + + NodeList l = engine.getMatchingNodes("//foo:bar", d); + assertEquals(1, l.getLength()); + assertEquals(Node.ELEMENT_NODE, l.item(0).getNodeType()); + + String s = engine.evaluate("count(foo:test//node())", d); + assertEquals("1", s); + } + + public void setUp() throws Exception { + testDocument = XMLUnit.buildControlDocument(testString); + } + + public AbstractXpathEngineTests(String name) { + super(name); + } + + +} \ No newline at end of file Property changes on: trunk/xmlunit/tests/java/org/custommonkey/xmlunit/AbstractXpathEngineTests.java ___________________________________________________________________ Name: svn:eol-style + native Modified: trunk/xmlunit/tests/java/org/custommonkey/xmlunit/jaxp13/test_Jaxp13XpathEngine.java =================================================================== --- trunk/xmlunit/tests/java/org/custommonkey/xmlunit/jaxp13/test_Jaxp13XpathEngine.java 2007-04-03 04:12:54 UTC (rev 169) +++ trunk/xmlunit/tests/java/org/custommonkey/xmlunit/jaxp13/test_Jaxp13XpathEngine.java 2007-04-03 04:28:28 UTC (rev 170) @@ -1,6 +1,6 @@ /* ****************************************************************** -Copyright (c) 200, Jeff Martin, Tim Bacon +Copyright (c) 2006-2007, Jeff Martin, Tim Bacon All rights reserved. Redistribution and use in source and binary forms, with or without @@ -36,94 +36,18 @@ package org.custommonkey.xmlunit.jaxp13; -import javax.xml.transform.OutputKeys; -import junit.framework.TestCase; -import junit.framework.TestSuite; +import org.custommonkey.xmlunit.AbstractXpathEngineTests; +import org.custommonkey.xmlunit.XpathEngine; -import org.custommonkey.xmlunit.XMLUnit; - -import org.w3c.dom.Document; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - /** * JUnit test for Jaxp13XpathEngine */ -public class test_Jaxp13XpathEngine extends TestCase { - private String[] testAttrNames = {"attrOne", "attrTwo"}; - private String testString = - "<test><nodeWithoutAttributes>intellectual property rights </nodeWithoutAttributes>" - + "<nodeWithoutAttributes>make us all poorer </nodeWithoutAttributes>" - + "<nodeWithAttributes " + testAttrNames[0] + "=\"open source \" " - + testAttrNames[1] + "=\"is the answer \">free your code from its chains" - + "</nodeWithAttributes></test>"; - private Document testDocument; - private Jaxp13XpathEngine simpleXpathEngine = new Jaxp13XpathEngine(); +public class test_Jaxp13XpathEngine extends AbstractXpathEngineTests { - public void testGetMatchingNodesNoMatches() throws Exception { - NodeList nodeList = simpleXpathEngine.getMatchingNodes("toast", testDocument); - assertEquals(0, nodeList.getLength()); + protected XpathEngine newXpathEngine() { + return new Jaxp13XpathEngine(); } - public void testGetMatchingNodesMatchRootElement() throws Exception { - NodeList nodeList = simpleXpathEngine.getMatchingNodes("test", testDocument); - assertEquals(1, nodeList.getLength()); - assertEquals(Node.ELEMENT_NODE, nodeList.item(0).getNodeType()); - } - - public void testGetMatchingNodesMatchElement() throws Exception { - NodeList nodeList = simpleXpathEngine.getMatchingNodes( - "test/nodeWithoutAttributes", testDocument); - assertEquals(2, nodeList.getLength()); - assertEquals(Node.ELEMENT_NODE, nodeList.item(0).getNodeType()); - } - - public void testGetMatchingNodesMatchText() throws Exception { - NodeList nodeList = simpleXpathEngine.getMatchingNodes( - "test//text()", testDocument); - assertEquals(3, nodeList.getLength()); - assertEquals(Node.TEXT_NODE, nodeList.item(0).getNodeType()); - } - - public void testGetMatchingNodesCheckSubNodes() throws Exception { - NodeList nodeList = simpleXpathEngine.getMatchingNodes( - "test/nodeWithAttributes", testDocument); - assertEquals(1, nodeList.getLength()); - Node aNode; - - aNode = nodeList.item(0); - assertEquals(Node.ELEMENT_NODE, aNode.getNodeType()); - assertEquals(true, aNode.hasAttributes()); - assertEquals(true, aNode.hasChildNodes()); - - NodeList children = aNode.getChildNodes(); - int length = children.getLength(); - assertEquals(1, length); - for (int i=0; i < length; ++i) { - assertEquals(Node.TEXT_NODE, children.item(i).getNodeType()); - } - - NamedNodeMap attributes = aNode.getAttributes(); - int numAttrs = attributes.getLength(); - assertEquals(testAttrNames.length, numAttrs); - for (int i=0; i < testAttrNames.length; ++i) { - Node attrNode = attributes.getNamedItem(testAttrNames[i]); - assertNotNull(attrNode); - assertEquals(Node.ATTRIBUTE_NODE, attrNode.getNodeType()); - } - } - - public void testEvaluate() throws Exception { - String result = simpleXpathEngine.evaluate( - "count(test//node())", testDocument); - assertEquals("3 elements and 3 text nodes", "6", result); - } - - public void setUp() throws Exception { - testDocument = XMLUnit.buildControlDocument(testString); - } - public test_Jaxp13XpathEngine(String name) { super(name); } Modified: trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_SimpleXpathEngine.java =================================================================== --- trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_SimpleXpathEngine.java 2007-04-03 04:12:54 UTC (rev 169) +++ trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_SimpleXpathEngine.java 2007-04-03 04:28:28 UTC (rev 170) @@ -37,114 +37,47 @@ package org.custommonkey.xmlunit; import javax.xml.transform.OutputKeys; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import org.w3c.dom.Document; -import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; -import org.w3c.dom.NodeList; /** * JUnit test for SimpleXpathEngine */ -public class test_SimpleXpathEngine extends TestCase { - private String[] testAttrNames = {"attrOne", "attrTwo"}; - private String testString = - "<test><nodeWithoutAttributes>intellectual property rights </nodeWithoutAttributes>" - + "<nodeWithoutAttributes>make us all poorer </nodeWithoutAttributes>" - + "<nodeWithAttributes " + testAttrNames[0] + "=\"open source \" " - + testAttrNames[1] + "=\"is the answer \">free your code from its chains" - + "</nodeWithAttributes></test>"; - private Document testDocument; +public class test_SimpleXpathEngine extends AbstractXpathEngineTests { + private SimpleXpathEngine simpleXpathEngine = new SimpleXpathEngine(); + protected XpathEngine newXpathEngine() { + return simpleXpathEngine; + } + public void testGetXPathResultNode() throws Exception { - Node result = simpleXpathEngine.getXPathResultNode("test", testDocument); + Node result = simpleXpathEngine.getXPathResultNode("test", + testDocument); SimpleSerializer serializer = new SimpleSerializer(); serializer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); assertEquals(testString, serializer.serialize(result.getFirstChild())); } - public void testGetMatchingNodesNoMatches() throws Exception { - NodeList nodeList = simpleXpathEngine.getMatchingNodes("toast", testDocument); - assertEquals(0, nodeList.getLength()); - } - - public void testGetMatchingNodesMatchRootElement() throws Exception { - NodeList nodeList = simpleXpathEngine.getMatchingNodes("test", testDocument); - assertEquals(1, nodeList.getLength()); - assertEquals(Node.ELEMENT_NODE, nodeList.item(0).getNodeType()); - } - - public void testGetMatchingNodesMatchElement() throws Exception { - NodeList nodeList = simpleXpathEngine.getMatchingNodes( - "test/nodeWithoutAttributes", testDocument); - assertEquals(2, nodeList.getLength()); - assertEquals(Node.ELEMENT_NODE, nodeList.item(0).getNodeType()); - } - public void testGetMatchingNodesMatchText() throws Exception { if (isJava5OrNewer()) { // fails with "more recent" version of Xalan shipping with Java5 return; } - NodeList nodeList = simpleXpathEngine.getMatchingNodes( - "test//text()", testDocument); - assertEquals(3, nodeList.getLength()); - assertEquals(Node.TEXT_NODE, nodeList.item(0).getNodeType()); + super.testGetMatchingNodesMatchText(); } - public void testGetMatchingNodesCheckSubNodes() throws Exception { - NodeList nodeList = simpleXpathEngine.getMatchingNodes( - "test/nodeWithAttributes", testDocument); - assertEquals(1, nodeList.getLength()); - Node aNode; - - aNode = nodeList.item(0); - assertEquals(Node.ELEMENT_NODE, aNode.getNodeType()); - assertEquals(true, aNode.hasAttributes()); - assertEquals(true, aNode.hasChildNodes()); - - NodeList children = aNode.getChildNodes(); - int length = children.getLength(); - assertEquals(1, length); - for (int i=0; i < length; ++i) { - assertEquals(Node.TEXT_NODE, children.item(i).getNodeType()); - } - - NamedNodeMap attributes = aNode.getAttributes(); - int numAttrs = attributes.getLength(); - assertEquals(testAttrNames.length, numAttrs); - for (int i=0; i < testAttrNames.length; ++i) { - Node attrNode = attributes.getNamedItem(testAttrNames[i]); - assertNotNull(attrNode); - assertEquals(Node.ATTRIBUTE_NODE, attrNode.getNodeType()); - } - } - public void testEvaluate() throws Exception { if (isJava5OrNewer()) { // fails with "more recent" version of Xalan shipping with Java5 return; } - String result = simpleXpathEngine.evaluate( - "count(test//node())", testDocument); - assertEquals("3 elements and 3 text nodes", "6", result); + super.testEvaluate(); } - public void setUp() throws Exception { - testDocument = XMLUnit.buildControlDocument(testString); - } - public test_SimpleXpathEngine(String name) { super(name); } - public static TestSuite suite() { - return new TestSuite(test_SimpleXpathEngine.class); - } - private static boolean isJava5OrNewer() { try { Class.forName("java.net.Proxy"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2007-04-03 04:12:53
|
Revision: 169 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=169&view=rev Author: bodewig Date: 2007-04-02 21:12:54 -0700 (Mon, 02 Apr 2007) Log Message: ----------- complete XPath section Modified Paths: -------------- trunk/xmlunit/src/site/XMLUnit-Java.xml Modified: trunk/xmlunit/src/site/XMLUnit-Java.xml =================================================================== --- trunk/xmlunit/src/site/XMLUnit-Java.xml 2007-04-03 03:48:34 UTC (rev 168) +++ trunk/xmlunit/src/site/XMLUnit-Java.xml 2007-04-03 04:12:54 UTC (rev 169) @@ -1267,14 +1267,227 @@ <section id="xpath-engines"> <title>XPath Engines</title> + + <para>Central to XMLUnit's XPath support is the + <literal>XpathEngine</literal> interface which consists of only + three methods:</para> + + <programlisting language="Java"><![CDATA[ + /** + * Execute the specified xpath syntax <code>select</code> expression + * on the specified document and return the list of nodes (could have + * length zero) that match + * @param select + * @param document + * @return list of matching nodes + */ + NodeList getMatchingNodes(String select, Document document) + throws XpathException; + + /** + * Evaluate the result of executing the specified xpath syntax + * <code>select</code> expression on the specified document + * @param select + * @param document + * @return evaluated result + */ + String evaluate(String select, Document document) + throws XpathException; + + /** + * Establish a namespace context. + */ + void setNamespaceContext(NamespaceContext ctx); +]]></programlisting> + + + <para>The first two methods expect an XPath expression that + selects content from the DOM document that is the second + argument. The result of the selection can be either a DOM + <literal>NodeList</literal> or a <literal>String</literal>. The + later form tries to flatten the result, the value is said to be + "String-ified".</para> + + <para>The third method is part of XMLUnit's support for XML + Namespaces in XPath expressions. See <xref linkend="xpath-ns"/> + for more details.</para> + + <para>There are two implementations of the interface, + <literal>org.custommonkey.xmlunit.SimpleXpathEngine</literal> + and + <literal>org.custommonkey.xmlunit.jaxp13.Jaxp13XpathEngine</literal>. + The first implementation is the only one available in XMLUnit + 1.0 and uses the <link linked="JAXP">configured</link> JAXP XSLT + transformer. The second is new to XMLUnit 1.1 and only + available if JAXP 1.3 or later is supported, which should be the + case for Java 5 and later.</para> + + <para><literal>XpathException</literal> is an + <literal>Exception</literal> that will be thrown for invalid + XPath expressions or other problems with the underlying XPath + engine. It will typically wrap a + <literal>javax.xml.xpath.XPathExpressionException</literal> in + the <literal>Jaxp13XpathEngine</literal> case or a + <literal>javax.xml.transform.TransformerException</literal> when + <literal>SimpleXpathEngine</literal> is used.</para> + + <para>The <literal>XMLUnit.newXpathEngine</literal> method will + first try to create an instance of + <literal>Jaxp13XpathEngine</literal> and fall back to + <literal>SimpleXpathEngine</literal> if JAXP 1.3 is not + supported.</para> + + <para>One example of using the XPath support is included inside + it <literal>org.custommonkey.xmlunit.examples</literal> package. + It asserts that the stringified form of an XPath selection + matches a regular expression. The code needed for this + is:</para> + + <example> + <title>Matching an XPath Selection Against a Regular + Expression</title> + <programlisting language="Java"><![CDATA[ + XpathEngine engine = XMLUnit.newXpathEngine(); + String value = engine.evaluate(xpath, doc); + Assert.assertTrue(message, value.matches(regex)); +]]></programlisting></example> + </section> + <section id="xpath-ns"> + <title>Using XML Namespaces in XPath Selectors</title> + + <para>Starting with XMLUnit 1.1 XML Namespaces are supported for + XPath queries.</para> + + <para>The <literal>NamespaceContext</literal> interface provides + a mapping from prefix to namespace URI and is used by the XPath + engine. XPath selections then use the mapping's prefixex where + needed. Note that a prefix used in the document under test and + a prefix given as part of the + <literal>NamespaceContext</literal> are not related at all; the + context only applies to the XPath expression, the prefix used in + the document is ignored completely.</para> + + <para>Right now XMLUnit provides only a single implementation of + the <literal>NamespaceContext</literal> interface: + <literal>SimpleNamespaceContext</literal>. This implementation + expects a <literal>java.util.Map</literal> as its constructor + argument. The <literal>Map</literal> must contain + (<literal>String</literal>) prefixes as keys and + (<literal>String</literal>) namespace URIs as values.</para> + + <para>The empty string is used as prefix for the default + namespace of a document.</para> + + <para>The following example is taken from XMLUnit's own tests. + It demonstrates that the namespace prefix of the document under + test is irrelevant and shows how to set up the namespace + context.</para> + + <example> + <title>Using Namespaces in XPath Tests</title> + <programlisting language="Java"><![CDATA[ + String testDoc = "<t:test xmlns:t=\"urn:foo\"><t:bar/></t:test>"; + Document d = XMLUnit.buildControlDocument(testDoc); + HashMap m = new HashMap(); + m.put("foo", "urn:foo"); + + NamespaceContext ctx = new SimpleNamespaceContext(m); + XpathEngine engine = newXpathEngine(); + engine.setNamespaceContext(ctx); + + NodeList l = engine.getMatchingNodes("//foo:bar", d); + assertEquals(1, l.getLength()); + assertEquals(Node.ELEMENT_NODE, l.item(0).getNodeType()); +]]></programlisting></example> + + <para>It is possible to set a global + <literal>NamespaceContext</literal>, see <xref + linkend="xpath-config"/> for details.</para> + </section> + <section id="xpath-junit3"> <title>JUnit 3.x Convenience Methods</title> + + <para><literal>XMLTestCase</literal> and + <literal>XMLAssert</literal> provide several overloads for the + following common types of assertions:</para> + + <itemizedlist> + + <listitem>Two XPath expression should return the same DOM + <literal>NodeList</literal> as result: + <literal>assertXpathsEqual</literal>. There are methods that + use two different expressions on the same document and others + that compare expressions selecting from two different + documents. + + <para>The <literal>NodeList</literal>s are wrapped into a + surrogate root XML element and the resulting DOM + <literal>Document</literal>s are compared using + <literal>Diff.similar()</literal>.</para> + </listitem> + + <listitem>The opposite of the above, the expressions should + yield different results: + <literal>assertXpathsNotEqual</literal>.</listitem> + + <listitem>Two XPath expression should return the same + "String-ified" result: + <literal>assertXpathValuesEqual</literal>. There are methods + that use two different expressions on the same document and + others that compare expressions selecting from two different + documents.</listitem> + + <listitem>The opposite of the above, the expressions should + yield different results: + <literal>assertXpathValuesNotEqual</literal>.</listitem> + + <listitem>The XPath expression should return an expected value + when "String-ified": + <literal>assertXpathEvaluatesTo</literal>.</listitem> + + <listitem>The <literal>NodeList</literal> selected by an XPath + expression is not empty: + <literal>assertXpathExists</literal>.</listitem> + + <listitem>The <literal>NodeList</literal> selected by an XPath + expression is empty: + <literal>assertXpathNotExists</literal>.</listitem> + </itemizedlist> + + <para>Neither of these methods provides any control over the + message of the <literal>AssertionFailedError</literal> if the + expectation fails.</para> </section> <section id="xpath-config"> <title>Configuration Options</title> + + <para>When using <literal>XpathEngine</literal> directly you are + responsible for creating the DOM document yourself. If you use + the convenience methods of <literal>XMLTestCase</literal> or + <literal>XMLAssert</literal> you have several options to specify + the input; XMLUnit will use the control or test parser that has + been configured (see <xref linkend="JAXP"/>) to create a DOM + document from the given piece of XML in that case.</para> + + <para>If JAXP 1.3 is not available, + <literal>SimpleXpathEngine</literal> will use the configured + JAXP XSLT transformer (see <xref linkend="JAXP"/>) under the + covers.</para> + + <para>It is possible to establish a global + <literal>NamespaceContext</literal> with the help of the + <literal>XMLUnit.setXpathNamespaceContext</literal> method. Any + <literal>XpathEngine</literal> created by + <literal>XMLUnit.newXpathEngine</literal> will automatically use + the given context. Note that the JUnit 3 convenience methods + use <literal>XMLUnit.newXpathEngine</literal> implicitly and + will thus use the configured + <literal>NamespaceContext</literal>.</para> + </section> </section> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2007-04-03 03:48:40
|
Revision: 168 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=168&view=rev Author: bodewig Date: 2007-04-02 20:48:34 -0700 (Mon, 02 Apr 2007) Log Message: ----------- Provide a Maven 2 POM and an Ivy File Modified Paths: -------------- trunk/xmlunit/LICENSE.txt trunk/xmlunit/build.xml Added Paths: ----------- trunk/xmlunit/src/etc/xmlunit-ivy.xml trunk/xmlunit/src/etc/xmlunit.pom Modified: trunk/xmlunit/LICENSE.txt =================================================================== --- trunk/xmlunit/LICENSE.txt 2007-04-01 09:52:52 UTC (rev 167) +++ trunk/xmlunit/LICENSE.txt 2007-04-03 03:48:34 UTC (rev 168) @@ -1,6 +1,6 @@ /* ****************************************************************** -Copyright (c) 2001, Jeff Martin, Tim Bacon +Copyright (c) 2001-2007, Jeff Martin, Tim Bacon All rights reserved. Redistribution and use in source and binary forms, with or without Modified: trunk/xmlunit/build.xml =================================================================== --- trunk/xmlunit/build.xml 2007-04-01 09:52:52 UTC (rev 167) +++ trunk/xmlunit/build.xml 2007-04-03 03:48:34 UTC (rev 168) @@ -93,6 +93,9 @@ <target name="setDistVersion" depends="init"> <replace dir="${src.dir}" token="@@version@@" value="${xmlunit.version}" includes="**/*.java"/> + <tstamp> + <format property="ivy.publication.datetime" pattern="yyyyMMddHHmmss"/> + </tstamp> </target> <target name="docs" depends="init"> @@ -121,6 +124,24 @@ basedir="${out.dir}" excludes="**/test_*.class" /> + + <copy todir="${lib.dir}"> + <fileset dir="src/etc"> + <include name="xmlunit.pom"/> + <include name="xmlunit-ivy.xml"/> + </fileset> + <mapper type="glob" from="xmlunit*" to="xmlunit-${xmlunit.version}*"/> + <filterset> + <filter token="VERSION" value="${xmlunit.version}"/> + <filter token="DATE" value="${ivy.publication.datetime}"/> + <filter token="DESCRIPTION" value="XMLUnit compares a control XML document to a test document or the result of a transformation, validates documents, and compares the results of XPath expressions."/> + <filter token="LICENSE" value="BSD License"/> + <filter token="LICENSE_URL" value="http://xmlunit.svn.sourceforge.net/viewvc/*checkout*/xmlunit/trunk/xmlunit/LICENSE.txt"/> + <filter token="GROUP" value="xmlunit"/> + <filter token="ARTIFACT" value="xmlunit"/> + <filter token="TYPE" value="jar"/> + </filterset> + </copy> </target> <target name="dist" depends="jar,test,docs"> Added: trunk/xmlunit/src/etc/xmlunit-ivy.xml =================================================================== --- trunk/xmlunit/src/etc/xmlunit-ivy.xml (rev 0) +++ trunk/xmlunit/src/etc/xmlunit-ivy.xml 2007-04-03 03:48:34 UTC (rev 168) @@ -0,0 +1,13 @@ +<ivy-module version="1.3"> + <info organization="@GROUP@" + module="@ARTIFACT@" + revision="@VERSION@" + publication="@DATE@"> + <license name="@LICENSE@" + url="@LICENSE_URL@"/> + <description>@DESCRIPTION@</description> + </info> + <publications> + <artifact name="@ARTIFACT@" type="@TYPE@"/> + </publications> +</ivy-module> Property changes on: trunk/xmlunit/src/etc/xmlunit-ivy.xml ___________________________________________________________________ Name: svn:eol-style + native Added: trunk/xmlunit/src/etc/xmlunit.pom =================================================================== --- trunk/xmlunit/src/etc/xmlunit.pom (rev 0) +++ trunk/xmlunit/src/etc/xmlunit.pom 2007-04-03 03:48:34 UTC (rev 168) @@ -0,0 +1,16 @@ +<project> + <modelVersion>4.0.0</modelVersion> + <groupId>@GROUP@</groupId> + <artifactId>@ARTIFACT@</artifactId> + <packaging>@TYPE@</packaging> + <version>@VERSION@</version> + <description>@DESCRIPTION@</description> + <url>http://xmlunit.sourceforge.net/</url> + <licenses> + <license> + <name>@LICENSE@</name> + <url>@LICENSE_URL@</url> + </license> + </licenses> + <dependencies/> +</project> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: SourceForge.net <no...@so...> - 2007-04-03 02:20:03
|
Bugs item #1673686, was opened at 2007-03-04 15:17 Message generated for change (Comment added) made by sf-robot You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=377768&aid=1673686&group_id=23187 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None >Status: Closed Resolution: Fixed Priority: 5 Private: No Submitted By: Barrie Treloar (barrie) Assigned to: Nobody/Anonymous (nobody) Summary: XMLTestCase should be abstract (like junit's TestCase) Initial Comment: XMLTestCase should be abstract so any test tools that blindly load any *Test.class file do no try to run junit against XMLTestCase directly. The workaround is to exclude XMLTestCase from the junit test inclusion (assuming the tooling supports this easily) ---------------------------------------------------------------------- >Comment By: SourceForge Robot (sf-robot) Date: 2007-04-02 19:20 Message: Logged In: YES user_id=1312539 Originator: NO This Tracker item was closed automatically by the system. It was previously set to a Pending status, and the original submitter did not respond within 14 days (the time period specified by the administrator of this Tracker). ---------------------------------------------------------------------- Comment By: Stefan Bodewig (bodewig) Date: 2007-03-19 08:32 Message: Logged In: YES user_id=113148 Originator: NO XMLTestCase in svn HEAD is abstract now and will be in XMLUNit 1.1. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=377768&aid=1673686&group_id=23187 |
From: <bo...@us...> - 2007-04-01 09:52:55
|
Revision: 167 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=167&view=rev Author: bodewig Date: 2007-04-01 02:52:52 -0700 (Sun, 01 Apr 2007) Log Message: ----------- Complete validation section Modified Paths: -------------- trunk/xmlunit/src/site/XMLUnit-Java.xml Modified: trunk/xmlunit/src/site/XMLUnit-Java.xml =================================================================== --- trunk/xmlunit/src/site/XMLUnit-Java.xml 2007-03-30 04:11:22 UTC (rev 166) +++ trunk/xmlunit/src/site/XMLUnit-Java.xml 2007-04-01 09:52:52 UTC (rev 167) @@ -663,7 +663,7 @@ <para>XMLUnit requires a JAXP compliant XML parser virtually everywhere. Several features of XMLUnit also require a JAXP - compliant XSLT transformer. If it is avaliable, a JAXP + compliant XSLT transformer. If it is available, a JAXP compliant XPath engine will be used for XPath tests.</para> <para>To build XMLUnit at least JAXP 1.2 is required, this is @@ -746,7 +746,7 @@ <literal>Document</literal>.</para> <para>The output of <literal>Transform</literal> can be used - as input to comparisions, validations, XPath tests and so on. + as input to comparisons, validations, XPath tests and so on. There is no detailed sections on transformations since they are really only a different way to create input for the rest of XMLUnit's machinery. Examples can be found in <xref @@ -800,11 +800,11 @@ <title>DOM Tree Walking</title> <para>To test pieces of XML by traversing the DOM tree you use - the <literal>NodeTester</literal> class. Each DOm + the <literal>NodeTester</literal> class. Each DOM <literal>Node</literal> will be passed to a <literal>NodeTester</literal> implementation you provide. The <literal>AbstractNodeTester</literal> class is provided as a - NullObject pattern base class for your implementations of your + NullObject Pattern base class for implementations of your own.</para> <para>More information is available in <xref @@ -817,10 +817,11 @@ <para>Initially XMLUnit was tightly coupled to JUnit and the recommended approach was to write unit tests by inheriting from - <literal>XMLTestCase</literal>. <literal>XMLTestCase</literal> - provides a pretty long list of <literal>assert...</literal> - methods that may simplify your interaction with XMLUnit's - internals in many common cases.</para> + the <literal>XMLTestCase</literal> class. + <literal>XMLTestCase</literal> provides a pretty long list of + <literal>assert...</literal> methods that may simplify your + interaction with XMLUnit's internals in many common + cases.</para> <para>The <literal>XMLAssert</literal> class provides the same set of <literal>assert...</literal>s as static methods. Use @@ -832,7 +833,7 @@ <para>All power of XMLUnit is available whether you use <literal>XMLTestCase</literal> and/or <literal>XMLAssert</literal> or the underlying API directly. If - you are using JUnit 3.x then using the specifc classes may prove + you are using JUnit 3.x then using the specific classes may prove to be more convenient.</para> </section> @@ -876,8 +877,8 @@ <literal>XMLUnit.getControlDocumentBuilderFactory</literal>, <literal>XMLUnit.getTestDocumentBuilderFactory</literal> and <literal>XMLUnit.getSAXParserFactory</literal> (used by - Validator). Note that all these methods return factories or - parsers that are namespace aware.</para> + <literal>Validator</literal>). Note that all these methods + return factories or parsers that are namespace aware.</para> <para>The various <literal>build...</literal> methods in <literal>XMLUnit</literal> provide convenience layers for @@ -893,7 +894,9 @@ <literal>org.xml.sax.EntityResolver</literal> for the control and test parsers via <literal>XMLUnit.setControlEntityResolver</literal> and - <literal>XMLUnit.setTestEntityResolver</literal>.</para> + <literal>XMLUnit.setTestEntityResolver</literal>. + <literal>Validator</literal> uses the resolver set via + <literal>setControlEntityResolver</literal> as well.</para> </section> <section id="element-content-whitespace"> @@ -904,7 +907,7 @@ model doesn't allow text content. I.e. the newline and space characters between <literal><![CDATA[<foo>]]></literal> and <literal><![CDATA[<bar>]]></literal> in the following example - belongs into this category.</para> + could belong into this category.</para> <programlisting language="XML"><![CDATA[ <foo> @@ -1038,6 +1041,115 @@ <title>DTD Validation</title> </section> + <para>Validating against a DTD is straight forward if the piece + of XML contains a <literal>DOCTYPE</literal> declaration with a + <literal>SYSTEM</literal> identifier that can be resolved at + validation time. Simply create a <literal>Validator</literal> + object using one of the single argument constructors.</para> + + <example> + <title>Validating against the DTD defined in + <literal>DOCTYPE</literal></title> + <programlisting language="Java"><![CDATA[ +InputSource is = new InputSource(new FileInputStream(myXmlDocument)); +Validator v = new Validator(is); +bool isValid = v.isValid(); +]]></programlisting></example> + + <para>If the piece of XML doesn't contain any + <literal>DOCTYPE</literal> declaration at all or it contains a + <literal>DOCTYPE</literal> but you want to validate against a + different DTD, you'd use one of the three argument versions of + <literal>Validator</literal>'s constructors. In this case the + <literal>publicId</literal> argument becomes the + <literal>PUBLIC</literal> and <literal>systemId</literal> the + <literal>SYSTEM</literal> identifier of the + <literal>DOCTYPE</literal> that is implicitly added to the piece + of XML. Any existing <literal>DOCTYPE</literal> will be + removed. The <literal>systemId</literal> should be a URL that + can be resolved by your parser.</para> + + <example> + <title>Validating a piece of XML that doesn't contain a + <literal>DOCTYPE</literal></title> + <programlisting language="Java"><![CDATA[ +InputSource is = new InputSource(new FileInputStream(myXmlDocument)); +Validator v = new Validator(is, + (new File(myDTD)).toURI().toURL(), + myPublicId); +bool isValid = v.isValid(); +]]></programlisting></example> + + <para>If the piece of XML already has the correct + <literal>DOCTYPE</literal> declaration but the declaration + either doesn't specify a <literal>SYSTEM</literal> identifier at + all or you want the <literal>SYSTEM</literal> identifier to + resolve to a different location you have two options:</para> + + <itemizedlist> + <listitem>Use one of the two argument constructors and specify + the alternative URL as + <literal>systemId</literal>. + + <example> + <title>Validating against a local DTD</title> + <programlisting language="Java"><![CDATA[ +InputSource is = new InputSource(new FileInputStream(myXmlDocument)); +Validator v = new Validator(is, + (new File(myDTD)).toURI().toURL()); +bool isValid = v.isValid(); +]]></programlisting></example> + </listitem> + + <listitem>Use a custom <literal>EntityResolver</literal> via + <literal>XMLUnit.setControlEntityResolver</literal> together + with one of the single argument constructor overloads of + Validator. + + <para>This approach would allow you to use an OASIS + catalog<footnote><ulink + url="http://www.oasis-open.org/committees/download.php/14809/xml-catalogs.html">http://www.oasis-open.org/committees/download.php/14809/xml-catalogs.html</ulink></footnote> + in conjunction with the Apache XML Resolver + library<footnote><ulink + url="http://xml.apache.org/commons/components/resolver/index.html">http://xml.apache.org/commons/components/resolver/index.html</ulink></footnote> + to resolve the DTD location as well as the location of any + other entity in your piece of XML, for example.</para> + + <example> + <title>Validating against DTD using Apache's XML Resolver and + a XML Catalog</title> + <programlisting language="Java"><![CDATA[ +InputSource is = new InputSource(new FileInputStream(myXmlDocument)); +XMLUnit.setControlEntityResolver(new CatalogResolver()) +Validator v = new Validator(is); +bool isValid = v.isValid(); +]]></programlisting> + + <programlisting><![CDATA[ +#CatalogManager.properties + +verbosity=1 +relative-catalogs=yes +catalogs=/some/path/to/catalog +prefer=public +static-catalog=yes +catalog-class-name=org.apache.xml.resolver.Resolver +]]></programlisting> + + <programlisting language="XML"><![CDATA[ +<!-- catalog file --> + +<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog"> + <public publicId="-//Some//DTD V 1.1//EN" + uri="mydtd.dtd"/> +</catalog> +]]></programlisting> + +</example> + + </listitem> + </itemizedlist> + <section id="validating-schema"> <title>XML Schema Validation</title> </section> @@ -1083,14 +1195,70 @@ behavior. If no <literal>systemId</literal> has been specified, the configured <literal>EntityResolver</literal> may still be used.</para> + + <example> + <title>Validating against a local XML Schema</title> + <programlisting language="Java"><![CDATA[ +InputSource is = new InputSource(new FileInputStream(myXmlDocument)); +Validator v = new Validator(is); +v.useXMLSchema(true); +v.setJAXP12SchemaSource(new File(myXmlSchemaFile)); +bool isValid = v.isValid(); +]]></programlisting></example> + </section> <section id="validation-junit3"> <title>JUnit 3.x Convenience Methods</title> + + <para>Both <literal>XMLAssert</literal> and + <literal>XMLTestCase</literal> provide an + <literal>assertXMLValid(Validator)</literal> method that will + fail if <literal>Validator</literal>'s + <literal>isValid</literal> method returns + <literal>false</literal>.</para> + + <para>In addition several overloads of the + <literal>assertXMLValid</literal> method are provided that + directly correspond to similar overloads of + <literal>Validator</literal>'s constructor. These overloads + don't support XML Schema validation at all.</para> + + <para><literal>Validator</literal> itself provides an + <literal>assertIsValid</literal> method that will throw an + <literal>AssertionFailedError</literal> if validation + fails.</para> + + <para>Neither method provides any control over the message of + the <literal>AssertionFailedError</literal> in case of a + failure.</para> </section> <section id="validation-config"> <title>Configuration Options</title> + + <itemizedlist> + <listitem><literal>Validator</literal> uses a SAX parser + created by the configured SAX parser factory (see <xref + linkend="JAXP"/>).</listitem> + + <listitem>It will use the "control" + <literal>EntityResolver</literal> if one has been specified + (see <xref linkend="entityresolver"/>).</listitem> + + <listitem>The location of a DTD can be specified via + <literal>Validator</literal>'s <literal>systemId</literal> + constructor argument or a custom EntityResolver (see <xref + linkend="validating-dtd"/>).</listitem> + + <listitem>XML Schema validation is enabled via + <literal>Validator.useXMLSchema(true)</literal>.</listitem> + + <listitem>The location(s) of XML Schema document(s) can be + specified via + <literal>Validator.setJAXP12SchemaSource</literal> (see <xref + linkend="validating-schema"/>).</listitem> + </itemizedlist> </section> </section> @@ -1124,7 +1292,7 @@ been asked for repeatedly:</para> <itemizedlist> - <listitem>Support for XML namespaces in XPath + <listitem>Support for XML Namespaces in XPath processing</listitem> <listitem>Support for XML Schema validation.</listitem> @@ -1140,15 +1308,15 @@ <itemizedlist> <listitem> - <literal>XMLTestCase</literal> is now abstract. There is - no reason why you should have created instances of this - class without subclassing it, but if you did, your code - will now break. You will most likely want to look at the + <literal>XMLTestCase</literal> is now abstract. You + probably have never created instances of this class + without subclassing it, but if you did, your code will now + break. You will most likely want to look at the <literal>XMLAssert</literal> class. </listitem> <listitem> - <para>All methods that have been declared to throw + <para>All methods that had been declared to throw <literal>TransformerConfigurationException</literal> or <literal>ParserConfigurationException</literal> now no longer declare it. Exceptions of these types cannot be @@ -1208,7 +1376,7 @@ "piece of XML" in many classes.</listitem> <listitem><literal>Validator</literal> will now use the - custom <literal>EntityResolver</literal> <link + custom <literal>EntityResolver</literal> <link linkend="entityresolver">configured</link> for the "control" parser as a fallback.</listitem> @@ -1257,7 +1425,7 @@ <listitem>Under certain circumstances the reported XPath expressions for nodes that showed differences were wrong. - XMLUnit could lose the root element or errornously append an + XMLUnit could lose the root element or erroneously append an extra attribute name. Issues <ulink url="http://sourceforge.net/tracker/index.php?func=detail&aid=1047364&group_id=23187&atid=377768">1047364</ulink> and <ulink url="http://sourceforge.net/tracker/index.php?func=detail&aid=1027863&group_id=23187&atid=377770">1027863</ulink>.</listitem> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2007-03-30 04:11:20
|
Revision: 166 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=166&view=rev Author: bodewig Date: 2007-03-29 21:11:22 -0700 (Thu, 29 Mar 2007) Log Message: ----------- validating against an XML Schema Modified Paths: -------------- trunk/xmlunit/src/site/XMLUnit-Java.xml Modified: trunk/xmlunit/src/site/XMLUnit-Java.xml =================================================================== --- trunk/xmlunit/src/site/XMLUnit-Java.xml 2007-03-30 04:00:40 UTC (rev 165) +++ trunk/xmlunit/src/site/XMLUnit-Java.xml 2007-03-30 04:11:22 UTC (rev 166) @@ -886,7 +886,7 @@ </section> - <section> + <section id="entityresolver"> <title><literal>EntityResolver</literal></title> <para>You can provide a custom @@ -1018,6 +1018,22 @@ <section id="validating-basics"> <title>The <literal>Validator</literal> class</title> + <para>The <literal>Validator</literal> class encapsulates + XMLUnit's validation support. It will use the + <literal>SAXParser</literal> configured in XMLUnit (see <xref + linkend="JAXP"/>).</para> + + <para>The piece of XML to validate is specified in the + constructor. The constructors using more than a single argument + are only relevant if you want to validate against a DTD and need + to provide the location of the DTD itself - for details see the + next section.</para> + + <para>By default, <literal>Validator</literal> will validate + against a DTD, but it is possible to validate against a (or + multiple) Schema(s) as well. Schema validation requires an XML + parser that supports it, of course.</para> + <section id="validating-dtd"> <title>DTD Validation</title> </section> @@ -1025,6 +1041,48 @@ <section id="validating-schema"> <title>XML Schema Validation</title> </section> + + <para>In order to validate against the XML Schema language + Schema validation has to be enabled via the + <literal>useXMLSchema</literal> method of + <literal>Validator</literal>.</para> + + <para>By default the parser will try to resolve the location of + Schema definition files via a <literal>schemaLocation</literal> + attribute if it is present in the piece of XML or it will try to + open the Schema's URI as an URL and read from it.</para> + + <para>The <literal>setJAXP12SchemaSource</literal> method of + <literal>Validator</literal> allows you to override this + behavior as long as the parser supports the + <literal>http://java.sun.com/xml/jaxp/properties/schemaSource</literal> + property in the way described in <link + linkend="http://java.sun.com/webservices/jaxp/change-requests-11.html">JAXP + 1.2 Approved CHANGES</link>.</para> + + <para><literal>setJAXP12SchemaSource</literal>'s argument can be + one of</para> + + <itemizedlist> + <listitem>A <literal>String</literal> which contains an + URI.</listitem> + <listitem>An <literal>InputStream</literal> the Schema can be + read from.</listitem> + <listitem>An <literal>InputSource</literal> the Schema can be + read from.</listitem> + <listitem>A <literal>File</literal> the Schema can be + read from.</listitem> + <listitem>An array containing any of the above.</listitem> + </itemizedlist> + + <para>If the property has been set using a + <literal>String</literal>, the <literal>Validator</literal> + class will provide its <literal>systemId</literal> as specified + in the constructor when asked to resolve it. You must only use + the single argument constructors if you want to avoid this + behavior. If no <literal>systemId</literal> has been specified, + the configured <literal>EntityResolver</literal> may still be + used.</para> </section> <section id="validation-junit3"> @@ -1149,6 +1207,11 @@ <literal>org.xml.sax.InputSource</literal> to be used as a "piece of XML" in many classes.</listitem> + <listitem><literal>Validator</literal> will now use the + custom <literal>EntityResolver</literal> <link + linkend="entityresolver">configured</link> for the "control" + parser as a fallback.</listitem> + <listitem> <para>A new package <literal>org.custommonkey.xmlunit.examples</literal> has This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2007-03-30 04:00:41
|
Revision: 165 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=165&view=rev Author: bodewig Date: 2007-03-29 21:00:40 -0700 (Thu, 29 Mar 2007) Log Message: ----------- Use configured EntityResolver in Validator if present Modified Paths: -------------- trunk/xmlunit/src/java/org/custommonkey/xmlunit/Validator.java trunk/xmlunit/src/java/org/custommonkey/xmlunit/XMLUnit.java Modified: trunk/xmlunit/src/java/org/custommonkey/xmlunit/Validator.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/Validator.java 2007-03-30 03:50:01 UTC (rev 164) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/Validator.java 2007-03-30 04:00:40 UTC (rev 165) @@ -37,6 +37,7 @@ package org.custommonkey.xmlunit; import org.custommonkey.xmlunit.exceptions.ConfigurationException; +import org.custommonkey.xmlunit.exceptions.XMLUnitRuntimeException; import java.io.IOException; import java.io.InputStreamReader; @@ -444,8 +445,28 @@ public InputSource resolveEntity(String publicId, String systemId) { if (validationInputSource.getSystemId() != null) { return new InputSource(validationInputSource.getSystemId()); - } else if (systemId != null) { - return new InputSource(systemId); + } else { + InputSource s = null; + try { + if (XMLUnit.getControlEntityResolver() != null) { + s = XMLUnit.getControlEntityResolver() + .resolveEntity(publicId, systemId); + } + } catch (SAXException e) { + throw new XMLUnitRuntimeException("failed to resolve entity: " + + publicId, e); + } catch (IOException e) { + // even if we wanted to re-throw IOException (which we + // can't because of backwards compatibility) the mere + // fact that DefaultHandler has stripped IOException + // from EntityResolver's method's signature wouldn't + // let us. + throw new XMLUnitRuntimeException("failed to resolve entity: " + + publicId, e); + } + if (s == null && systemId != null) { + return new InputSource(systemId); + } } return null; } Modified: trunk/xmlunit/src/java/org/custommonkey/xmlunit/XMLUnit.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/XMLUnit.java 2007-03-30 03:50:01 UTC (rev 164) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/XMLUnit.java 2007-03-30 04:00:40 UTC (rev 165) @@ -146,6 +146,13 @@ } /** + * Obtains the EntityResolver to be added to all new control parsers. + */ + public static EntityResolver getControlEntityResolver() { + return controlEntityResolver; + } + + /** * Get the <code>DocumentBuilderFactory</code> instance used to instantiate * parsers for the control XML in an XMLTestCase. * @return factory for control parsers This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2007-03-30 03:50:00
|
Revision: 164 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=164&view=rev Author: bodewig Date: 2007-03-29 20:50:01 -0700 (Thu, 29 Mar 2007) Log Message: ----------- refactor DoctypeReader/InputStream Modified Paths: -------------- trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeInputStream.java trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeReader.java trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeSupport.java trunk/xmlunit/src/java/org/custommonkey/xmlunit/Validator.java trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DoctypeInputStream.java trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DoctypeReader.java Added Paths: ----------- trunk/xmlunit/src/java/org/custommonkey/xmlunit/util/ trunk/xmlunit/src/java/org/custommonkey/xmlunit/util/IntegerBuffer.java trunk/xmlunit/tests/java/org/custommonkey/xmlunit/AbstractDoctypeTests.java trunk/xmlunit/tests/java/org/custommonkey/xmlunit/util/ trunk/xmlunit/tests/java/org/custommonkey/xmlunit/util/test_IntegerBuffer.java Removed Paths: ------------- trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeConstants.java Deleted: trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeConstants.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeConstants.java 2007-03-29 07:19:41 UTC (rev 163) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeConstants.java 2007-03-30 03:50:01 UTC (rev 164) @@ -1,45 +0,0 @@ -/* -****************************************************************** -Copyright (c) 2001, Jeff Martin, Tim Bacon -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; - -interface DoctypeConstants { - String DOCTYPE_OPEN_DECL = "<!"; - int DECL_LENGTH = DOCTYPE_OPEN_DECL.length(); - String DOCTYPE_CLOSE_DECL = ">"; - String DOCTYPE = "DOCTYPE "; - String SYSTEM = " SYSTEM \""; -} \ No newline at end of file Modified: trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeInputStream.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeInputStream.java 2007-03-29 07:19:41 UTC (rev 163) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeInputStream.java 2007-03-30 03:50:01 UTC (rev 164) @@ -51,21 +51,11 @@ * <br />Examples and more at <a href="http://xmlunit.sourceforge.net"/>xmlunit.sourceforge.net</a> */ public class DoctypeInputStream extends InputStream { + + private final ByteArrayOutputStream baos = new ByteArrayOutputStream(1024); private final InputStream wrappedStream; + private final DoctypeSupport support; - private static final byte[] DOCTYPE_BYTES = { - 'D', 'O', 'C', 'T', 'Y', 'P', 'E', ' ' - }; - - private byte[] readAheadBeforeDeclBuffer = null; - private int readAheadBeforeDeclOffset = 0; - private byte[] readAheadAfterDeclBuffer = null; - private int readAheadAfterDeclOffset = 0; - - private final DoctypeSupport docType; - private boolean writeDecl = false; - - /** * Create an InputStream whose XML content is provided by the * originalSource with the exception of the DOCTYPE which is @@ -74,143 +64,44 @@ * @param doctypeName * @param systemID */ - public DoctypeInputStream(InputStream originalSource, String doctypeName, - String systemID) { + public DoctypeInputStream(InputStream originalSource, String encoding, + String doctypeName, String systemID) { wrappedStream = originalSource instanceof BufferedInputStream ? originalSource : new BufferedInputStream(originalSource); - docType = new DoctypeSupport(doctypeName, systemID); + support = + new DoctypeSupport(doctypeName, systemID, + new DoctypeSupport.Readable() { + public int read() throws IOException { + return wrappedStream.read(); + } + }, + false, encoding); } /** - * Read DOCTYPE-replaced content from the wrapped Reader + * @return the content of the original source, without amendments or + * substitutions. Safe to call multiple times. + * @throws IOException if thrown while reading from the original source */ - public int read() throws IOException { - int nextByte = -1; - - if (writeDecl) { - // currently writing our own DOCTYPE declaration - nextByte = docType.read(); - if (nextByte == -1) { - writeDecl = false; - } else { - return nextByte; + protected String getContent(String encoding) throws IOException { + if (baos.size() == 0) { + byte[] buffer = new byte[8192]; + int bytesRead = -1; + while ((bytesRead = wrappedStream.read(buffer)) > -1) { + baos.write(buffer, 0, bytesRead); } } - - if (readAheadBeforeDeclBuffer != null) { - // in part of original document before our DOCTYPE - this - // has already been read - nextByte = readAheadBeforeDeclBuffer[readAheadBeforeDeclOffset++]; - if (readAheadBeforeDeclOffset >= readAheadBeforeDeclBuffer.length) { - readAheadBeforeDeclBuffer = null; - writeDecl = true; - } - } else if (!docType.hasBeenRead()) { - // DOCTYPE not written, yet, need to see where it should go - - // read ahead until we find a good place to insert the doctype, - // store bytes in readAheadBuffers - ByteArrayOutputStream beforeDecl = new ByteArrayOutputStream(); - ByteArrayOutputStream afterDecl = new ByteArrayOutputStream(); - int current; - boolean ready = false; - while (!ready && (current = wrappedStream.read()) != -1) { - byte c = (byte) current; - if (c >= 0 && Character.isWhitespace((char) c)) { - beforeDecl.write(c); - } else if (c == '<') { - // could be XML declaration, comment, PI, DOCTYPE - // or the first element - byte[] elementOrDeclOr = readUntilCloseCharacterIsReached(); - if (elementOrDeclOr.length > 0) { - if (elementOrDeclOr[0] == '?') { - // XML declaration or PI - beforeDecl.write('<'); - beforeDecl.write(elementOrDeclOr, 0, - elementOrDeclOr.length); - } else if (elementOrDeclOr[0] != '!') { - // first element - afterDecl.write('<'); - afterDecl.write(elementOrDeclOr, 0, - elementOrDeclOr.length); - ready = true; - } else { - // comment or doctype - if (indexOfDoctype(elementOrDeclOr) == -1) { - afterDecl.write('<'); - afterDecl.write(elementOrDeclOr, 0, - elementOrDeclOr.length); - } // else swallow old declaration - ready = true; - } - } - - } else { - afterDecl.write(c); - ready = true; - } - } - readAheadBeforeDeclBuffer = beforeDecl.size() > 0 - ? beforeDecl.toByteArray() : null; - readAheadAfterDeclBuffer = afterDecl.size() > 0 - ? afterDecl.toByteArray() : null; - writeDecl = (readAheadBeforeDeclBuffer == null); - return read(); - } else if (readAheadAfterDeclBuffer != null) { - // in part of original document read ahead after our DOCTYPE - nextByte = readAheadAfterDeclBuffer[readAheadAfterDeclOffset++]; - if (readAheadAfterDeclOffset >= readAheadAfterDeclBuffer.length) { - readAheadAfterDeclBuffer = null; - } - } else { - nextByte = wrappedStream.read(); - } - return nextByte; + return encoding == null ? baos.toString() : baos.toString(encoding); } - private byte[] readUntilCloseCharacterIsReached() throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - int byteRead = -1; - int openCount = 1; - while (openCount > 0 && (byteRead = wrappedStream.read()) != -1) { - byte c = (byte) byteRead; - baos.write(c); - if (c == '<') { - openCount++; - } - if (c == '>') { - openCount--; - } - } - return baos.toByteArray(); + /** + * Read DOCTYPE-replaced content from the wrapped InputStream + */ + public int read() throws IOException { + return support.read(); } - + public void close() throws IOException { wrappedStream.close(); } - - /** - * Could be faster when searching from the other end, but should do. - */ - private static int indexOfDoctype(byte[] b) { - int index = -1; - for (int i = 0; i < b.length - DOCTYPE_BYTES.length + 1; i++) { - if (b[i] == DOCTYPE_BYTES[0]) { - boolean found = false; - int j = 1; - for (; !found && j < DOCTYPE_BYTES.length; j++) { - if (b[i + j] != DOCTYPE_BYTES[j]) { - found = true; - } - } - if (found) { - index = i; - break; - } else { - i += j - 1; - } - } - } - return index; - } } \ No newline at end of file Modified: trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeReader.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeReader.java 2007-03-29 07:19:41 UTC (rev 163) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeReader.java 2007-03-30 03:50:01 UTC (rev 164) @@ -49,19 +49,13 @@ * document against a DTD. * <br />Examples and more at <a href="http://xmlunit.sourceforge.net"/>xmlunit.sourceforge.net</a> */ -public class DoctypeReader extends Reader implements DoctypeConstants { +public class DoctypeReader extends Reader { private final Reader originalReader; private final StringBuffer sourceBuffer = new StringBuffer(1024); - private char[] readAheadBeforeDeclBuffer = null; - private int readAheadBeforeDeclOffset = 0; - private char[] readAheadAfterDeclBuffer = null; - private int readAheadAfterDeclOffset = 0; + private final DoctypeSupport support; - private final DoctypeSupport docType; - private boolean writeDecl = false; - /** * Create a Reader whose XML content is provided by the originalSource with * the exception of the DOCTYPE which is provided by the doctypeName @@ -74,18 +68,23 @@ String systemID) { originalReader = originalSource instanceof BufferedReader ? originalSource : new BufferedReader(originalSource); - docType = new DoctypeSupport(doctypeName, systemID); + support = + new DoctypeSupport(doctypeName, systemID, + new DoctypeSupport.Readable() { + public int read() throws IOException { + return originalReader.read(); + } + }, + true, null); } /** * @return the content of the original source, without amendments or * substitutions. Safe to call multiple times. * @throws IOException if thrown while reading from the original source - * @deprecated this method is only here for BWC, it is no longer - * used by this class */ protected String getContent() throws IOException { - return obsoleteGetContent(originalReader).toString(); + return getContent(originalReader).toString(); } /** @@ -93,7 +92,7 @@ * @return the contents of the originalSource within a StringBuffer * @throws IOException if thrown while reading from the original source */ - private StringBuffer obsoleteGetContent(Reader originalSource) + private StringBuffer getContent(Reader originalSource) throws IOException { if (sourceBuffer.length() == 0) { BufferedReader bufferedReader; @@ -163,19 +162,22 @@ public String replaceDoctype(StringBuffer withinContent, String doctypeName, String systemId) { String content = withinContent.toString(); - int startDoctype = content.indexOf(DOCTYPE); + int startDoctype = content.indexOf(DoctypeSupport.DOCTYPE); boolean noCurrentDoctype = false; if (startDoctype == -1) { startDoctype = obsoleteFindStartDoctype(withinContent); noCurrentDoctype = true; } - int endDoctype = startDoctype + DOCTYPE.length(); + int endDoctype = startDoctype + DoctypeSupport.DOCTYPE.length(); if (noCurrentDoctype) { - withinContent.insert(startDoctype, DOCTYPE_OPEN_DECL); - withinContent.insert(startDoctype + DECL_LENGTH, DOCTYPE); - endDoctype += DECL_LENGTH; + withinContent.insert(startDoctype, + DoctypeSupport.DOCTYPE_OPEN_DECL); + withinContent.insert(startDoctype + + DoctypeSupport.DOCTYPE_OPEN_DECL.length(), + DoctypeSupport.DOCTYPE); + endDoctype += DoctypeSupport.DOCTYPE_OPEN_DECL.length(); } else { int startInternalDecl = content.indexOf('[', endDoctype); if (startInternalDecl > 0) { @@ -190,14 +192,14 @@ int atPos = endDoctype; withinContent.insert(atPos, doctypeName); atPos += doctypeName.length(); - withinContent.insert(atPos, SYSTEM); - atPos += SYSTEM.length(); + withinContent.insert(atPos, DoctypeSupport.SYSTEM); + atPos += DoctypeSupport.SYSTEM.length(); withinContent.insert(atPos, systemId); atPos += systemId.length(); withinContent.insert(atPos, '"'); if (noCurrentDoctype) { - withinContent.insert(++atPos, DOCTYPE_CLOSE_DECL); + withinContent.insert(++atPos, DoctypeSupport.DOCTYPE_CLOSE_DECL); } return withinContent.toString(); } @@ -224,102 +226,9 @@ * Read DOCTYPE-replaced content from the wrapped Reader */ public int read() throws IOException { - int nextChar = -1; - - if (writeDecl) { - // currently writing our own DOCTYPE declaration - nextChar = docType.read(); - if (nextChar == -1) { - writeDecl = false; - } else { - return nextChar; - } - } - - if (readAheadBeforeDeclBuffer != null) { - // in part of original document before our DOCTYPE - this - // has already been read - nextChar = readAheadBeforeDeclBuffer[readAheadBeforeDeclOffset++]; - if (readAheadBeforeDeclOffset >= readAheadBeforeDeclBuffer.length) { - readAheadBeforeDeclBuffer = null; - writeDecl = true; - } - } else if (!docType.hasBeenRead()) { - // DOCTYPE not written, yet, need to see where it should go - - // read ahead until we find a good place to insert the doctype, - // store characters in readAheadBuffers - StringBuffer beforeDecl = new StringBuffer(); - StringBuffer afterDecl = new StringBuffer(); - int current; - boolean ready = false; - while (!ready && (current = originalReader.read()) != -1) { - char c = (char) current; - if (Character.isWhitespace(c)) { - beforeDecl.append(c); - } else if (c == '<') { - // could be XML declaration, comment, PI, DOCTYPE - // or the first element - String elementOrDeclOr = readUntilCloseCharacterIsReached(); - if (elementOrDeclOr.length() > 0) { - if (elementOrDeclOr.charAt(0) == '?') { - // XML declaration or PI - beforeDecl.append('<').append(elementOrDeclOr); - } else if (elementOrDeclOr.charAt(0) != '!') { - // first element - afterDecl.append('<').append(elementOrDeclOr); - ready = true; - } else { - // comment or doctype - if (elementOrDeclOr.indexOf(DOCTYPE) == -1) { - afterDecl.append('<').append(elementOrDeclOr); - } // else swallow old declaration - ready = true; - } - } - - } else { - afterDecl.append(c); - ready = true; - } - } - readAheadBeforeDeclBuffer = beforeDecl.length() > 0 - ? beforeDecl.toString().toCharArray() - : null; - readAheadAfterDeclBuffer = afterDecl.length() > 0 - ? afterDecl.toString().toCharArray() - : null; - writeDecl = (readAheadBeforeDeclBuffer == null); - return read(); - } else if (readAheadAfterDeclBuffer != null) { - // in part of original document read ahead after our DOCTYPE - nextChar = readAheadAfterDeclBuffer[readAheadAfterDeclOffset++]; - if (readAheadAfterDeclOffset >= readAheadAfterDeclBuffer.length) { - readAheadAfterDeclBuffer = null; - } - } else { - nextChar = originalReader.read(); - } - return nextChar; + return support.read(); } - private String readUntilCloseCharacterIsReached() throws IOException { - StringBuffer sb = new StringBuffer(); - int characterRead = -1; - int openCount = 1; - while (openCount > 0 && (characterRead = originalReader.read()) != -1) { - char c = (char) characterRead; - sb.append(c); - if (c == '<') { - openCount++; - } - if (c == '>') { - openCount--; - } - } - return sb.toString(); - } - public void close() throws IOException { originalReader.close(); } Modified: trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeSupport.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeSupport.java 2007-03-29 07:19:41 UTC (rev 163) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeSupport.java 2007-03-30 03:50:01 UTC (rev 164) @@ -36,39 +36,231 @@ package org.custommonkey.xmlunit; +import java.io.IOException; + +import org.custommonkey.xmlunit.exceptions.XMLUnitRuntimeException; +import org.custommonkey.xmlunit.util.IntegerBuffer; + /** * Contains some common code for DoctypeReader and DoctypeInputStream. * * <p>When used with DoctypeInputStream it assumes that the whole * DOCTYPE declaration consists of US-ASCII characters.</p> */ -final class DoctypeSupport implements DoctypeConstants { +final class DoctypeSupport { - private final String decl; - private int offset = 0; + static interface Readable { + int read() throws IOException; + } + final static String DOCTYPE_OPEN_DECL = "<!"; + final static String DOCTYPE_CLOSE_DECL = ">"; + final static String DOCTYPE = "DOCTYPE "; + final static String SYSTEM = " SYSTEM \""; + private final static int[] DOCTYPE_INTS = { + 'D', 'O', 'C', 'T', 'Y', 'P', 'E', ' ' + }; + + private boolean hasSplit; + private final Readable original; + private Readable decl; + private Readable beforeDoctype; + private Readable afterDoctype; + /** * Encapsulates a DOCTYPE declaration for the given name and system id. */ - DoctypeSupport(String name, String systemId) { + DoctypeSupport(String name, String systemId, Readable original, + boolean characters, String encoding) { + this.original = original; + StringBuffer sb = new StringBuffer(DOCTYPE_OPEN_DECL); sb.append(DOCTYPE).append(name).append(SYSTEM) .append(systemId).append("\"").append(DOCTYPE_CLOSE_DECL); - decl = sb.toString(); + String s = sb.toString(); + IntegerBuffer buf = + new IntegerBuffer(s.length() * (characters ? 1 : 2)); + + if (characters) { + char[] c = s.toCharArray(); + for (int i = 0; i < c.length; i++) { + buf.append(c[i]); + } + } else { + try { + byte[] b = encoding == null + ? s.getBytes() : s.getBytes(encoding); + for (int i = 0; i < b.length; i++) { + buf.append(b[i] & 0xFF); + } + } catch (java.io.UnsupportedEncodingException use) { + throw new XMLUnitRuntimeException("Unsupported encoding", use); + } + } + + decl = new IntBufferReadable(buf); } /** - * Whether anybody has started to read the declaration. + * Reads the next character from the declaration. + * @return -1 if the end of the declaration has been reached. */ - boolean hasBeenRead() { - return offset != 0; + int read() throws IOException { + int nextInt = -1; + if (!hasSplit) { + split(); + } + if (beforeDoctype != null) { + nextInt = beforeDoctype.read(); + if (nextInt == -1) { + beforeDoctype = null; + } + } + if (nextInt == -1 && decl != null) { + nextInt = decl.read(); + if (nextInt == -1) { + decl = null; + } + } + if (nextInt == -1 && afterDoctype != null) { + nextInt = afterDoctype.read(); + if (nextInt == -1) { + afterDoctype = null; + } + } + if (nextInt == -1) { + nextInt = original.read(); + } + return nextInt; } /** - * Reads the next character from the declaration. - * @return -1 if the end of the declaration has been reached. + * Reads enough of the original Readable to know where to place + * the declaration. Fills beforeDecl and afterDecl from the data + * read ahead. Swallows the original DOCTYPE if there is one. */ - int read() { - return offset >= decl.length() ? -1 : decl.charAt(offset++); + private void split() throws IOException { + hasSplit = true; + IntegerBuffer before = new IntegerBuffer(); + IntegerBuffer after = new IntegerBuffer(); + + int current; + boolean ready = false; + boolean stillNeedToSeeDoctype = true; + while (!ready && (current = original.read()) != -1) { + if (Character.isWhitespace((char) current)) { + before.append(current); + } else if (current == '<') { + // could be XML declaration, comment, PI, DOCTYPE + // or the first element + int[] elementOrDeclOr = readUntilCloseCharIsReached(); + if (elementOrDeclOr.length > 0) { + if (elementOrDeclOr[0] == '?') { + // XML declaration or PI + before.append('<'); + before.append(elementOrDeclOr); + } else if (elementOrDeclOr[0] != '!') { + // first element + after.append('<'); + after.append(elementOrDeclOr); + stillNeedToSeeDoctype = false; + ready = true; + } else { + // comment or doctype + IntegerBuffer b = + new IntegerBuffer(elementOrDeclOr.length); + b.append(elementOrDeclOr); + if (b.indexOf(DOCTYPE_INTS) == -1) { + after.append('<'); + after.append(elementOrDeclOr); + } else { + // swallow old declaration + stillNeedToSeeDoctype = false; + } + ready = true; + } + } else { + after.append('<'); + stillNeedToSeeDoctype = false; + ready = true; + } + } else { + after.append(current); + stillNeedToSeeDoctype = false; + ready = true; + } + } + + // need to eliminate original DOCTYPE if it exists + while (stillNeedToSeeDoctype && (current = original.read()) != -1) { + if (Character.isWhitespace((char) current)) { + after.append(current); + } else if (current == '<') { + int[] elementOrDeclOr = readUntilCloseCharIsReached(); + if (elementOrDeclOr.length > 0) { + if (elementOrDeclOr[0] == '?') { + // PI + after.append('<'); + after.append(elementOrDeclOr); + } else if (elementOrDeclOr[0] != '!') { + // first element + after.append('<'); + after.append(elementOrDeclOr); + stillNeedToSeeDoctype = false; + } else { + // comment or doctype + IntegerBuffer b = + new IntegerBuffer(elementOrDeclOr.length); + b.append(elementOrDeclOr); + if (b.indexOf(DOCTYPE_INTS) == -1) { + after.append('<'); + after.append(elementOrDeclOr); + } else { + // swallow old declaration + stillNeedToSeeDoctype = false; + } + } + } else { + after.append('<'); + stillNeedToSeeDoctype = false; + } + } else { + after.append(current); + stillNeedToSeeDoctype = false; + } + } + + beforeDoctype = before.size() > 0 + ? new IntBufferReadable(before) : null; + afterDoctype = after.size() > 0 + ? new IntBufferReadable(after) : null; } + + private int[] readUntilCloseCharIsReached() throws IOException { + IntegerBuffer i = new IntegerBuffer(); + int intRead = -1; + int openCount = 1; + while (openCount > 0 && (intRead = original.read()) != -1) { + i.append(intRead); + if (intRead == '<') { + openCount++; + } + if (intRead == '>') { + openCount--; + } + } + return i.toIntArray(); + } + + private static class IntBufferReadable implements Readable { + private final int[] buf; + private int off; + IntBufferReadable(IntegerBuffer b) { + buf = b.toIntArray(); + } + public int read() { + return off >= buf.length ? -1 : buf[off++]; + } + } + } \ No newline at end of file Modified: trunk/xmlunit/src/java/org/custommonkey/xmlunit/Validator.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/Validator.java 2007-03-29 07:19:41 UTC (rev 163) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/Validator.java 2007-03-30 03:50:01 UTC (rev 164) @@ -258,6 +258,8 @@ doctype, systemID)) : new InputSource(new DoctypeInputStream(sourceForValidation .getByteStream(), + sourceForValidation + .getEncoding(), doctype, systemID)), systemID, true); } @@ -382,7 +384,7 @@ } else if (usingDoctypeReader) { try { messages.append("\nContent was: ") - .append(readFully(validationInputSource)); + .append(getOriginalContent(validationInputSource)); } catch (IOException e) { // silent but deadly? } @@ -492,30 +494,11 @@ schemaSource); } - private static String readFully(InputSource s) throws IOException { - return s.getCharacterStream() != null - ? readFully(s.getCharacterStream()) : readFully(s.getByteStream()); + private static String getOriginalContent(InputSource s) + throws IOException { + return s.getCharacterStream() instanceof DoctypeReader + ? ((DoctypeReader) s.getCharacterStream()).getContent() + : ((DoctypeInputStream) s.getByteStream()) + .getContent(s.getEncoding()); } - - private static String readFully(Reader r) throws IOException { - StringBuffer sb = new StringBuffer(); - char[] buffer = new char[4096]; - int charsRead = -1; - while ((charsRead = r.read(buffer)) > -1) { - sb.append(buffer, 0, charsRead); - } - return sb.toString(); - } - - private static String readFully(java.io.InputStream is) throws IOException { - java.io.ByteArrayOutputStream baos = - new java.io.ByteArrayOutputStream(); - byte[] buffer = new byte[8192]; - int bytesRead = -1; - while ((bytesRead = is.read(buffer)) > -1) { - baos.write(buffer, 0, bytesRead); - } - return new String(baos.toByteArray()); - } - } Added: trunk/xmlunit/src/java/org/custommonkey/xmlunit/util/IntegerBuffer.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/util/IntegerBuffer.java (rev 0) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/util/IntegerBuffer.java 2007-03-30 03:50:01 UTC (rev 164) @@ -0,0 +1,146 @@ +/* +****************************************************************** +Copyright (c) 2001, Jeff Martin, Tim Bacon +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.util; + +/** + * Simplistic dynamically growing buffer of integers used by DoctypeSupport. + * + * <p>No attempt has been made to make this class thread-safe at all. + * The append methods and indexOf are not too efficient either, but + * work for what we need.</p> + */ +public class IntegerBuffer { + + // should be big enough for the DoctypeSupport use case + private static final int INITIAL_SIZE = 512; + + private int[] buffer; + private int currentSize; + + /** + * Creates a new buffer. + */ + public IntegerBuffer() { + this(INITIAL_SIZE); + } + + /** + * Creates a new buffer with the given initial capacity. + */ + public IntegerBuffer(int capacity) { + buffer = new int[capacity]; + } + + /** + * Returns the current size. + */ + public int size() { + return currentSize; + } + + /** + * Returns the current capacity (the size the buffer can use + * before it needs to grow). + */ + public int capacity() { + return buffer.length; + } + + /** + * Appends a single int. + */ + public void append(int i) { + // could simply delegate to the other append methods, but this + // (avoiding arraycopy) is more efficient. + while (currentSize >= buffer.length) { + grow(); + } + buffer[currentSize++] = i; + } + + /** + * Appends an array of ints. + */ + public void append(int[] i) { + // could simply delegate to the other append methods, but this + // (avoiding repeated comparisions) is more efficient. + while (currentSize + i.length > buffer.length) { + grow(); + } + System.arraycopy(i, 0, buffer, currentSize, i.length); + currentSize += i.length; + } + + /** + * Returns an arry view of this buffer's content. + */ + public int[] toIntArray() { + int[] i = new int[currentSize]; + System.arraycopy(buffer, 0, i, 0, currentSize); + return i; + } + + /** + * finds sequence in current buffer. + * + * @return index of sequence or -1 if not found + */ + public int indexOf(int[] sequence) { + int index = -1; + for (int i = 0; index == -1 && i <= currentSize - sequence.length; + i++) { + if (buffer[i] == sequence[0]) { + boolean matches = true; + for (int j = 1; matches && j < sequence.length; j++) { + if (buffer[i + j] != sequence[j]) { + matches = false; + } + } + if (matches) { + index = i; + } + } + } + return index; + } + + private void grow() { + int[] i = new int[buffer.length * 2 + 1]; + System.arraycopy(buffer, 0, i, 0, buffer.length); + buffer = i; + } +} \ No newline at end of file Property changes on: trunk/xmlunit/src/java/org/custommonkey/xmlunit/util/IntegerBuffer.java ___________________________________________________________________ Name: svn:eol-style + native Added: trunk/xmlunit/tests/java/org/custommonkey/xmlunit/AbstractDoctypeTests.java =================================================================== --- trunk/xmlunit/tests/java/org/custommonkey/xmlunit/AbstractDoctypeTests.java (rev 0) +++ trunk/xmlunit/tests/java/org/custommonkey/xmlunit/AbstractDoctypeTests.java 2007-03-30 03:50:01 UTC (rev 164) @@ -0,0 +1,121 @@ +/* +****************************************************************** +Copyright (c) 200, Jeff Martin, Tim Bacon +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; + +import java.io.IOException; + +import junit.framework.TestCase; + +/** + * JUnit test for DoctypeReader and DoctypeInputStream + */ +public abstract class AbstractDoctypeTests extends TestCase { + + private static final String COMMENT = "<!-- comment -->"; + protected static final String NO_DTD = + "<document><element>one</element></document>"; + + public abstract void testGetContent() throws IOException; + + protected abstract void assertEquals(String expected, String input, + String docType, String systemId) + throws IOException; + + public void testRead() throws IOException { + String oz = "Chirurgische Verbesserungen sind g\u00fcnstig"; + assertEquals("<!DOCTYPE Kylie SYSTEM \"bumJob\">" + oz, + oz, "Kylie", "bumJob"); + } + + public void testInternalDTD() throws IOException { + assertEquals("<!DOCTYPE ni SYSTEM \"shrubbery\">", + test_Constants.CHUCK_JONES_RIP_DTD_DECL, "ni", + "shrubbery"); + } + + public void testExternalDTD() throws IOException { + assertEquals("<!DOCTYPE ni SYSTEM \"shrubbery\">", + "<! DOCTYPE PUBLIC \"yak\" SYSTEM \"llama\">", "ni", + "shrubbery"); + } + + public void testNoDTD() throws IOException { + assertEquals("<!DOCTYPE ni SYSTEM \"shrubbery\">" + NO_DTD, + NO_DTD, "ni", "shrubbery"); + } + + public void testNoDTDButXMLDecl() throws IOException { + assertEquals(test_Constants.XML_DECLARATION + + "<!DOCTYPE ni SYSTEM \"shrubbery\">" + NO_DTD, + test_Constants.XML_DECLARATION + NO_DTD, + "ni", "shrubbery"); + } + + public void testInternalDTDWithComment() throws IOException { + assertEquals(test_Constants.XML_DECLARATION + + "<!DOCTYPE ni SYSTEM \"shrubbery\">" + + COMMENT, + test_Constants.XML_DECLARATION + + COMMENT + + test_Constants.CHUCK_JONES_RIP_DTD_DECL, + "ni", "shrubbery"); + } + + public void testExternalDTDWithComment() throws IOException { + assertEquals("<!DOCTYPE ni SYSTEM \"shrubbery\">" + + COMMENT, + COMMENT + "<! DOCTYPE PUBLIC \"yak\" SYSTEM \"llama\">", + "ni", "shrubbery"); + } + + public void testNoDTDWithComment() throws IOException { + assertEquals("<!DOCTYPE ni SYSTEM \"shrubbery\">" + COMMENT + NO_DTD, + COMMENT + NO_DTD, "ni", "shrubbery"); + } + + public void testNoDTDButXMLDeclWithComment() throws IOException { + assertEquals(test_Constants.XML_DECLARATION + + "<!DOCTYPE ni SYSTEM \"shrubbery\">" + COMMENT + NO_DTD, + test_Constants.XML_DECLARATION + COMMENT + NO_DTD, + "ni", "shrubbery"); + } + + public AbstractDoctypeTests(String name) { + super(name); + } +} + Property changes on: trunk/xmlunit/tests/java/org/custommonkey/xmlunit/AbstractDoctypeTests.java ___________________________________________________________________ Name: svn:eol-style + native Modified: trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DoctypeInputStream.java =================================================================== --- trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DoctypeInputStream.java 2007-03-29 07:19:41 UTC (rev 163) +++ trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DoctypeInputStream.java 2007-03-30 03:50:01 UTC (rev 164) @@ -49,10 +49,8 @@ /** * JUnit test for DoctypeInputStream */ -public class test_DoctypeInputStream extends TestCase { +public class test_DoctypeInputStream extends AbstractDoctypeTests { - private static final String NEWLINE = System.getProperty("line.separator"); - private static final String NO_DTD = "<document><element>one</element></document>"; private File testFile; public void tearDown() { @@ -85,13 +83,13 @@ return buf.toString(); } - private void assertEquals(String expected, String input, String docType, - String systemId) throws IOException { + protected void assertEquals(String expected, String input, String docType, + String systemId) throws IOException { FileInputStream fis = null; try { fis = testDocument(input); DoctypeInputStream doctypeInputStream = - new DoctypeInputStream(fis, docType, systemId); + new DoctypeInputStream(fis, "ISO-8859-1", docType, systemId); assertEquals(expected, readFully(doctypeInputStream)); } finally { @@ -101,42 +99,18 @@ } } - public void testRead() throws IOException { - String oz = "Chirurgische Verbesserungen sind g\u00fcnstig"; - assertEquals("<!DOCTYPE Kylie SYSTEM \"bumJob\">" + oz, - oz, "Kylie", "bumJob"); + public void testGetContent() throws IOException { + String source = "WooPDeDoO!\nGooRanga!\n plIng! "; + DoctypeInputStream dis = + new DoctypeInputStream(new java.io.StringBufferInputStream(source), + null, "nonsense", "words"); + assertEquals(source, dis.getContent(null)); + // can get content indefinitely from this stream + assertEquals(source, dis.getContent("UTF-8")); } - public void testReplaceDoctypeInternalDTD() throws IOException { - assertEquals("<!DOCTYPE ni SYSTEM \"shrubbery\">", - test_Constants.CHUCK_JONES_RIP_DTD_DECL, "ni", - "shrubbery"); - } - - public void XtestReplaceDoctypeExternalDTD() throws IOException { - assertEquals("<!DOCTYPE ni SYSTEM \"shrubbery\">", - "<! DOCTYPE PUBLIC \"yak\" SYSTEM \"llama\">", "ni", - "shrubbery"); - } - - public void testReplaceDoctypeNoDTD() throws IOException { - assertEquals("<!DOCTYPE ni SYSTEM \"shrubbery\">" + NO_DTD, - NO_DTD, "ni", "shrubbery"); - } - - public void testReplaceDoctypeNoDTDButXMLDecl() throws IOException { - assertEquals(test_Constants.XML_DECLARATION - + "<!DOCTYPE ni SYSTEM \"shrubbery\">" + NO_DTD, - test_Constants.XML_DECLARATION + NO_DTD, - "ni", "shrubbery"); - } - public test_DoctypeInputStream(String name) { super(name); } - - public static TestSuite suite() { - return new TestSuite(test_DoctypeInputStream.class); - } } Modified: trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DoctypeReader.java =================================================================== --- trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DoctypeReader.java 2007-03-29 07:19:41 UTC (rev 163) +++ trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DoctypeReader.java 2007-03-30 03:50:01 UTC (rev 164) @@ -36,7 +36,7 @@ package org.custommonkey.xmlunit; - +import java.io.IOException; import java.io.StringReader; import junit.framework.TestCase; @@ -45,29 +45,12 @@ /** * JUnit test for DoctypeReader */ -public class test_DoctypeReader extends TestCase { +public class test_DoctypeReader extends AbstractDoctypeTests { private DoctypeReader doctypeReader; private StringReader sourceReader; private static final String NEWLINE = System.getProperty("line.separator"); - private static final String NO_DTD = "<document><element>one</element></document>"; - public void testRead() throws Exception { - String oz = "Surgical enhancement is cheap"; - StringReader reader = new StringReader(oz); - doctypeReader = new DoctypeReader(reader, "Kylie", "bumJob"); - - StringBuffer buf = new StringBuffer(); - String expected = "<!DOCTYPE Kylie SYSTEM \"bumJob\">" + oz; - char[] ch = new char[expected.length()]; - int numChars; - while ((numChars = doctypeReader.read(ch))!=-1) { - buf.append(ch); - } - - assertEquals(expected, buf.toString()); - } - - public void testGetContent() throws Exception { + public void testGetContent() throws IOException { String source = "WooPDeDoO!" + NEWLINE + "GooRanga!" + NEWLINE + " plIng! "; sourceReader = new StringReader(source); @@ -115,12 +98,27 @@ doctypeReader.replaceDoctype(buf, "ni", "shrubbery")); } - public test_DoctypeReader(String name) { - super(name); + private static String readFully(DoctypeReader reader) + throws IOException { + StringBuffer buf = new StringBuffer(); + char[] ch = new char[1024]; + int numChars; + while ((numChars = reader.read(ch))!=-1) { + buf.append(ch, 0, numChars); + } + return buf.toString(); } - public static TestSuite suite() { - return new TestSuite(test_DoctypeReader.class); + protected void assertEquals(String expected, String input, String docType, + String systemId) throws IOException { + DoctypeReader doctypeReader = + new DoctypeReader(new StringReader(expected), docType, + systemId); + assertEquals(expected, readFully(doctypeReader)); } + + public test_DoctypeReader(String name) { + super(name); + } } Added: trunk/xmlunit/tests/java/org/custommonkey/xmlunit/util/test_IntegerBuffer.java =================================================================== --- trunk/xmlunit/tests/java/org/custommonkey/xmlunit/util/test_IntegerBuffer.java (rev 0) +++ trunk/xmlunit/tests/java/org/custommonkey/xmlunit/util/test_IntegerBuffer.java 2007-03-30 03:50:01 UTC (rev 164) @@ -0,0 +1,168 @@ +/* +****************************************************************** +Copyright (c) 200, Jeff Martin, Tim Bacon +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.util; + +import junit.framework.TestCase; + +/** + * Tests for IntegerBuffer + */ +public class test_IntegerBuffer extends TestCase { + + public void testToArrayEmpty() { + assertNotNull((new IntegerBuffer()).toIntArray()); + assertEquals(0, (new IntegerBuffer()).toIntArray().length); + } + + public void testSingleIntAppend() { + IntegerBuffer b = new IntegerBuffer(); + b.append(1); + assertNotNull(b.toIntArray()); + assertEquals(1, b.toIntArray().length); + assertEquals(1, b.toIntArray()[0]); + } + + public void testArrayAppend() { + IntegerBuffer b = new IntegerBuffer(); + b.append(new int[] {1, 2}); + assertNotNull(b.toIntArray()); + assertEquals(2, b.toIntArray().length); + for (int i = 0; i < 2; i++) { + assertEquals(i + 1, b.toIntArray()[i]); + } + } + + public void testSingleIntAppendWithGrowth() { + IntegerBuffer b = new IntegerBuffer(1); + for (int i = 0; i < 2; i++) { + b.append(i); + } + assertNotNull(b.toIntArray()); + assertEquals(2, b.toIntArray().length); + for (int i = 0; i < 2; i++) { + assertEquals(i, b.toIntArray()[i]); + } + } + + public void testArrayAppendWithGrowth() { + IntegerBuffer b = new IntegerBuffer(1); + b.append(new int[] {1, 2}); + assertNotNull(b.toIntArray()); + assertEquals(2, b.toIntArray().length); + for (int i = 0; i < 2; i++) { + assertEquals(i + 1, b.toIntArray()[i]); + } + } + + public void testSize() { + IntegerBuffer b = new IntegerBuffer(); + assertEquals(0, b.size()); + b.append(0); + assertEquals(1, b.size()); + b.append(new int[] {1, 2}); + assertEquals(3, b.size()); + } + + public void testCapacity() { + IntegerBuffer b = new IntegerBuffer(1); + assertEquals(1, b.capacity()); + b.append(0); + assertEquals(1, b.capacity()); + b.append(0); + assertTrue(b.capacity() > 1); + } + + public void testIndexOfSimple() { + IntegerBuffer b = new IntegerBuffer(); + int[] test = new int[] {1, 2, 3}; + assertEquals(-1, b.indexOf(test)); + b.append(test); + assertEquals(0, b.indexOf(test)); + b.append(test); + assertEquals(0, b.indexOf(test)); + } + + public void testIndexOfWithOffset() { + IntegerBuffer b = new IntegerBuffer(); + int[] test = new int[] {1, 2, 3}; + b.append(0); + assertEquals(-1, b.indexOf(test)); + b.append(test); + assertEquals(1, b.indexOf(test)); + } + + public void testIndexOfWithRepeatedInts() { + IntegerBuffer b = new IntegerBuffer(); + int[] test = new int[] {1, 2, 3}; + b.append(1); + assertEquals(-1, b.indexOf(test)); + b.append(test); + assertEquals(1, b.indexOf(test)); + } + + public void testIndexOfSupSequenceIsThere() { + IntegerBuffer b = new IntegerBuffer(); + int[] test = new int[] {1, 2, 3}; + b.append(new int[] {1, 2}); + b.append(4); + assertEquals(-1, b.indexOf(test)); + } + + public void testAllBytes() { + IntegerBuffer buf = new IntegerBuffer(); + for (byte b = Byte.MIN_VALUE; b < Byte.MAX_VALUE; b++) { + buf.append(b); + } + buf.append(Byte.MAX_VALUE); + int[] is = buf.toIntArray(); + for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++) { + assertEquals((byte) i, is[i + Math.abs(Byte.MIN_VALUE)]); + } + } + + public void testAllChars() { + IntegerBuffer buf = new IntegerBuffer(); + for (char c = Character.MIN_VALUE; c < Character.MAX_VALUE; c++) { + buf.append(c); + } + buf.append(Character.MAX_VALUE); + int[] is = buf.toIntArray(); + for (int i = Character.MIN_VALUE; i <= Character.MAX_VALUE; i++) { + assertEquals((char) i, is[i + Math.abs(Character.MIN_VALUE)]); + } + } +} \ No newline at end of file Property changes on: trunk/xmlunit/tests/java/org/custommonkey/xmlunit/util/test_IntegerBuffer.java ___________________________________________________________________ Name: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2007-03-29 07:19:42
|
Revision: 163 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=163&view=rev Author: bodewig Date: 2007-03-29 00:19:41 -0700 (Thu, 29 Mar 2007) Log Message: ----------- test_XMLTestCase behaves now, can run in same VM as other tests Modified Paths: -------------- trunk/xmlunit/build.xml Modified: trunk/xmlunit/build.xml =================================================================== --- trunk/xmlunit/build.xml 2007-03-28 16:19:54 UTC (rev 162) +++ trunk/xmlunit/build.xml 2007-03-29 07:19:41 UTC (rev 163) @@ -80,11 +80,6 @@ <exclude name="**/jaxp13/**" unless="jaxp13+.impl"/> </fileset> </batchtest> - <batchtest fork="yes" todir="${test.report.dir}"> - <fileset dir="${test.dir}/java"> - <include name="**/test_XMLTestCase.java"/> - </fileset> - </batchtest> </junit> <junitreport todir="${test.report.dir}"> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2007-03-28 16:19:53
|
Revision: 162 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=162&view=rev Author: bodewig Date: 2007-03-28 09:19:54 -0700 (Wed, 28 Mar 2007) Log Message: ----------- typos Modified Paths: -------------- trunk/xmlunit/src/site/XMLUnit-Java.xml Modified: trunk/xmlunit/src/site/XMLUnit-Java.xml =================================================================== --- trunk/xmlunit/src/site/XMLUnit-Java.xml 2007-03-28 16:19:23 UTC (rev 161) +++ trunk/xmlunit/src/site/XMLUnit-Java.xml 2007-03-28 16:19:54 UTC (rev 162) @@ -876,7 +876,7 @@ <literal>XMLUnit.getControlDocumentBuilderFactory</literal>, <literal>XMLUnit.getTestDocumentBuilderFactory</literal> and <literal>XMLUnit.getSAXParserFactory</literal> (used by - Validator). Not that all these methods return factories or + Validator). Note that all these methods return factories or parsers that are namespace aware.</para> <para>The various <literal>build...</literal> methods in @@ -949,9 +949,9 @@ <literal>InputSource</literal> allows you to read from arbitrary <literal>InputStream</literal>s or <literal>Reader</literal>s. Use an - <literal>InputStream</literal> wrapped into an + <literal>InputStream</literal> wrapped by an <literal>InputSource</literal> if you want the XML parser to - pick the proper encoding from the XML declaration.</para> + pick up the proper encoding from the XML declaration.</para> </listitem> <listitem>A <literal>String</literal>. @@ -962,7 +962,7 @@ whether the input is a control or test piece of XML.</para> <para>Note that using a <literal>String</literal> assumes - that you XML has already been converted from its XML + that your XML has already been converted from its XML encoding to a Java <literal>String</literal> upfront.</para> </listitem> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2007-03-28 16:19:24
|
Revision: 161 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=161&view=rev Author: bodewig Date: 2007-03-28 09:19:23 -0700 (Wed, 28 Mar 2007) Log Message: ----------- I know this fails for some documents with DOCTYPEs, commit it now anyway: refactor Validator support for InputStreams Modified Paths: -------------- trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeReader.java trunk/xmlunit/src/java/org/custommonkey/xmlunit/Validator.java Added Paths: ----------- trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeConstants.java trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeInputStream.java trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeSupport.java trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DoctypeInputStream.java Added: trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeConstants.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeConstants.java (rev 0) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeConstants.java 2007-03-28 16:19:23 UTC (rev 161) @@ -0,0 +1,45 @@ +/* +****************************************************************** +Copyright (c) 2001, Jeff Martin, Tim Bacon +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; + +interface DoctypeConstants { + String DOCTYPE_OPEN_DECL = "<!"; + int DECL_LENGTH = DOCTYPE_OPEN_DECL.length(); + String DOCTYPE_CLOSE_DECL = ">"; + String DOCTYPE = "DOCTYPE "; + String SYSTEM = " SYSTEM \""; +} \ No newline at end of file Property changes on: trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeConstants.java ___________________________________________________________________ Name: svn:executable + * Name: svn:eol-style + native Added: trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeInputStream.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeInputStream.java (rev 0) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeInputStream.java 2007-03-28 16:19:23 UTC (rev 161) @@ -0,0 +1,216 @@ +/* +****************************************************************** +Copyright (c) 2001, Jeff Martin, Tim Bacon +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; + +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.IOException; + +/** + * Adapts the marked-up content in a source InputStream to specify that it + * conforms to a different DTD. + * Combines InputStream semantics with the ability to specify a target doctype + * for a byte stream containing XML markup. + * Used by Validator class to wrap an InputStrea, when performing validation of a + * document against a DTD. + * <br />Examples and more at <a href="http://xmlunit.sourceforge.net"/>xmlunit.sourceforge.net</a> + */ +public class DoctypeInputStream extends InputStream { + private final InputStream wrappedStream; + + private static final byte[] DOCTYPE_BYTES = { + 'D', 'O', 'C', 'T', 'Y', 'P', 'E', ' ' + }; + + private byte[] readAheadBeforeDeclBuffer = null; + private int readAheadBeforeDeclOffset = 0; + private byte[] readAheadAfterDeclBuffer = null; + private int readAheadAfterDeclOffset = 0; + + private final DoctypeSupport docType; + private boolean writeDecl = false; + + + /** + * Create an InputStream whose XML content is provided by the + * originalSource with the exception of the DOCTYPE which is + * provided by the doctypeName and systemID. + * @param originalSource + * @param doctypeName + * @param systemID + */ + public DoctypeInputStream(InputStream originalSource, String doctypeName, + String systemID) { + wrappedStream = originalSource instanceof BufferedInputStream + ? originalSource : new BufferedInputStream(originalSource); + docType = new DoctypeSupport(doctypeName, systemID); + } + + /** + * Read DOCTYPE-replaced content from the wrapped Reader + */ + public int read() throws IOException { + int nextByte = -1; + + if (writeDecl) { + // currently writing our own DOCTYPE declaration + nextByte = docType.read(); + if (nextByte == -1) { + writeDecl = false; + } else { + return nextByte; + } + } + + if (readAheadBeforeDeclBuffer != null) { + // in part of original document before our DOCTYPE - this + // has already been read + nextByte = readAheadBeforeDeclBuffer[readAheadBeforeDeclOffset++]; + if (readAheadBeforeDeclOffset >= readAheadBeforeDeclBuffer.length) { + readAheadBeforeDeclBuffer = null; + writeDecl = true; + } + } else if (!docType.hasBeenRead()) { + // DOCTYPE not written, yet, need to see where it should go + + // read ahead until we find a good place to insert the doctype, + // store bytes in readAheadBuffers + ByteArrayOutputStream beforeDecl = new ByteArrayOutputStream(); + ByteArrayOutputStream afterDecl = new ByteArrayOutputStream(); + int current; + boolean ready = false; + while (!ready && (current = wrappedStream.read()) != -1) { + byte c = (byte) current; + if (c >= 0 && Character.isWhitespace((char) c)) { + beforeDecl.write(c); + } else if (c == '<') { + // could be XML declaration, comment, PI, DOCTYPE + // or the first element + byte[] elementOrDeclOr = readUntilCloseCharacterIsReached(); + if (elementOrDeclOr.length > 0) { + if (elementOrDeclOr[0] == '?') { + // XML declaration or PI + beforeDecl.write('<'); + beforeDecl.write(elementOrDeclOr, 0, + elementOrDeclOr.length); + } else if (elementOrDeclOr[0] != '!') { + // first element + afterDecl.write('<'); + afterDecl.write(elementOrDeclOr, 0, + elementOrDeclOr.length); + ready = true; + } else { + // comment or doctype + if (indexOfDoctype(elementOrDeclOr) == -1) { + afterDecl.write('<'); + afterDecl.write(elementOrDeclOr, 0, + elementOrDeclOr.length); + } // else swallow old declaration + ready = true; + } + } + + } else { + afterDecl.write(c); + ready = true; + } + } + readAheadBeforeDeclBuffer = beforeDecl.size() > 0 + ? beforeDecl.toByteArray() : null; + readAheadAfterDeclBuffer = afterDecl.size() > 0 + ? afterDecl.toByteArray() : null; + writeDecl = (readAheadBeforeDeclBuffer == null); + return read(); + } else if (readAheadAfterDeclBuffer != null) { + // in part of original document read ahead after our DOCTYPE + nextByte = readAheadAfterDeclBuffer[readAheadAfterDeclOffset++]; + if (readAheadAfterDeclOffset >= readAheadAfterDeclBuffer.length) { + readAheadAfterDeclBuffer = null; + } + } else { + nextByte = wrappedStream.read(); + } + return nextByte; + } + + private byte[] readUntilCloseCharacterIsReached() throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + int byteRead = -1; + int openCount = 1; + while (openCount > 0 && (byteRead = wrappedStream.read()) != -1) { + byte c = (byte) byteRead; + baos.write(c); + if (c == '<') { + openCount++; + } + if (c == '>') { + openCount--; + } + } + return baos.toByteArray(); + } + + public void close() throws IOException { + wrappedStream.close(); + } + + /** + * Could be faster when searching from the other end, but should do. + */ + private static int indexOfDoctype(byte[] b) { + int index = -1; + for (int i = 0; i < b.length - DOCTYPE_BYTES.length + 1; i++) { + if (b[i] == DOCTYPE_BYTES[0]) { + boolean found = false; + int j = 1; + for (; !found && j < DOCTYPE_BYTES.length; j++) { + if (b[i + j] != DOCTYPE_BYTES[j]) { + found = true; + } + } + if (found) { + index = i; + break; + } else { + i += j - 1; + } + } + } + return index; + } +} \ No newline at end of file Property changes on: trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeInputStream.java ___________________________________________________________________ Name: svn:executable + * Name: svn:eol-style + native Modified: trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeReader.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeReader.java 2007-03-28 04:10:28 UTC (rev 160) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeReader.java 2007-03-28 16:19:23 UTC (rev 161) @@ -38,10 +38,7 @@ import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; import java.io.Reader; -import java.io.StringReader; /** * Adapts the marked-up content in a source Reader to specify that it @@ -52,19 +49,19 @@ * document against a DTD. * <br />Examples and more at <a href="http://xmlunit.sourceforge.net"/>xmlunit.sourceforge.net</a> */ -public class DoctypeReader extends Reader { - private static final String DOCTYPE_OPEN_DECL = "<!"; - private static final int DECL_LENGTH = DOCTYPE_OPEN_DECL.length(); - private static final String DOCTYPE_CLOSE_DECL = ">"; - private static final String DOCTYPE = "DOCTYPE "; - private static final String SYSTEM = " SYSTEM \""; - private final Reader originalSource; +public class DoctypeReader extends Reader implements DoctypeConstants { + + private final Reader originalReader; private final StringBuffer sourceBuffer = new StringBuffer(1024); - private final String doctypeName; - private final String systemId; - private Reader replacementReader; + private char[] readAheadBeforeDeclBuffer = null; + private int readAheadBeforeDeclOffset = 0; + private char[] readAheadAfterDeclBuffer = null; + private int readAheadAfterDeclOffset = 0; + private final DoctypeSupport docType; + private boolean writeDecl = false; + /** * Create a Reader whose XML content is provided by the originalSource with * the exception of the DOCTYPE which is provided by the doctypeName @@ -75,44 +72,20 @@ */ public DoctypeReader(Reader originalSource, String doctypeName, String systemID) { - this.originalSource = originalSource; - this.doctypeName = doctypeName; - this.systemId = systemID; + originalReader = originalSource instanceof BufferedReader + ? originalSource : new BufferedReader(originalSource); + docType = new DoctypeSupport(doctypeName, systemID); } /** - * Create a Reader whose XML content is provided by the originalSource with - * the exception of the DOCTYPE which is provided by the doctypeName - * and systemID. - * @param originalSource - * @param doctypeName - * @param systemID - */ - public DoctypeReader(InputStream originalSource, String encoding, - String doctypeName, String systemID) - throws IOException { - this(encoding != null - ? new InputStreamReader(originalSource, encoding) - : xmlStreamToReader(originalSource), - doctypeName, systemID); - } - - // XXX - we are cheating here, we should read into the source - // stream to see whether the XML decl (if any) specifies the - // encoding and then return an InputStreamReader using the proper - // encoding - private static Reader xmlStreamToReader(InputStream originalSource) - throws IOException { - return new InputStreamReader(originalSource); - } - - /** * @return the content of the original source, without amendments or * substitutions. Safe to call multiple times. * @throws IOException if thrown while reading from the original source + * @deprecated this method is only here for BWC, it is no longer + * used by this class */ protected String getContent() throws IOException { - return getContent(originalSource).toString(); + return obsoleteGetContent(originalReader).toString(); } /** @@ -120,7 +93,8 @@ * @return the contents of the originalSource within a StringBuffer * @throws IOException if thrown while reading from the original source */ - private StringBuffer getContent(Reader originalSource) throws IOException { + private StringBuffer obsoleteGetContent(Reader originalSource) + throws IOException { if (sourceBuffer.length() == 0) { BufferedReader bufferedReader; if (originalSource instanceof BufferedReader) { @@ -152,7 +126,7 @@ * @param withinContent * @return */ - private int findStartDoctype(StringBuffer withinContent) { + private int obsoleteFindStartDoctype(StringBuffer withinContent) { int startAt = -1; char curChar; boolean canInsert = true; @@ -183,6 +157,8 @@ * @param doctypeName * @param systemId * @return the content, after DOCTYPE amendment / addition + * @deprecated this method is only here for BWC, it is no longer + * used by this class */ public String replaceDoctype(StringBuffer withinContent, String doctypeName, String systemId) { @@ -190,7 +166,7 @@ int startDoctype = content.indexOf(DOCTYPE); boolean noCurrentDoctype = false; if (startDoctype == -1) { - startDoctype = findStartDoctype(withinContent); + startDoctype = obsoleteFindStartDoctype(withinContent); noCurrentDoctype = true; } @@ -227,18 +203,6 @@ } /** - * Wrap the DOCTYPE-replaced content in a StringReader - * @return a StringReader from which the DOCTYPE-replaced content can be read - * @throws IOException - */ - private Reader getReplacementReader() throws IOException { - StringBuffer originalContent = getContent(originalSource); - String replacedContent = replaceDoctype(originalContent, - doctypeName, systemId); - return new StringReader(replacedContent); - } - - /** * Read DOCTYPE-replaced content from the wrapped Reader * @param cbuf * @param off @@ -248,17 +212,115 @@ * @throws IOException */ public int read(char cbuf[], int off, int len) throws IOException { - if (replacementReader == null) { - replacementReader = getReplacementReader(); + int startPos = off; + int currentlyRead; + while (off - startPos < len && (currentlyRead = read()) != -1) { + cbuf[off++] = (char) currentlyRead; } - return replacementReader.read(cbuf, off, len); + return off == startPos && len != 0 ? -1 : off - startPos; } /** - * Close the wrapped Reader - * @throws IOException + * Read DOCTYPE-replaced content from the wrapped Reader */ + public int read() throws IOException { + int nextChar = -1; + + if (writeDecl) { + // currently writing our own DOCTYPE declaration + nextChar = docType.read(); + if (nextChar == -1) { + writeDecl = false; + } else { + return nextChar; + } + } + + if (readAheadBeforeDeclBuffer != null) { + // in part of original document before our DOCTYPE - this + // has already been read + nextChar = readAheadBeforeDeclBuffer[readAheadBeforeDeclOffset++]; + if (readAheadBeforeDeclOffset >= readAheadBeforeDeclBuffer.length) { + readAheadBeforeDeclBuffer = null; + writeDecl = true; + } + } else if (!docType.hasBeenRead()) { + // DOCTYPE not written, yet, need to see where it should go + + // read ahead until we find a good place to insert the doctype, + // store characters in readAheadBuffers + StringBuffer beforeDecl = new StringBuffer(); + StringBuffer afterDecl = new StringBuffer(); + int current; + boolean ready = false; + while (!ready && (current = originalReader.read()) != -1) { + char c = (char) current; + if (Character.isWhitespace(c)) { + beforeDecl.append(c); + } else if (c == '<') { + // could be XML declaration, comment, PI, DOCTYPE + // or the first element + String elementOrDeclOr = readUntilCloseCharacterIsReached(); + if (elementOrDeclOr.length() > 0) { + if (elementOrDeclOr.charAt(0) == '?') { + // XML declaration or PI + beforeDecl.append('<').append(elementOrDeclOr); + } else if (elementOrDeclOr.charAt(0) != '!') { + // first element + afterDecl.append('<').append(elementOrDeclOr); + ready = true; + } else { + // comment or doctype + if (elementOrDeclOr.indexOf(DOCTYPE) == -1) { + afterDecl.append('<').append(elementOrDeclOr); + } // else swallow old declaration + ready = true; + } + } + + } else { + afterDecl.append(c); + ready = true; + } + } + readAheadBeforeDeclBuffer = beforeDecl.length() > 0 + ? beforeDecl.toString().toCharArray() + : null; + readAheadAfterDeclBuffer = afterDecl.length() > 0 + ? afterDecl.toString().toCharArray() + : null; + writeDecl = (readAheadBeforeDeclBuffer == null); + return read(); + } else if (readAheadAfterDeclBuffer != null) { + // in part of original document read ahead after our DOCTYPE + nextChar = readAheadAfterDeclBuffer[readAheadAfterDeclOffset++]; + if (readAheadAfterDeclOffset >= readAheadAfterDeclBuffer.length) { + readAheadAfterDeclBuffer = null; + } + } else { + nextChar = originalReader.read(); + } + return nextChar; + } + + private String readUntilCloseCharacterIsReached() throws IOException { + StringBuffer sb = new StringBuffer(); + int characterRead = -1; + int openCount = 1; + while (openCount > 0 && (characterRead = originalReader.read()) != -1) { + char c = (char) characterRead; + sb.append(c); + if (c == '<') { + openCount++; + } + if (c == '>') { + openCount--; + } + } + return sb.toString(); + } + public void close() throws IOException { - replacementReader.close(); + originalReader.close(); } } Added: trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeSupport.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeSupport.java (rev 0) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeSupport.java 2007-03-28 16:19:23 UTC (rev 161) @@ -0,0 +1,74 @@ +/* +****************************************************************** +Copyright (c) 2001, Jeff Martin, Tim Bacon +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; + +/** + * Contains some common code for DoctypeReader and DoctypeInputStream. + * + * <p>When used with DoctypeInputStream it assumes that the whole + * DOCTYPE declaration consists of US-ASCII characters.</p> + */ +final class DoctypeSupport implements DoctypeConstants { + + private final String decl; + private int offset = 0; + + /** + * Encapsulates a DOCTYPE declaration for the given name and system id. + */ + DoctypeSupport(String name, String systemId) { + StringBuffer sb = new StringBuffer(DOCTYPE_OPEN_DECL); + sb.append(DOCTYPE).append(name).append(SYSTEM) + .append(systemId).append("\"").append(DOCTYPE_CLOSE_DECL); + decl = sb.toString(); + } + + /** + * Whether anybody has started to read the declaration. + */ + boolean hasBeenRead() { + return offset != 0; + } + + /** + * Reads the next character from the declaration. + * @return -1 if the end of the declaration has been reached. + */ + int read() { + return offset >= decl.length() ? -1 : decl.charAt(offset++); + } +} \ No newline at end of file Property changes on: trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeSupport.java ___________________________________________________________________ Name: svn:executable + * Name: svn:eol-style + native Modified: trunk/xmlunit/src/java/org/custommonkey/xmlunit/Validator.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/Validator.java 2007-03-28 04:10:28 UTC (rev 160) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/Validator.java 2007-03-28 16:19:23 UTC (rev 161) @@ -251,14 +251,15 @@ */ public Validator(InputSource sourceForValidation, String systemID, String doctype) - throws SAXException, IOException, ConfigurationException { + throws SAXException, ConfigurationException { this(sourceForValidation.getCharacterStream() != null - ? new DoctypeReader(sourceForValidation.getCharacterStream(), - doctype, systemID) - : new DoctypeReader(sourceForValidation.getByteStream(), - sourceForValidation.getEncoding(), - doctype, systemID), - systemID); + ? new InputSource(new DoctypeReader(sourceForValidation + .getCharacterStream(), + doctype, systemID)) + : new InputSource(new DoctypeInputStream(sourceForValidation + .getByteStream(), + doctype, systemID)), + systemID, true); } /** @@ -380,8 +381,8 @@ isValid = Boolean.TRUE; } else if (usingDoctypeReader) { try { - messages.append("\nContent was: ").append(((DoctypeReader) - validationInputSource.getCharacterStream()).getContent()); + messages.append("\nContent was: ") + .append(readFully(validationInputSource)); } catch (IOException e) { // silent but deadly? } @@ -490,4 +491,31 @@ parser.setProperty(JAXPConstants.Properties.SCHEMA_SOURCE, schemaSource); } + + private static String readFully(InputSource s) throws IOException { + return s.getCharacterStream() != null + ? readFully(s.getCharacterStream()) : readFully(s.getByteStream()); + } + + private static String readFully(Reader r) throws IOException { + StringBuffer sb = new StringBuffer(); + char[] buffer = new char[4096]; + int charsRead = -1; + while ((charsRead = r.read(buffer)) > -1) { + sb.append(buffer, 0, charsRead); + } + return sb.toString(); + } + + private static String readFully(java.io.InputStream is) throws IOException { + java.io.ByteArrayOutputStream baos = + new java.io.ByteArrayOutputStream(); + byte[] buffer = new byte[8192]; + int bytesRead = -1; + while ((bytesRead = is.read(buffer)) > -1) { + baos.write(buffer, 0, bytesRead); + } + return new String(baos.toByteArray()); + } + } Added: trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DoctypeInputStream.java =================================================================== --- trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DoctypeInputStream.java (rev 0) +++ trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DoctypeInputStream.java 2007-03-28 16:19:23 UTC (rev 161) @@ -0,0 +1,142 @@ +/* +****************************************************************** +Copyright (c) 200, Jeff Martin, Tim Bacon +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; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; + +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * JUnit test for DoctypeInputStream + */ +public class test_DoctypeInputStream extends TestCase { + + private static final String NEWLINE = System.getProperty("line.separator"); + private static final String NO_DTD = "<document><element>one</element></document>"; + private File testFile; + + public void tearDown() { + if (testFile != null) { + testFile.delete(); + } + } + + private FileInputStream testDocument(String content) + throws IOException { + testFile = File.createTempFile("xmlunit_", ".xml"); + FileOutputStream fos = new FileOutputStream(testFile); + OutputStreamWriter w = new OutputStreamWriter(fos, "ISO-8859-1"); + w.write(content); + w.close(); + + return new FileInputStream(testFile); + } + + private static String readFully(DoctypeInputStream dis) + throws IOException { + StringBuffer buf = new StringBuffer(); + char[] ch = new char[1024]; + int numChars; + InputStreamReader reader = + new InputStreamReader(dis, "ISO-8859-1"); + while ((numChars = reader.read(ch))!=-1) { + buf.append(ch, 0, numChars); + } + return buf.toString(); + } + + private void assertEquals(String expected, String input, String docType, + String systemId) throws IOException { + FileInputStream fis = null; + try { + fis = testDocument(input); + DoctypeInputStream doctypeInputStream = + new DoctypeInputStream(fis, docType, systemId); + + assertEquals(expected, readFully(doctypeInputStream)); + } finally { + if (fis != null) { + fis.close(); + } + } + } + + public void testRead() throws IOException { + String oz = "Chirurgische Verbesserungen sind g\u00fcnstig"; + assertEquals("<!DOCTYPE Kylie SYSTEM \"bumJob\">" + oz, + oz, "Kylie", "bumJob"); + } + + public void testReplaceDoctypeInternalDTD() throws IOException { + assertEquals("<!DOCTYPE ni SYSTEM \"shrubbery\">", + test_Constants.CHUCK_JONES_RIP_DTD_DECL, "ni", + "shrubbery"); + } + + public void XtestReplaceDoctypeExternalDTD() throws IOException { + assertEquals("<!DOCTYPE ni SYSTEM \"shrubbery\">", + "<! DOCTYPE PUBLIC \"yak\" SYSTEM \"llama\">", "ni", + "shrubbery"); + } + + public void testReplaceDoctypeNoDTD() throws IOException { + assertEquals("<!DOCTYPE ni SYSTEM \"shrubbery\">" + NO_DTD, + NO_DTD, "ni", "shrubbery"); + } + + public void testReplaceDoctypeNoDTDButXMLDecl() throws IOException { + assertEquals(test_Constants.XML_DECLARATION + + "<!DOCTYPE ni SYSTEM \"shrubbery\">" + NO_DTD, + test_Constants.XML_DECLARATION + NO_DTD, + "ni", "shrubbery"); + } + + public test_DoctypeInputStream(String name) { + super(name); + } + + public static TestSuite suite() { + return new TestSuite(test_DoctypeInputStream.class); + } +} + Property changes on: trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_DoctypeInputStream.java ___________________________________________________________________ Name: svn:executable + * Name: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2007-03-28 04:10:27
|
Revision: 160 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=160&view=rev Author: bodewig Date: 2007-03-27 21:10:28 -0700 (Tue, 27 Mar 2007) Log Message: ----------- Add information on URIResolver and InputSource Modified Paths: -------------- trunk/xmlunit/src/site/XMLUnit-Java.xml Modified: trunk/xmlunit/src/site/XMLUnit-Java.xml =================================================================== --- trunk/xmlunit/src/site/XMLUnit-Java.xml 2007-03-28 04:07:35 UTC (rev 159) +++ trunk/xmlunit/src/site/XMLUnit-Java.xml 2007-03-28 04:10:28 UTC (rev 160) @@ -752,6 +752,10 @@ of XMLUnit's machinery. Examples can be found in <xref linkend="transform-intro"/>.</para> + <para>It is possible to provide a custom + <literal>javax.xml.transform.URIResolver</literal> via the + <literal>XMLUnit.setURIResolver</literal> method.</para> + <para>You can access the underlying XSLT transformer via <literal>XMLUnit.getTransformerFactory</literal>.</para> </section> @@ -872,8 +876,11 @@ <literal>XMLUnit.getControlDocumentBuilderFactory</literal>, <literal>XMLUnit.getTestDocumentBuilderFactory</literal> and <literal>XMLUnit.getSAXParserFactory</literal> (used by - Validator). The various <literal>build...</literal> methods - in <literal>XMLUnit</literal> provide convenience layers for + Validator). Not that all these methods return factories or + parsers that are namespace aware.</para> + + <para>The various <literal>build...</literal> methods in + <literal>XMLUnit</literal> provide convenience layers for building DOM <literal>Document</literal>s using the configured parsers.</para> @@ -907,6 +914,15 @@ <para>Using <literal>XMLUnit.setIgnoreWhitespace</literal> it is possible to make the test and control parser ignore this kind of whitespace.</para> + + <para>Note that setting this property to + <literal>true</literal> usually doesn't have any effect since + it only works on validating parsers and XMLUnit doesn't enable + validation by default. It does have an effect when comparing + pieces of XML, though, since the same flag is used for a + different purpose as well in that case. See <xref + linkend="comparing-config"/> for more details.</para> + </section> </section> @@ -927,12 +943,27 @@ <literal>Transform</literal> class.</para> </listitem> + <listitem>A SAX <literal>InputSource</literal>. + + <para>This is the most generic way since + <literal>InputSource</literal> allows you to read from + arbitrary <literal>InputStream</literal>s or + <literal>Reader</literal>s. Use an + <literal>InputStream</literal> wrapped into an + <literal>InputSource</literal> if you want the XML parser to + pick the proper encoding from the XML declaration.</para> + </listitem> + <listitem>A <literal>String</literal>. <para>Here a DOM <literal>Document</literal> is built from the input <literal>String</literal> using the JAXP parser specified for control or test documents - depending on whether the input is a control or test piece of XML.</para> + + <para>Note that using a <literal>String</literal> assumes + that you XML has already been converted from its XML + encoding to a Java <literal>String</literal> upfront.</para> </listitem> <listitem>A <literal>Reader</literal>. @@ -1110,6 +1141,14 @@ </itemizedlist> </listitem> + <listitem>It is now possible to provide a custom + <literal>javax.xml.transform.URIResolver</literal> for + transformations.</listitem> + + <listitem>New overloads have been added that allow + <literal>org.xml.sax.InputSource</literal> to be used as a + "piece of XML" in many classes.</listitem> + <listitem> <para>A new package <literal>org.custommonkey.xmlunit.examples</literal> has This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bo...@us...> - 2007-03-28 04:07:35
|
Revision: 159 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=159&view=rev Author: bodewig Date: 2007-03-27 21:07:35 -0700 (Tue, 27 Mar 2007) Log Message: ----------- More overrides that allow InputSource as source Modified Paths: -------------- trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeReader.java trunk/xmlunit/src/java/org/custommonkey/xmlunit/Validator.java trunk/xmlunit/src/java/org/custommonkey/xmlunit/XMLAssert.java trunk/xmlunit/src/java/org/custommonkey/xmlunit/XMLTestCase.java trunk/xmlunit/src/java/org/custommonkey/xmlunit/XMLUnit.java trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_Validator.java Modified: trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeReader.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeReader.java 2007-03-28 04:06:22 UTC (rev 158) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/DoctypeReader.java 2007-03-28 04:07:35 UTC (rev 159) @@ -38,6 +38,8 @@ import java.io.BufferedReader; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.io.Reader; import java.io.StringReader; @@ -79,6 +81,32 @@ } /** + * Create a Reader whose XML content is provided by the originalSource with + * the exception of the DOCTYPE which is provided by the doctypeName + * and systemID. + * @param originalSource + * @param doctypeName + * @param systemID + */ + public DoctypeReader(InputStream originalSource, String encoding, + String doctypeName, String systemID) + throws IOException { + this(encoding != null + ? new InputStreamReader(originalSource, encoding) + : xmlStreamToReader(originalSource), + doctypeName, systemID); + } + + // XXX - we are cheating here, we should read into the source + // stream to see whether the XML decl (if any) specifies the + // encoding and then return an InputStreamReader using the proper + // encoding + private static Reader xmlStreamToReader(InputStream originalSource) + throws IOException { + return new InputStreamReader(originalSource); + } + + /** * @return the content of the original source, without amendments or * substitutions. Safe to call multiple times. * @throws IOException if thrown while reading from the original source Modified: trunk/xmlunit/src/java/org/custommonkey/xmlunit/Validator.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/Validator.java 2007-03-28 04:06:22 UTC (rev 158) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/Validator.java 2007-03-28 04:07:35 UTC (rev 159) @@ -240,6 +240,29 @@ /** * Full constructor. + * Validates the contents of the InputSource using the DTD + * specified with the systemID and named with the doctype name. + * + * @param sourceForValidation + * @param systemID + * @param doctype + * @throws SAXException + * @throws ConfigurationException if validation could not be turned on + */ + public Validator(InputSource sourceForValidation, String systemID, + String doctype) + throws SAXException, IOException, ConfigurationException { + this(sourceForValidation.getCharacterStream() != null + ? new DoctypeReader(sourceForValidation.getCharacterStream(), + doctype, systemID) + : new DoctypeReader(sourceForValidation.getByteStream(), + sourceForValidation.getEncoding(), + doctype, systemID), + systemID); + } + + /** + * Full constructor. * Validates the contents of the Reader using the DTD specified with the * systemID and named with the doctype name. * @@ -249,9 +272,12 @@ * @throws SAXException * @throws ConfigurationException if validation could not be turned on */ - public Validator(Reader readerForValidation, String systemID, String doctype) + public Validator(Reader readerForValidation, String systemID, + String doctype) throws SAXException, ConfigurationException { - this(new DoctypeReader(readerForValidation, doctype, systemID), + this(readerForValidation instanceof DoctypeReader + ? readerForValidation + : new DoctypeReader(readerForValidation, doctype, systemID), systemID); } Modified: trunk/xmlunit/src/java/org/custommonkey/xmlunit/XMLAssert.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/XMLAssert.java 2007-03-28 04:06:22 UTC (rev 158) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/XMLAssert.java 2007-03-28 04:07:35 UTC (rev 159) @@ -49,6 +49,7 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -109,9 +110,7 @@ * @param assertion true if asserting that result is similar */ public static void assertXMLEqual(Diff diff, boolean assertion) { - if (assertion != diff.similar()) { - fail(diff.toString()); - } + assertXMLEqual(null, diff, assertion); } /** @@ -120,21 +119,28 @@ * @param diff the result of an XML comparison * @param assertion true if asserting that result is similar */ - public static void assertXMLEqual(String msg, Diff diff, boolean assertion) { + public static void assertXMLEqual(String msg, Diff diff, + boolean assertion) { if (assertion != diff.similar()) { - fail(msg + ", " + diff.toString()); + fail(getFailMessage(msg, diff)); } } + private static String getFailMessage(String msg, Diff diff) { + StringBuffer sb = new StringBuffer(); + if (msg != null && msg.length() > 0) { + sb.append(msg).append(", "); + } + return sb.append(diff.toString()).toString(); + } + /** * Assert that the result of an XML comparison is or is not identical * @param diff the result of an XML comparison * @param assertion true if asserting that result is identical */ public static void assertXMLIdentical(Diff diff, boolean assertion) { - if (assertion != diff.identical()) { - fail(diff.toString()); - } + assertXMLIdentical(null, diff, assertion); } /** @@ -156,7 +162,7 @@ */ public static void assertXMLIdentical(String msg, Diff diff, boolean assertion) { if (assertion != diff.identical()) { - fail(msg + ", " + diff.toString()); + fail(getFailMessage(msg, diff)); } } @@ -167,10 +173,21 @@ * @throws SAXException * @throws IOException */ + public static void assertXMLEqual(InputSource control, InputSource test) + throws SAXException, IOException { + assertXMLEqual(null, control, test); + } + + /** + * Assert that two XML documents are similar + * @param control XML to be compared against + * @param test XML to be tested + * @throws SAXException + * @throws IOException + */ public static void assertXMLEqual(String control, String test) throws SAXException, IOException { - Diff diff = new Diff(control, test); - assertXMLEqual(diff, true); + assertXMLEqual(null, control, test); } /** @@ -179,8 +196,7 @@ * @param test XML to be tested */ public static void assertXMLEqual(Document control, Document test) { - Diff diff = new Diff(control, test); - assertXMLEqual(diff, true); + assertXMLEqual(null, control, test); } /** @@ -192,8 +208,22 @@ */ public static void assertXMLEqual(Reader control, Reader test) throws SAXException, IOException { + assertXMLEqual(null, control, test); + } + + /** + * Assert that two XML documents are similar + * @param err Message to be displayed on assertion failure + * @param control XML to be compared against + * @param test XML to be tested + * @throws SAXException + * @throws IOException + */ + public static void assertXMLEqual(String err, InputSource control, + InputSource test) + throws SAXException, IOException { Diff diff = new Diff(control, test); - assertXMLEqual(diff, true); + assertXMLEqual(err, diff, true); } /** @@ -243,24 +273,21 @@ * @throws SAXException * @throws IOException */ - public static void assertXMLNotEqual(String control, String test) + public static void assertXMLNotEqual(InputSource control, InputSource test) throws SAXException, IOException { - Diff diff = new Diff(control, test); - assertXMLEqual(diff, false); + assertXMLNotEqual(null, control, test); } /** * Assert that two XML documents are NOT similar - * @param err Message to be displayed on assertion failure * @param control XML to be compared against * @param test XML to be tested * @throws SAXException * @throws IOException */ - public static void assertXMLNotEqual(String err, String control, String test) + public static void assertXMLNotEqual(String control, String test) throws SAXException, IOException { - Diff diff = new Diff(control, test); - assertXMLEqual(err, diff, false); + assertXMLNotEqual(null, control, test); } /** @@ -269,33 +296,48 @@ * @param test XML to be tested */ public static void assertXMLNotEqual(Document control, Document test) { - Diff diff = new Diff(control, test); - assertXMLEqual(diff, false); + assertXMLNotEqual(null, control, test); } /** * Assert that two XML documents are NOT similar + * @param control XML to be compared against + * @param test XML to be tested + * @throws SAXException + * @throws IOException + */ + public static void assertXMLNotEqual(Reader control, Reader test) + throws SAXException, IOException { + assertXMLNotEqual(null, control, test); + } + + /** + * Assert that two XML documents are NOT similar * @param err Message to be displayed on assertion failure * @param control XML to be compared against * @param test XML to be tested + * @throws SAXException + * @throws IOException */ - public static void assertXMLNotEqual(String err, Document control, - Document test) { + public static void assertXMLNotEqual(String err, InputSource control, + InputSource test) + throws SAXException, IOException { Diff diff = new Diff(control, test); assertXMLEqual(err, diff, false); } /** * Assert that two XML documents are NOT similar + * @param err Message to be displayed on assertion failure * @param control XML to be compared against * @param test XML to be tested * @throws SAXException * @throws IOException */ - public static void assertXMLNotEqual(Reader control, Reader test) + public static void assertXMLNotEqual(String err, String control, String test) throws SAXException, IOException { Diff diff = new Diff(control, test); - assertXMLEqual(diff, false); + assertXMLEqual(err, diff, false); } /** @@ -303,6 +345,18 @@ * @param err Message to be displayed on assertion failure * @param control XML to be compared against * @param test XML to be tested + */ + public static void assertXMLNotEqual(String err, Document control, + Document test) { + Diff diff = new Diff(control, test); + assertXMLEqual(err, diff, false); + } + + /** + * Assert that two XML documents are NOT similar + * @param err Message to be displayed on assertion failure + * @param control XML to be compared against + * @param test XML to be tested * @throws SAXException * @throws IOException */ @@ -326,6 +380,20 @@ } /** + * Assert that the node lists of two Xpaths in the same document are equal + * @param xpathOne + * @param xpathTwo + * @param document + * @see XpathEngine + */ + public static void assertXpathsEqual(String controlXpath, String testXpath, + InputSource document) + throws SAXException, IOException, XpathException { + assertXpathsEqual(controlXpath, testXpath, + XMLUnit.buildControlDocument(document)); + } + + /** * Assert that the node lists of two Xpaths in the same XML string are * equal * @param xpathOne @@ -342,6 +410,25 @@ } /** + * Assert that the node lists of two Xpaths in two documents are equal + * @param xpathOne + * @param xpathTwo + * @param controlDocument + * @param testDocument + * @see XpathEngine + */ + public static void assertXpathsEqual(String controlXpath, + InputSource controlDocument, + String testXpath, + InputSource testDocument) + throws SAXException, IOException, XpathException { + assertXpathsEqual(controlXpath, + XMLUnit.buildControlDocument(controlDocument), + testXpath, + XMLUnit.buildTestDocument(testDocument)); + } + + /** * Assert that the node lists of two Xpaths in two XML strings are equal * @param xpathOne * @param inControlXMLString @@ -365,7 +452,8 @@ * Assert that the node lists of two Xpaths in two documents are equal * @param xpathOne * @param xpathTwo - * @param document + * @param controlDocument + * @param testDocument * @see XpathEngine */ public static void assertXpathsEqual(String controlXpath, @@ -398,6 +486,21 @@ } /** + * Assert that the node lists of two Xpaths in the same document are NOT equal + * @param xpathOne + * @param xpathTwo + * @param document + * @see XpathEngine + */ + public static void assertXpathsNotEqual(String controlXpath, + String testXpath, + InputSource document) + throws SAXException, IOException, XpathException { + assertXpathsNotEqual(controlXpath, testXpath, + XMLUnit.buildControlDocument(document)); + } + + /** * Assert that the node lists of two Xpaths in the same XML string are NOT * equal * @param xpathOne @@ -435,6 +538,27 @@ } /** + * Assert that the node lists of two Xpaths in two XML strings are + * NOT equal + * @param xpathOne + * @param controlDocument + * @param xpathTwo + * @param testDocument + * @throws SAXException + * @throws IOException + */ + public static void assertXpathsNotEqual(String controlXpath, + InputSource controlDocument, + String testXpath, + InputSource testDocument) + throws SAXException, IOException, XpathException { + assertXpathsNotEqual(controlXpath, + XMLUnit.buildControlDocument(controlDocument), + testXpath, + XMLUnit.buildTestDocument(testDocument)); + } + + /** * Assert that the node lists of two Xpaths in two documents are NOT equal * @param xpathOne * @param xpathTwo @@ -475,6 +599,23 @@ * equal * @param xpathOne * @param xpathTwo + * @param document + * @throws SAXException + * @throws IOException + */ + public static void assertXpathValuesEqual(String controlXpath, + String testXpath, + InputSource document) + throws SAXException, IOException, XpathException { + assertXpathValuesEqual(controlXpath, testXpath, + XMLUnit.buildControlDocument(document)); + } + + /** + * Assert that the evaluation of two Xpaths in the same XML string are + * equal + * @param xpathOne + * @param xpathTwo * @param inXMLString * @throws SAXException * @throws IOException @@ -491,6 +632,26 @@ /** * Assert that the evaluation of two Xpaths in two XML strings are equal * @param xpathOne + * @param control + * @param xpathTwo + * @param test + * @throws SAXException + * @throws IOException + */ + public static void assertXpathValuesEqual(String controlXpath, + InputSource control, + String testXpath, + InputSource test) + throws SAXException, IOException, XpathException { + assertXpathValuesEqual(controlXpath, + XMLUnit.buildControlDocument(control), + testXpath, + XMLUnit.buildTestDocument(test)); + } + + /** + * Assert that the evaluation of two Xpaths in two XML strings are equal + * @param xpathOne * @param inControlXMLString * @param xpathTwo * @param inTestXMLString @@ -531,6 +692,23 @@ * NOT equal * @param xpathOne * @param xpathTwo + * @param control + * @throws SAXException + * @throws IOException + */ + public static void assertXpathValuesNotEqual(String controlXpath, + String testXpath, + InputSource control) + throws SAXException, IOException, XpathException { + assertXpathValuesNotEqual(controlXpath, testXpath, + XMLUnit.buildControlDocument(control)); + } + + /** + * Assert that the evaluation of two Xpaths in the same XML string are + * NOT equal + * @param xpathOne + * @param xpathTwo * @param inXMLString * @throws SAXException * @throws IOException @@ -562,10 +740,30 @@ * Assert that the evaluation of two Xpaths in two XML strings are * NOT equal * @param xpathOne + * @param control + * @param xpathTwo + * @param test + * @throws SAXException + * @throws IOException + */ + public static void assertXpathValuesNotEqual(String controlXpath, + InputSource control, + String testXpath, + InputSource test) + throws SAXException, IOException, XpathException { + assertXpathValuesNotEqual(controlXpath, + XMLUnit.buildControlDocument(control), + testXpath, + XMLUnit.buildTestDocument(test)); + } + + /** + * Assert that the evaluation of two Xpaths in two XML strings are + * NOT equal + * @param xpathOne * @param inControlXMLString * @param xpathTwo * @param inTestXMLString - * @param ctx * @throws SAXException * @throws IOException */ @@ -608,6 +806,24 @@ } /** + * Assert the value of an Xpath expression in an XML document. + * @param expectedValue + * @param xpathExpression + * @param control + * @throws SAXException + * @throws IOException + * @see XpathEngine which provides the underlying evaluation mechanism + */ + public static void assertXpathEvaluatesTo(String expectedValue, + String xpathExpression, + InputSource control) + throws SAXException, IOException, + XpathException { + Document document = XMLUnit.buildControlDocument(control); + assertXpathEvaluatesTo(expectedValue, xpathExpression, document); + } + + /** * Assert the value of an Xpath expression in an XML String * @param expectedValue * @param xpathExpression @@ -644,6 +860,19 @@ /** * Assert that a specific XPath exists in some given XML * @param inXpathExpression + * @param control + * @see XpathEngine which provides the underlying evaluation mechanism + */ + public static void assertXpathExists(String xPathExpression, + InputSource control) + throws IOException, SAXException, XpathException { + Document inDocument = XMLUnit.buildControlDocument(control); + assertXpathExists(xPathExpression, inDocument); + } + + /** + * Assert that a specific XPath exists in some given XML + * @param inXpathExpression * @param inXMLString * @see XpathEngine which provides the underlying evaluation mechanism */ @@ -674,6 +903,19 @@ /** * Assert that a specific XPath does NOT exist in some given XML * @param inXpathExpression + * @param control + * @see XpathEngine which provides the underlying evaluation mechanism + */ + public static void assertXpathNotExists(String xPathExpression, + InputSource control) + throws IOException, SAXException, XpathException { + Document inDocument = XMLUnit.buildControlDocument(control); + assertXpathNotExists(xPathExpression, inDocument); + } + + /** + * Assert that a specific XPath does NOT exist in some given XML + * @param inXpathExpression * @param inXMLString * @see XpathEngine which provides the underlying evaluation mechanism */ @@ -702,6 +944,19 @@ } /** + * Assert that an InputSource containing XML contains valid XML: + * the document must contain a DOCTYPE declaration to be validated + * @param xml + * @throws SAXException + * @throws ConfigurationException if validation could not be turned on + * @see Validator + */ + public static void assertXMLValid(InputSource xml) + throws SAXException, ConfigurationException { + assertXMLValid(new Validator(xml)); + } + + /** * Assert that a String containing XML contains valid XML: the String must * contain a DOCTYPE declaration to be validated * @param xmlString @@ -711,10 +966,25 @@ */ public static void assertXMLValid(String xmlString) throws SAXException, ConfigurationException { - assertXMLValid(new Validator(new StringReader(xmlString))); + assertXMLValid(new Validator(xmlString)); } /** + * Assert that an InputSource containing XML contains valid XML: + * the document must contain a DOCTYPE to be validated, but the + * validation will use the systemId to obtain the DTD + * @param xml + * @param systemId + * @throws SAXException + * @throws ConfigurationException if validation could not be turned on + * @see Validator + */ + public static void assertXMLValid(InputSource xml, String systemId) + throws SAXException, ConfigurationException { + assertXMLValid(new Validator(xml, systemId)); + } + + /** * Assert that a String containing XML contains valid XML: the String must * contain a DOCTYPE to be validated, but the validation will use the * systemId to obtain the DTD @@ -726,10 +996,28 @@ */ public static void assertXMLValid(String xmlString, String systemId) throws SAXException, ConfigurationException { - assertXMLValid(new Validator(new StringReader(xmlString), systemId)); + assertXMLValid(new Validator(xmlString, systemId)); } /** + * Assert that a piece of XML contains valid XML: the document + * will be given a DOCTYPE to be validated with the name and + * systemId specified regardless of whether it already contains a + * doctype declaration. + * @param xml + * @param systemId + * @param doctype + * @throws SAXException + * @throws ConfigurationException if validation could not be turned on + * @see Validator + */ + public static void assertXMLValid(InputSource xml, String systemId, + String doctype) + throws SAXException, ConfigurationException { + assertXMLValid(new Validator(xml, systemId, doctype)); + } + + /** * Assert that a String containing XML contains valid XML: the String will * be given a DOCTYPE to be validated with the name and systemId specified * regardless of whether it already contains a doctype declaration. @@ -756,6 +1044,25 @@ /** * Execute a <code>NodeTest<code> for a single node type * and assert that it passes + * @param xml XML to be tested + * @param tester The test strategy + * @param nodeType The node type to be tested: constants defined + * in {@link Node org.w3c.dom.Node} e.g. <code>Node.ELEMENT_NODE</code> + * @throws SAXException + * @throws IOException + * @see AbstractNodeTester + * @see CountingNodeTester + */ + public static void assertNodeTestPasses(InputSource xml, NodeTester tester, + short nodeType) + throws SAXException, IOException { + NodeTest test = new NodeTest(xml); + assertNodeTestPasses(test, tester, new short[] {nodeType}, true); + } + + /** + * Execute a <code>NodeTest<code> for a single node type + * and assert that it passes * @param xmlString XML to be tested * @param tester The test strategy * @param nodeType The node type to be tested: constants defined Modified: trunk/xmlunit/src/java/org/custommonkey/xmlunit/XMLTestCase.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/XMLTestCase.java 2007-03-28 04:06:22 UTC (rev 158) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/XMLTestCase.java 2007-03-28 04:07:35 UTC (rev 159) @@ -45,6 +45,7 @@ import junit.framework.TestCase; import org.w3c.dom.Document; +import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -105,6 +106,19 @@ } /** + * Compare XML documents provided by two InputSource classes + * @param control Control document + * @param test Document to test + * @return Diff object describing differences in documents + * @throws SAXException + * @throws IOException + */ + public Diff compareXML(InputSource control, InputSource test) + throws SAXException, IOException { + return XMLUnit.compareXML(control, test); + } + + /** * Compare XML documents provided by two Reader classes * @param control Control document * @param test Document to test @@ -233,6 +247,18 @@ * @throws SAXException * @throws IOException */ + public void assertXMLEqual(InputSource control, InputSource test) + throws SAXException, IOException { + XMLAssert.assertXMLEqual(control, test); + } + + /** + * Assert that two XML documents are similar + * @param control XML to be compared against + * @param test XML to be tested + * @throws SAXException + * @throws IOException + */ public void assertXMLEqual(String control, String test) throws SAXException, IOException { XMLAssert.assertXMLEqual(control, test); @@ -277,7 +303,21 @@ * @param err Message to be displayed on assertion failure * @param control XML to be compared against * @param test XML to be tested + * @throws SAXException + * @throws IOException */ + public void assertXMLEqual(String err, InputSource control, + InputSource test) + throws SAXException, IOException { + XMLAssert.assertXMLEqual(err, control, test); + } + + /** + * Assert that two XML documents are similar + * @param err Message to be displayed on assertion failure + * @param control XML to be compared against + * @param test XML to be tested + */ public void assertXMLEqual(String err, Document control, Document test) { XMLAssert.assertXMLEqual(err, control, test); } @@ -302,22 +342,21 @@ * @throws SAXException * @throws IOException */ - public void assertXMLNotEqual(String control, String test) + public void assertXMLNotEqual(InputSource control, InputSource test) throws SAXException, IOException { XMLAssert.assertXMLNotEqual(control, test); } /** * Assert that two XML documents are NOT similar - * @param err Message to be displayed on assertion failure * @param control XML to be compared against * @param test XML to be tested * @throws SAXException * @throws IOException */ - public void assertXMLNotEqual(String err, String control, String test) + public void assertXMLNotEqual(String control, String test) throws SAXException, IOException { - XMLAssert.assertXMLNotEqual(err, control, test); + XMLAssert.assertXMLNotEqual(control, test); } /** @@ -331,24 +370,41 @@ /** * Assert that two XML documents are NOT similar + * @param control XML to be compared against + * @param test XML to be tested + * @throws SAXException + * @throws IOException + */ + public void assertXMLNotEqual(Reader control, Reader test) + throws SAXException, IOException { + XMLAssert.assertXMLNotEqual(control, test); + } + + /** + * Assert that two XML documents are NOT similar * @param err Message to be displayed on assertion failure * @param control XML to be compared against * @param test XML to be tested + * @throws SAXException + * @throws IOException */ - public void assertXMLNotEqual(String err, Document control, Document test) { + public void assertXMLNotEqual(String err, InputSource control, + InputSource test) + throws SAXException, IOException { XMLAssert.assertXMLNotEqual(err, control, test); } /** * Assert that two XML documents are NOT similar + * @param err Message to be displayed on assertion failure * @param control XML to be compared against * @param test XML to be tested * @throws SAXException * @throws IOException */ - public void assertXMLNotEqual(Reader control, Reader test) + public void assertXMLNotEqual(String err, String control, String test) throws SAXException, IOException { - XMLAssert.assertXMLNotEqual(control, test); + XMLAssert.assertXMLNotEqual(err, control, test); } /** @@ -356,6 +412,16 @@ * @param err Message to be displayed on assertion failure * @param control XML to be compared against * @param test XML to be tested + */ + public void assertXMLNotEqual(String err, Document control, Document test) { + XMLAssert.assertXMLNotEqual(err, control, test); + } + + /** + * Assert that two XML documents are NOT similar + * @param err Message to be displayed on assertion failure + * @param control XML to be compared against + * @param test XML to be tested * @throws SAXException * @throws IOException */ @@ -372,6 +438,19 @@ * @see XpathEngine */ public void assertXpathsEqual(String controlXpath, String testXpath, + InputSource document) + throws SAXException, IOException, XpathException { + XMLAssert.assertXpathsEqual(controlXpath, testXpath, document); + } + + /** + * Assert that the node lists of two Xpaths in the same document are equal + * @param xpathOne + * @param xpathTwo + * @param document + * @see XpathEngine + */ + public void assertXpathsEqual(String controlXpath, String testXpath, Document document) throws XpathException { XMLAssert.assertXpathsEqual(controlXpath, testXpath, document); @@ -393,6 +472,22 @@ } /** + * Assert that the node lists of two Xpaths in two XML pieces are equal + * @param xpathOne + * @param control + * @param xpathTwo + * @param test + * @throws SAXException + * @throws IOException + */ + public void assertXpathsEqual(String controlXpath, InputSource control, + String testXpath, InputSource test) + throws SAXException, IOException, XpathException { + XMLAssert.assertXpathsEqual(controlXpath, control, + testXpath, test); + } + + /** * Assert that the node lists of two Xpaths in two XML strings are equal * @param xpathOne * @param inControlXMLString @@ -439,6 +534,21 @@ } /** + * Assert that the node lists of two Xpaths in the same XML are NOT + * equal + * @param xpathOne + * @param xpathTwo + * @param control + * @throws SAXException + * @throws IOException + */ + public void assertXpathsNotEqual(String controlXpath, String testXpath, + InputSource control) + throws SAXException, IOException, XpathException { + XMLAssert.assertXpathsNotEqual(controlXpath, testXpath, control); + } + + /** * Assert that the node lists of two Xpaths in the same XML string are NOT * equal * @param xpathOne @@ -455,6 +565,22 @@ } /** + * Assert that the node lists of two Xpaths in two pieces of XML + * are NOT equal + * @param xpathOne + * @param control + * @param xpathTwo + * @param test + * @throws SAXException + * @throws IOException + */ + public void assertXpathsNotEqual(String controlXpath, InputSource control, + String testXpath, InputSource test) + throws SAXException, IOException, XpathException { + XMLAssert.assertXpathsNotEqual(controlXpath, control, testXpath, test); + } + + /** * Assert that the node lists of two Xpaths in two XML strings are NOT equal * @param xpathOne * @param inControlXMLString @@ -501,6 +627,21 @@ } /** + * Assert that the evaluation of two Xpaths in the same XML are + * equal + * @param xpathOne + * @param xpathTwo + * @param control + * @throws SAXException + * @throws IOException + */ + public void assertXpathValuesEqual(String controlXpath, String testXpath, + InputSource control) + throws SAXException, IOException, XpathException { + XMLAssert.assertXpathValuesEqual(controlXpath, testXpath, control); + } + + /** * Assert that the evaluation of two Xpaths in the same XML string are * equal * @param xpathOne @@ -519,6 +660,24 @@ /** * Assert that the evaluation of two Xpaths in two XML strings are equal * @param xpathOne + * @param control + * @param xpathTwo + * @param test + * @throws SAXException + * @throws IOException + */ + public void assertXpathValuesEqual(String controlXpath, + InputSource control, + String testXpath, + InputSource test) + throws SAXException, IOException, XpathException { + XMLAssert.assertXpathValuesEqual(controlXpath, control, + testXpath, test); + } + + /** + * Assert that the evaluation of two Xpaths in two XML strings are equal + * @param xpathOne * @param inControlXMLString * @param xpathTwo * @param inTestXMLString @@ -555,6 +714,23 @@ * NOT equal * @param xpathOne * @param xpathTwo + * @param control + * @throws SAXException + * @throws IOException + */ + public void assertXpathValuesNotEqual(String controlXpath, + String testXpath, + InputSource control) + throws SAXException, IOException, XpathException { + XMLAssert.assertXpathValuesNotEqual(controlXpath, testXpath, + control); + } + + /** + * Assert that the evaluation of two Xpaths in the same XML string are + * NOT equal + * @param xpathOne + * @param xpathTwo * @param inXMLString * @throws SAXException * @throws IOException @@ -584,6 +760,25 @@ * Assert that the evaluation of two Xpaths in two XML strings are * NOT equal * @param xpathOne + * @param control + * @param xpathTwo + * @param test + * @throws SAXException + * @throws IOException + */ + public void assertXpathValuesNotEqual(String controlXpath, + InputSource control, + String testXpath, + InputSource test) + throws SAXException, IOException, XpathException { + XMLAssert.assertXpathValuesNotEqual(controlXpath, control, + testXpath, test); + } + + /** + * Assert that the evaluation of two Xpaths in two XML strings are + * NOT equal + * @param xpathOne * @param inControlXMLString * @param xpathTwo * @param inTestXMLString @@ -620,6 +815,23 @@ * Assert the value of an Xpath expression in an XML String * @param expectedValue * @param xpathExpression + * @param control + * @throws SAXException + * @throws IOException + * @see XpathEngine which provides the underlying evaluation mechanism + */ + public void assertXpathEvaluatesTo(String expectedValue, + String xpathExpression, + InputSource control) + throws SAXException, IOException, XpathException { + XMLAssert.assertXpathEvaluatesTo(expectedValue, xpathExpression, + control); + } + + /** + * Assert the value of an Xpath expression in an XML String + * @param expectedValue + * @param xpathExpression * @param inXMLString * @throws SAXException * @throws IOException @@ -653,8 +865,19 @@ /** * Assert that a specific XPath exists in some given XML * @param inXpathExpression + * @param xml + * @see XpathEngine which provides the underlying evaluation mechanism + */ + public void assertXpathExists(String xPathExpression, + InputSource xml) + throws IOException, SAXException, XpathException { + XMLAssert.assertXpathExists(xPathExpression, xml); + } + + /** + * Assert that a specific XPath exists in some given XML + * @param inXpathExpression * @param inXMLString - * @param ctx * @see XpathEngine which provides the underlying evaluation mechanism */ public void assertXpathExists(String xPathExpression, @@ -678,6 +901,18 @@ /** * Assert that a specific XPath does NOT exist in some given XML * @param inXpathExpression + * @param xml + * @see XpathEngine which provides the underlying evaluation mechanism + */ + public void assertXpathNotExists(String xPathExpression, + InputSource xml) + throws IOException, SAXException, XpathException { + XMLAssert.assertXpathNotExists(xPathExpression, xml); + } + + /** + * Assert that a specific XPath does NOT exist in some given XML + * @param inXpathExpression * @param inXMLString * @see XpathEngine which provides the underlying evaluation mechanism */ @@ -724,6 +959,19 @@ } /** + * Assert that a piece of XML contains valid XML: the input must + * contain a DOCTYPE declaration to be validated + * @param xml + * @throws SAXException + * @throws ConfigurationException if validation could not be turned on + * @see Validator + */ + public void assertXMLValid(InputSource xml) + throws SAXException, ConfigurationException { + XMLAssert.assertXMLValid(xml); + } + + /** * Assert that a String containing XML contains valid XML: the String must * contain a DOCTYPE declaration to be validated * @param xmlString @@ -737,6 +985,21 @@ } /** + * Assert that a piece of XML contains valid XML: the document must + * contain a DOCTYPE to be validated, but the validation will use the + * systemId to obtain the DTD + * @param xml + * @param systemId + * @throws SAXException + * @throws ConfigurationException if validation could not be turned on + * @see Validator + */ + public void assertXMLValid(InputSource xml, String systemId) + throws SAXException, ConfigurationException { + XMLAssert.assertXMLValid(xml, systemId); + } + + /** * Assert that a String containing XML contains valid XML: the String must * contain a DOCTYPE to be validated, but the validation will use the * systemId to obtain the DTD @@ -752,6 +1015,24 @@ } /** + * Assert that a piece of XML contains valid XML: the document + * will be given a DOCTYPE to be validated with the name and + * systemId specified regardless of whether it already contains a + * doctype declaration. + * @param xml + * @param systemId + * @param doctype + * @throws SAXException + * @throws ConfigurationException if validation could not be turned on + * @see Validator + */ + public void assertXMLValid(InputSource xml, String systemId, + String doctype) + throws SAXException, ConfigurationException { + XMLAssert.assertXMLValid(xml, systemId, doctype); + } + + /** * Assert that a String containing XML contains valid XML: the String will * be given a DOCTYPE to be validated with the name and systemId specified * regardless of whether it already contains a doctype declaration. @@ -778,6 +1059,24 @@ /** * Execute a <code>NodeTest<code> for a single node type * and assert that it passes + * @param xml XML to be tested + * @param tester The test strategy + * @param nodeType The node type to be tested: constants defined + * in {@link Node org.w3c.dom.Node} e.g. <code>Node.ELEMENT_NODE</code> + * @throws SAXException + * @throws IOException + * @see AbstractNodeTester + * @see CountingNodeTester + */ + public void assertNodeTestPasses(InputSource xml, NodeTester tester, + short nodeType) + throws SAXException, IOException { + XMLAssert.assertNodeTestPasses(xml, tester, nodeType); + } + + /** + * Execute a <code>NodeTest<code> for a single node type + * and assert that it passes * @param xmlString XML to be tested * @param tester The test strategy * @param nodeType The node type to be tested: constants defined Modified: trunk/xmlunit/src/java/org/custommonkey/xmlunit/XMLUnit.java =================================================================== --- trunk/xmlunit/src/java/org/custommonkey/xmlunit/XMLUnit.java 2007-03-28 04:06:22 UTC (rev 158) +++ trunk/xmlunit/src/java/org/custommonkey/xmlunit/XMLUnit.java 2007-03-28 04:07:35 UTC (rev 159) @@ -507,6 +507,19 @@ return "1.1alpha"; } + /** + * Compare XML documents provided by two InputSource classes + * @param control Control document + * @param test Document to test + * @return Diff object describing differences in documents + * @throws SAXException + * @throws IOException + */ + public static Diff compareXML(InputSource control, InputSource test) + throws SAXException, IOException { + return new Diff(control, test); + } + /** * Compare XML documents provided by two Reader classes * @param control Control document Modified: trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_Validator.java =================================================================== --- trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_Validator.java 2007-03-28 04:06:22 UTC (rev 158) +++ trunk/xmlunit/tests/java/org/custommonkey/xmlunit/test_Validator.java 2007-03-28 04:07:35 UTC (rev 159) @@ -39,10 +39,13 @@ import junit.framework.AssertionFailedError; import junit.framework.TestSuite; import org.w3c.dom.Document; +import org.xml.sax.InputSource; import java.io.File; +import java.io.FileInputStream; import java.io.FileReader; import java.io.FileWriter; +import java.io.StringBufferInputStream; import java.io.StringReader; /** @@ -56,15 +59,18 @@ public void testXSchema() throws Exception{ File xsdFile = new File(test_Constants.BASEDIR + "/tests/etc/Book.xsd"); - assertTrue("xsdFile " + xsdFile.getAbsolutePath() + " exists", xsdFile.exists()); + assertTrue("xsdFile " + xsdFile.getAbsolutePath() + " exists", + xsdFile.exists()); - File xmlFile = new File(test_Constants.BASEDIR + "/tests/etc/BookXsdGenerated.xml"); - assertTrue("xmlFile " + xmlFile.getAbsolutePath() + " exists", xmlFile.exists()); - validator = new Validator(new FileReader(xmlFile)); + File xmlFile = new File(test_Constants.BASEDIR + + "/tests/etc/BookXsdGenerated.xml"); + assertTrue("xmlFile " + xmlFile.getAbsolutePath() + " exists", + xmlFile.exists()); + validator = + new Validator(new InputSource(new FileInputStream(xmlFile))); validator.useXMLSchema(true); - - validator.assertIsValid(); + assertTrue("Schema " + validator.toString(), validator.isValid()); } public void testIsValidGood() throws Exception { @@ -72,8 +78,7 @@ + test_Constants.CHUCK_JONES_RIP_DTD_DECL + test_Constants.CHUCK_JONES_RIP_XML; validator = new Validator(new StringReader(toonXML)); - assertEquals("toonXML " + validator.toString(), - true, validator.isValid()); + assertTrue("toonXML " + validator.toString(), validator.isValid()); // test XMLTestCase passXMLTestCaseTest(toonXML); passXMLTestCaseTest(validator); @@ -90,7 +95,7 @@ public void testIsValidExternalSystemId() throws Exception { writeTempDTDFile(); - assertEquals(tempDTDFile.getAbsolutePath(), true, tempDTDFile.exists()); + assertTrue(tempDTDFile.getAbsolutePath(), tempDTDFile.exists()); String externalDTD = test_Constants.XML_DECLARATION + test_Constants.DOCUMENT_WITH_GOOD_EXTERNAL_DTD; @@ -98,8 +103,7 @@ validator = new Validator(new StringReader(externalDTD), tempDTDUrl); - assertEquals("externalDTD " + validator.toString(), - true, validator.isValid()); + assertTrue("externalDTD " + validator.toString(), validator.isValid()); // test XMLTestCase passXMLTestCaseTest(externalDTD, tempDTDFile.toURL().toExternalForm()); passXMLTestCaseTest(validator); @@ -109,8 +113,7 @@ validator = new Validator(new StringReader(noDTD), tempDTDFile.toURL().toExternalForm()); - assertEquals("noDTD " + validator.toString(), - false, validator.isValid()); + assertFalse("noDTD " + validator.toString(), validator.isValid()); // test XMLTestCase failXMLTestCaseTest(noDTD, tempDTDFile.toURL().toExternalForm()); failXMLTestCaseTest(validator); @@ -118,7 +121,7 @@ public void testIsValidNoDTD() throws Exception { writeTempDTDFile(); - assertEquals(tempDTDFile.getAbsolutePath(), true, tempDTDFile.exists()); + assertTrue(tempDTDFile.getAbsolutePath(), tempDTDFile.exists()); String noDTD = test_Constants.CHUCK_JONES_RIP_XML; String systemid = tempDTDFile.toURL().toExternalForm(); @@ -126,39 +129,33 @@ String notDoctype = "anima"; validator = new Validator(new StringReader(noDTD), systemid, doctype); - assertEquals(validator.toString(), true, validator.isValid()); + assertTrue(validator.toString(), validator.isValid()); // test XMLTestCase passXMLTestCaseTest(noDTD, systemid, doctype); passXMLTestCaseTest(validator); + // and Document constructor + Document document = getDocument(noDTD); + validator = new Validator(document, systemid, doctype); + assertTrue("Document " + validator.toString(), validator.isValid()); validator = new Validator(new StringReader(noDTD), systemid, notDoctype); - assertEquals(validator.toString(), false, validator.isValid()); + assertFalse(validator.toString(), validator.isValid()); // test XMLTestCase failXMLTestCaseTest(noDTD, systemid, notDoctype); failXMLTestCaseTest(validator); - - Document document = getDocument(noDTD); - validator = new Validator(document, systemid, doctype); - assertEquals("Document " + validator.toString(), - true, validator.isValid()); - // test XMLTestCase - passXMLTestCaseTest(validator); - + // and Document constructor validator = new Validator(document, systemid, notDoctype); - assertEquals("Document " + validator.toString(), - false, validator.isValid()); - // test XMLTestCase - failXMLTestCaseTest(validator); + assertFalse("Document " + validator.toString(), validator.isValid()); } public void testIsValidBad() throws Exception { String noDTD = test_Constants.XML_DECLARATION + test_Constants.CHUCK_JONES_RIP_XML; validator = new Validator(new StringReader(noDTD)); - assertEquals("noDTD " + validator.toString(), - false, validator.isValid()); + assertFalse("noDTD " + validator.toString(), validator.isValid()); // test XMLTestCase + failXMLTestCaseTest(noDTD); failXMLTestCaseTest(validator); String dtdTwice = test_Constants.XML_DECLARATION @@ -166,18 +163,18 @@ + test_Constants.CHUCK_JONES_RIP_DTD_DECL + test_Constants.CHUCK_JONES_RIP_XML; validator = new Validator(new StringReader(dtdTwice)); - assertEquals("dtdTwice " + validator.toString(), - false, validator.isValid()); + assertFalse("dtdTwice " + validator.toString(), validator.isValid()); // test XMLTestCase + failXMLTestCaseTest(dtdTwice); failXMLTestCaseTest(validator); String invalidXML = test_Constants.XML_DECLARATION + test_Constants.CHUCK_JONES_RIP_DTD_DECL + test_Constants.CHUCK_JONES_SPINNING_IN_HIS_GRAVE_XML; validator = new Validator(new StringReader(invalidXML)); - assertEquals("invalidXML " + validator.toString(), - false, validator.isValid()); + assertFalse("invalidXML " + validator.toString(), validator.isValid()); // test XMLTestCase + failXMLTestCaseTest(invalidXML); failXMLTestCaseTest(validator); } @@ -209,13 +206,22 @@ // ---- XMLTestCase methods ---- private void passXMLTestCaseTest(String xml) throws Exception { assertXMLValid(xml); + assertXMLValid(new InputSource(new StringReader(xml))); + assertXMLValid(new InputSource(new StringBufferInputStream(xml))); } private void passXMLTestCaseTest(String xml, String systemId) throws Exception { assertXMLValid(xml, systemId); + assertXMLValid(new InputSource(new StringReader(xml)), systemId); + assertXMLValid(new InputSource(new StringBufferInputStream(xml)), + systemId); } private void passXMLTestCaseTest(String xml, String systemId, String doctype) throws Exception { assertXMLValid(xml, systemId, doctype); + assertXMLValid(new InputSource(new StringReader(xml)), systemId, + doctype); + assertXMLValid(new InputSource(new StringBufferInputStream(xml)), + systemId, doctype); } private void passXMLTestCaseTest(Validator validator) throws Exception { assertXMLValid(validator); @@ -227,7 +233,40 @@ } catch (AssertionFailedError e) { // expecting this } + try { + assertXMLValid(new InputSource(new StringReader(xml)), systemId); + fail("Expected assertion to fail!"); + } catch (AssertionFailedError e) { + // expecting this + } + try { + assertXMLValid(new InputSource(new StringBufferInputStream(xml)), + systemId); + fail("Expected assertion to fail!"); + } catch (AssertionFailedError e) { + // expecting this + } } + private void failXMLTestCaseTest(String xml) throws Exception { + try { + assertXMLValid(xml); + fail("Expected assertion to fail!"); + } catch (AssertionFailedError e) { + // expecting this + } + try { + assertXMLValid(new InputSource(new StringReader(xml))); + fail("Expected assertion to fail!"); + } catch (AssertionFailedError e) { + // expecting this + } + try { + assertXMLValid(new InputSource(new StringBufferInputStream(xml))); + fail("Expected assertion to fail!"); + } catch (AssertionFailedError e) { + // expecting this + } + } private void failXMLTestCaseTest(String xml, String systemId, String doctype) throws Exception { try { @@ -236,6 +275,20 @@ } catch (AssertionFailedError e) { // expecting this } + try { + assertXMLValid(new InputSource(new StringReader(xml)), systemId, + doctype); + fail("Expected assertion to fail!"); + } catch (AssertionFailedError e) { + // expecting this + } + try { + assertXMLValid(new InputSource(new StringBufferInputStream(xml)), + systemId, doctype); + fail("Expected assertion to fail!"); + } catch (AssertionFailedError e) { + // expecting this + } } private void failXMLTestCaseTest(Validator validator) throws Exception { try { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |