diff --git a/src/test/java/failing/TestInvalidAttributeValue190.java b/src/test/java/failing/TestInvalidAttributeValue190.java new file mode 100644 index 00000000..edac3cb4 --- /dev/null +++ b/src/test/java/failing/TestInvalidAttributeValue190.java @@ -0,0 +1,74 @@ +package failing; + +import stax2.BaseStax2Test; + +import java.io.StringReader; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.stream.*; + +import org.codehaus.stax2.XMLStreamReader2; +import org.codehaus.stax2.validation.ValidationProblemHandler; +import org.codehaus.stax2.validation.XMLValidationException; +import org.codehaus.stax2.validation.XMLValidationProblem; +import org.codehaus.stax2.validation.XMLValidationSchema; +import org.codehaus.stax2.validation.XMLValidationSchemaFactory; + +import com.ctc.wstx.sw.RepairingNsStreamWriter; + +public class TestInvalidAttributeValue190 + extends BaseStax2Test +{ + /* A reproducer for https://github.com/FasterXML/woodstox/issues/190 */ + public void testInvalidAttributeValue() throws Exception + { + final String DOC = ""; + + final String INPUT_DTD = +"\n" ++"\n" +; + + XMLInputFactory f = getInputFactory(); + setCoalescing(f, true); + + XMLValidationSchemaFactory schemaFactory = + XMLValidationSchemaFactory.newInstance(XMLValidationSchema.SCHEMA_ID_DTD); + XMLValidationSchema schema = schemaFactory.createSchema(new StringReader(INPUT_DTD)); + XMLStreamReader2 sr = (XMLStreamReader2)f.createXMLStreamReader( + new StringReader(DOC)); + + final List probs = new ArrayList(); + + sr.validateAgainst(schema); + sr.setValidationProblemHandler(new ValidationProblemHandler() { + @Override + public void reportProblem(XMLValidationProblem problem) + throws XMLValidationException { + probs.add(problem); + } + }); + + assertTokenType(START_ELEMENT, sr.next()); + assertEquals("root", sr.getLocalName()); + + final String verboseValue = sr.getAttributeValue(null, "verbose"); + + assertEquals("yes", verboseValue); + + assertEquals(1, probs.size()); + assertEquals("Element has no attribute \"verbose\"", probs.get(0).getMessage()); + + // now do the same on the writer side + // and make sure that the reported problems are the same + { + // RepairingNsStreamWriter + StringWriter writer = new StringWriter(); + RepairingNsStreamWriter sw = (RepairingNsStreamWriter) stax2.BaseStax2Test.constructStreamWriter(writer, true, true); + validateWriter(DOC, probs, f, schema, writer, sw); + } + + } +} diff --git a/src/test/java/failing/TestRelaxNG189.java b/src/test/java/failing/TestRelaxNG189.java new file mode 100644 index 00000000..45a6e34f --- /dev/null +++ b/src/test/java/failing/TestRelaxNG189.java @@ -0,0 +1,62 @@ +package failing; + +import javax.xml.stream.*; + +import org.codehaus.stax2.validation.*; + +import wstxtest.vstream.BaseValidationTest; + +/** + * A reproducer for https://github.com/FasterXML/woodstox/issues/189 + * Move to {@link wstxtest.vstream.TestRelaxNG} once fixed. + */ +public class TestRelaxNG189 + extends BaseValidationTest +{ + + /** + * Test case for testing handling ID/IDREF/IDREF attributes, using + * schema datatype library. + */ + public void testSimpleIdAttrsWriter() + throws XMLStreamException + { + final String schemaDef = + "\n" + +" \n" + +" \n" + +" \n" + +" \n" + +" \n" + +" \n" + +" \n" + +" \n" + +" \n" + +" \n" + +" \n" + +"" + ; + + XMLValidationSchema schema = parseRngSchema(schemaDef); + + String XML; + + // And then invalid one, with dangling ref + XML = "" + +" \n" + +"" + ; + verifyFailure(XML, schema, "reference to undefined id", + "Undefined ID", true, false, true); + + // and another one with some of refs undefined + XML = "" + +" \n" + +"" + ; + verifyFailure(XML, schema, "reference to undefined id", + "Undefined ID", true, false, true); + } + +} diff --git a/src/test/java/failing/TestRelaxNG190.java b/src/test/java/failing/TestRelaxNG190.java new file mode 100644 index 00000000..658e2745 --- /dev/null +++ b/src/test/java/failing/TestRelaxNG190.java @@ -0,0 +1,43 @@ +package failing; + +import java.io.StringWriter; + +import javax.xml.stream.*; + +import org.codehaus.stax2.validation.*; + +import com.ctc.wstx.sw.RepairingNsStreamWriter; + +/** + * A reproducer for https://github.com/FasterXML/woodstox/issues/190 + * Move to {@link wstxtest.vstream.TestRelaxNG} once fixed. + */ +public class TestRelaxNG190 + extends wstxtest.vstream.TestRelaxNG +{ + + public void testPartialValidationOk() + throws XMLStreamException + { + /* Hmmh... RelaxNG does define expected root. So need to + * wrap the doc... + */ + String XML = + "\n" + +"\n" + +"\n" + +" foobar\n" + +" Foo Bar\n" + +"\n" + +"" + ; + XMLValidationSchema schema = parseRngSchema(SIMPLE_RNG_SCHEMA); + { + StringWriter writer = new StringWriter(); + RepairingNsStreamWriter sw = (RepairingNsStreamWriter) constructStreamWriter(writer, true, true); + _testPartialValidationOk(XML, schema, sw, writer); + } + } + + +} diff --git a/src/test/java/failing/TestW3CSchema189.java b/src/test/java/failing/TestW3CSchema189.java new file mode 100644 index 00000000..a505652e --- /dev/null +++ b/src/test/java/failing/TestW3CSchema189.java @@ -0,0 +1,29 @@ +package failing; + +import javax.xml.stream.XMLStreamException; + +import org.codehaus.stax2.validation.XMLValidationSchema; + +import wstxtest.msv.TestW3CSchema; + +/** + */ +public class TestW3CSchema189 + extends TestW3CSchema +{ + + /** + * A reproducer for https://github.com/FasterXML/woodstox/issues/189 + * Move to {@link TestW3CSchema} once fixed. + */ + public void testSimpleNonNsUndefinedIdWriter189() throws XMLStreamException + { + XMLValidationSchema schema = parseW3CSchema(SIMPLE_NON_NS_SCHEMA); + String XML = "" + + "FG" + + ""; + verifyFailure(XML, schema, "undefined referenced id ('m3')", + "Undefined ID 'm3'", true, false, true); + } + +} diff --git a/src/test/java/failing/W3CSchemaNillable179Test.java b/src/test/java/failing/W3CSchemaNillable179Test.java index ea2005cc..ffe43581 100644 --- a/src/test/java/failing/W3CSchemaNillable179Test.java +++ b/src/test/java/failing/W3CSchemaNillable179Test.java @@ -1,81 +1,115 @@ package failing; // ^^^ Move under "wstxtest/msv" once passing -import java.io.IOException; -import java.io.InputStream; +import java.io.StringReader; import java.io.StringWriter; -import javax.xml.XMLConstants; -import javax.xml.transform.Source; -import javax.xml.transform.stream.StreamSource; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; -import javax.xml.validation.Validator; - import org.codehaus.stax2.*; import org.codehaus.stax2.validation.*; -import org.xml.sax.SAXException; import wstxtest.vstream.BaseValidationTest; /** - * Test whether MSV validator behaves the same w.r.t. nillable elements as javax.xml.validation validator. + * Test whether nillable elements are handled correctly by both reader and writer. * A reproducer for https://github.com/FasterXML/woodstox/issues/179. */ public class W3CSchemaNillable179Test extends BaseValidationTest { + private static final String SCHEMA = + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; // for [woodstox-core#179] public void testNillableDateTime() throws Exception { - /* - - - - */ - testNillable("wstxtest/msv/nillableDateTime.xml"); + final String xmlDocument = + "\n" + + " \n" + + ""; + testNillable(xmlDocument, true, true); + + // The same document without xsi:nil="true" must fail for both reader and writer validation + try { + testNillable(xmlDocument.replace(" xsi:nil=\"true\"", ""), true, false); + fail("Expected a LocalValidationError"); + } catch (LocalValidationError expected) { + assertEquals("Unknown reason (at end element )", expected.problem.getMessage()); + } + try{ + testNillable(xmlDocument.replace(" xsi:nil=\"true\"", ""), false, true); + fail("Expected a LocalValidationError"); + } catch (LocalValidationError expected) { + assertEquals("Unknown reason (at end element )", expected.problem.getMessage()); + } + } // for [woodstox-core#179] public void testNillableInt() throws Exception { - /* - - - - */ - testNillable("wstxtest/msv/nillableInt.xml"); + final String xmlDocument = + "\n" + + " \n" + + ""; + testNillable(xmlDocument, true, true); + + // The same document without xsi:nil="true" must fail for both reader and writer validation + try { + testNillable(xmlDocument.replace(" xsi:nil=\"true\"", ""), true, false); + fail("Expected a LocalValidationError"); + } catch (LocalValidationError expected) { + assertEquals("Unknown reason (at end element )", expected.problem.getMessage()); + } + try{ + testNillable(xmlDocument.replace(" xsi:nil=\"true\"", ""), false, true); + fail("Expected a LocalValidationError"); + } catch (LocalValidationError expected) { + assertEquals("Unknown reason (at end element )", expected.problem.getMessage()); + } + } // for [woodstox-core#179] public void testNillableString() throws Exception { - /* - - - - */ - testNillable("wstxtest/msv/nillableString.xml"); + final String xmlDocument = + "\n" + + " \n" + + ""; + testNillable(xmlDocument, true, true); + + // Empty strings are legal + testNillable(xmlDocument.replace(" xsi:nil=\"true\"", ""), true, false); + testNillable(xmlDocument.replace(" xsi:nil=\"true\"", ""), false, true); + } - void testNillable(String xmlResource) throws Exception + void testNillable(String xmlDocument, boolean validateReader, boolean validateWriter) throws Exception { - boolean woodstoxPassed = true; - Exception woodstoxE = null; - // Woodstox - final String xsdResource = "wstxtest/msv/nillable.xsd"; - { + StringWriter writer = new StringWriter(); + XMLStreamReader2 xmlReader = null; + XMLStreamWriter2 xmlWriter = null; + try { XMLValidationSchemaFactory schF = XMLValidationSchemaFactory.newInstance(XMLValidationSchema.SCHEMA_ID_W3C_SCHEMA); - InputStream schemaInput = getClass().getClassLoader().getResourceAsStream(xsdResource); - InputStream xmlInput = getClass().getClassLoader().getResourceAsStream(xmlResource); - try { - XMLValidationSchema schema = schF.createSchema(schemaInput); - XMLInputFactory2 f = getInputFactory(); - setValidating(f, false); + XMLValidationSchema schema = schF.createSchema(new StringReader(SCHEMA)); + XMLInputFactory2 f = getInputFactory(); + setValidating(f, validateReader); - XMLStreamReader2 xmlReader = (XMLStreamReader2) f.createXMLStreamReader(xmlInput); + xmlReader = (XMLStreamReader2) f.createXMLStreamReader(new StringReader(xmlDocument)); - /* the validation exception is only thrown from the writer + if (validateReader) { xmlReader.setValidationProblemHandler(new ValidationProblemHandler() { @Override public void reportProblem(XMLValidationProblem problem) @@ -84,10 +118,11 @@ public void reportProblem(XMLValidationProblem problem) } }); xmlReader.validateAgainst(schema); - */ + } - StringWriter writer = new StringWriter(); - XMLStreamWriter2 xmlWriter = (XMLStreamWriter2) getOutputFactory().createXMLStreamWriter(writer); + xmlWriter = (XMLStreamWriter2) getOutputFactory().createXMLStreamWriter(writer); + + if (validateWriter) { xmlWriter.setValidationProblemHandler(new ValidationProblemHandler() { @Override public void reportProblem(XMLValidationProblem problem) @@ -96,67 +131,22 @@ public void reportProblem(XMLValidationProblem problem) } }); xmlWriter.validateAgainst(schema); - - try { - xmlWriter.copyEventFromReader(xmlReader, false); - while (xmlReader.hasNext()) { - xmlReader.next(); - xmlWriter.copyEventFromReader(xmlReader, false); - } - } catch (LocalValidationError e) { - woodstoxPassed = false; - woodstoxE = e; - } - } finally { - if (xmlInput != null) { - xmlInput.close(); - } - if (schemaInput != null) { - schemaInput.close(); - } } - } - // javax.xml.validation - boolean javaxXmlValidationPassed = true; - { - InputStream schemaInput = getClass().getClassLoader().getResourceAsStream(xsdResource); - InputStream xmlInput = getClass().getClassLoader().getResourceAsStream(xmlResource); - SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); - try { - Source schemaFile = new StreamSource(schemaInput); - Schema schema = factory.newSchema(schemaFile); - Validator validator = schema.newValidator(); - try { - validator.validate(new StreamSource(xmlInput)); - } catch (SAXException e) { - javaxXmlValidationPassed = false; - } catch (IOException e) { - throw new RuntimeException(e); - } - } finally { - if (xmlInput != null) { - xmlInput.close(); - } - if (schemaInput != null) { - schemaInput.close(); - } + xmlWriter.copyEventFromReader(xmlReader, false); + while (xmlReader.hasNext()) { + xmlReader.next(); + xmlWriter.copyEventFromReader(xmlReader, false); } - } - - if (woodstoxPassed != javaxXmlValidationPassed) { - if (woodstoxPassed) { - fail("Woodstox MSV validator passed" - + " but javax.xml.validation validator did not pass" - + " for " + xsdResource + " and "+ xmlResource); - - } else { - fail("Woodstox MSV validator did not pass" - + " but javax.xml.validation validator passed" - + " for " + xsdResource + " and "+ xmlResource - +".\nFailure: "+woodstoxE); + } finally { + if (xmlReader != null) { + xmlReader.close(); + } + if (xmlWriter != null) { + xmlWriter.close(); } } + assertEquals(xmlDocument, writer.toString()); } /* diff --git a/src/test/java/stax2/BaseStax2Test.java b/src/test/java/stax2/BaseStax2Test.java index 86c2db93..526764d8 100644 --- a/src/test/java/stax2/BaseStax2Test.java +++ b/src/test/java/stax2/BaseStax2Test.java @@ -1,7 +1,9 @@ package stax2; import java.io.*; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import junit.framework.TestCase; @@ -12,6 +14,12 @@ import org.codehaus.stax2.evt.*; import org.codehaus.stax2.ri.Stax2ReaderAdapter; +import org.codehaus.stax2.validation.ValidationProblemHandler; +import org.codehaus.stax2.validation.XMLValidationException; +import org.codehaus.stax2.validation.XMLValidationProblem; +import org.codehaus.stax2.validation.XMLValidationSchema; + +import com.ctc.wstx.stax.WstxOutputFactory; /** * Base unit test class to be inherited by all unit tests that test @@ -186,6 +194,14 @@ protected XMLStreamReader2 constructNonNsStreamReader(String content, boolean co return (XMLStreamReader2) f.createXMLStreamReader(new StringReader(content)); } + protected static XMLStreamWriter2 constructStreamWriter(Writer writer, boolean nsSupported, boolean repairing) throws XMLStreamException { + WstxOutputFactory f = new WstxOutputFactory(); + f.getConfig().doSupportNamespaces(nsSupported); + f.getConfig().enableAutomaticNamespaces(repairing); + return (XMLStreamWriter2) f.createXMLStreamWriter(writer); + } + + /** * Method to force constructing a wrapper for given stream reader. * Have to use this method to work around natural resistance by @@ -328,7 +344,7 @@ protected static boolean isNamespaceAware(XMLOutputFactory f) * @return Dummy value calculated on contents; used to make sure * no dead code is eliminated */ - protected int streamThrough(XMLStreamReader sr) + protected static int streamThrough(XMLStreamReader sr) throws XMLStreamException { int result = 0; @@ -513,6 +529,13 @@ protected static void assertNoAttrNamespace(String attrNsURI) } } + protected static void assertMessageContains(Throwable e, String substring) { + final String actual = e.getMessage(); + if (!actual.contains(substring)) { + fail("Message '"+ actual +"' should contain '"+ substring +"'"); + } + } + protected static void failStrings(String msg, String exp, String act) { // !!! TODO: Indicate position where Strings differ @@ -571,6 +594,40 @@ protected void verifyException(Throwable e, String match) } } + protected static void validateWriter(final String DOC, final List probs, XMLInputFactory f, + XMLValidationSchema schema, StringWriter writer, XMLStreamWriter2 sw) throws XMLStreamException { + sw.validateAgainst(schema); + final List writerProbs = new ArrayList(); + sw.setValidationProblemHandler(new ValidationProblemHandler() { + + @Override + public void reportProblem(XMLValidationProblem problem) throws XMLValidationException { + writerProbs.add(problem); + } + }); + + XMLStreamReader2 sr = (XMLStreamReader2)f.createXMLStreamReader( + new StringReader(DOC)); + + sw.copyEventFromReader(sr, false); + while (sr.hasNext()) { + /* int type = */sr.next(); + sw.copyEventFromReader(sr, false); + } + sr.close(); + sw.close(); + assertEquals(DOC, writer.toString()); + + assertEquals(probs.size(), writerProbs.size()); + for (int i = 0; i < probs.size(); i++) { + XMLValidationProblem expected = probs.get(i); + XMLValidationProblem actual = writerProbs.get(i); + assertEquals(expected.getMessage(), actual.getMessage()); + assertEquals(expected.getSeverity(), actual.getSeverity()); + } + } + + /* /////////////////////////////////////////////////////////// // Debug/output helpers diff --git a/src/test/java/stax2/vwstream/TestAttributeValidation.java b/src/test/java/stax2/vwstream/TestAttributeValidation.java index 74ff5d36..d4793a1d 100644 --- a/src/test/java/stax2/vwstream/TestAttributeValidation.java +++ b/src/test/java/stax2/vwstream/TestAttributeValidation.java @@ -84,7 +84,7 @@ private void _testInvalidFixedAttr(boolean nsAware, boolean repairing) sw.writeAttribute("fixAttr", "otherValue"); fail(modeDesc+" Expected a validation exception when trying to add a #FIXED attribute with 'wrong' value"); } catch (XMLValidationException vex) { - // expected... + assertMessageContains(vex, "Value of attribute \"fixAttr\" (element ) not \"fixedValue\" as expected, but \"otherValue\""); } // Should not close, since stream is invalid now... @@ -96,7 +96,7 @@ private void _testInvalidFixedAttr(boolean nsAware, boolean repairing) sw.writeAttribute("fixAttr", ""); fail(modeDesc+" Expected a validation exception when trying to add a #FIXED attribute with an empty value"); } catch (XMLValidationException vex) { - // expected... + assertMessageContains(vex, "Value of attribute \"fixAttr\" (element ) not \"fixedValue\" as expected, but \"\""); } // And finally, same for empty elem in case impl. is different @@ -107,7 +107,7 @@ private void _testInvalidFixedAttr(boolean nsAware, boolean repairing) sw.writeAttribute("fixAttr", "foobar"); fail(modeDesc+" Expected a validation exception when trying to add a #FIXED attribute with an empty value"); } catch (XMLValidationException vex) { - // expected... + assertMessageContains(vex, "Value of attribute \"fixAttr\" (element ) not \"fixedValue\" as expected, but \"foobar\""); } } @@ -173,7 +173,7 @@ public void _testInvalidRequiredAttr(boolean nsAware, boolean repairing) sw.writeEndElement(); fail(modeDesc+" Expected a validation exception when omitting a #REQUIRED attribute"); } catch (XMLValidationException vex) { - // expected... + assertMessageContains(vex, "Required attribute \"reqAttr\" missing from element "); } // Should not close, since stream is invalid now... } @@ -229,7 +229,7 @@ private void _testInvalidNsAttr(boolean repairing) throws XMLStreamException sw.writeAttribute(NS_PREFIX2, NS_URI, "attr", "value"); fail(modeDesc+" Expected a validation exception when trying to add an attribute with wrong ns prefix"); } catch (XMLValidationException vex) { - // expected... + assertMessageContains(vex, "Element has no attribute \"ns2:attr\""); } // Should not close, since stream is invalid now... } diff --git a/src/test/java/stax2/vwstream/TestOutputValidation.java b/src/test/java/stax2/vwstream/TestOutputValidation.java index 17f08e6b..f88c208f 100644 --- a/src/test/java/stax2/vwstream/TestOutputValidation.java +++ b/src/test/java/stax2/vwstream/TestOutputValidation.java @@ -59,7 +59,7 @@ public void testInvalidMixedContent() sw.writeCharacters("Illegal text!"); fail("Expected a validation exception for non-whitespace text output on non-mixed element content"); } catch (XMLValidationException vex) { - // expected... + assertMessageContains(vex, "Element has non-mixed content specification; can not contain non-white space text, or any CDATA sections"); } } } @@ -149,7 +149,7 @@ public void testInvalidEmptyContent() sw.writeStartElement("leaf"); fail(modeDesc+" Expected a validation exception when trying to add an element into EMPTY content model"); } catch (XMLValidationException vex) { - // expected... + assertMessageContains(vex, "Validation error, encountered element as a child of : No elements allowed in pure #PCDATA content model"); } sw.close(); @@ -160,7 +160,7 @@ public void testInvalidEmptyContent() sw.writeEmptyElement("leaf"); fail(modeDesc+" Expected a validation exception when trying to add an element into EMPTY content model"); } catch (XMLValidationException vex) { - // expected... + assertMessageContains(vex, "Validation error, encountered element as a child of : No elements allowed in pure #PCDATA content model"); } sw.close(); @@ -170,7 +170,9 @@ public void testInvalidEmptyContent() try { sw.writeCharacters(" "); fail(modeDesc+" Expected a validation exception when trying to any text into EMPTY content model"); - } catch (XMLValidationException vex) { } + } catch (XMLValidationException vex) { + assertMessageContains(vex, "Element has EMPTY content specification; can not contain CHARACTERS"); + } sw.close(); // Then CDATA @@ -179,7 +181,9 @@ public void testInvalidEmptyContent() try { sw.writeCData("foo"); fail(modeDesc+" Expected a validation exception when trying to add CDATA into EMPTY content model"); - } catch (XMLValidationException vex) { } + } catch (XMLValidationException vex) { + assertMessageContains(vex, "Element has EMPTY content specification; can not contain CDATA"); + } sw.close(); // Then ENTITY @@ -188,7 +192,9 @@ public void testInvalidEmptyContent() try { sw.writeEntityRef("amp"); fail(modeDesc+" Expected a validation exception when trying to add CDATA into EMPTY content model"); - } catch (XMLValidationException vex) { } + } catch (XMLValidationException vex) { + assertMessageContains(vex, "Element has EMPTY content specification; can not contain ENTITY_REFERENCE"); + } sw.close(); // Then comment @@ -197,7 +203,9 @@ public void testInvalidEmptyContent() try { sw.writeComment("comment"); fail(modeDesc+" Expected a validation exception when trying to add comment into EMPTY content model"); - } catch (XMLValidationException vex) { } + } catch (XMLValidationException vex) { + assertMessageContains(vex, "Element has EMPTY content specification; can not contain COMMENT"); + } sw.close(); // Then proc. instr. @@ -206,7 +214,9 @@ public void testInvalidEmptyContent() try { sw.writeProcessingInstruction("target", "data"); fail(modeDesc+" Expected a validation exception when trying to add processing instruction into EMPTY content model"); - } catch (XMLValidationException vex) { } + } catch (XMLValidationException vex) { + assertMessageContains(vex, "Element has EMPTY content specification; can not contain PROCESSING_INSTRUCTION"); + } sw.close(); } } @@ -301,7 +311,7 @@ public void testInvalidAnyContent() sw.writeStartElement("unknown"); fail(modeDesc+" Expected a validation exception when trying to add an undeclared element"); } catch (XMLValidationException vex) { - // expected... + assertMessageContains(vex, "Undefined element encountered"); } sw.close(); @@ -312,7 +322,7 @@ public void testInvalidAnyContent() sw.writeAttribute("unknown", "value"); fail(modeDesc+" Expected a validation exception when trying to add an undeclared attribute"); } catch (XMLValidationException vex) { - // expected... + assertMessageContains(vex, "Element has no attribute \"unknown\""); } sw.close(); } diff --git a/src/test/java/stax2/vwstream/TestStructuralValidation.java b/src/test/java/stax2/vwstream/TestStructuralValidation.java index 7ce4ea33..d0beae51 100644 --- a/src/test/java/stax2/vwstream/TestStructuralValidation.java +++ b/src/test/java/stax2/vwstream/TestStructuralValidation.java @@ -64,7 +64,7 @@ public void testInvalidRootElem() sw.writeStartElement("branch"); fail(modeDesc+" Expected a validation exception when trying to write wrong root element"); } catch (XMLValidationException vex) { - // expected... + assertMessageContains(vex, "Unexpected root element ; expected as per DOCTYPE declaration"); } // should not continue after exception; state may not be valid @@ -74,7 +74,7 @@ public void testInvalidRootElem() sw.writeStartElement("undefined"); fail(modeDesc+" Expected a validation exception when trying to write an undefined root element"); } catch (XMLValidationException vex) { - // expected... + assertMessageContains(vex, "Undefined element encountered"); } // and same for explicitly empty element; wrong root @@ -84,7 +84,7 @@ public void testInvalidRootElem() sw.writeEmptyElement("branch"); fail(modeDesc+" Expected a validation exception when trying to write wrong root element"); } catch (XMLValidationException vex) { - // expected... + assertMessageContains(vex, "Unexpected root element ; expected as per DOCTYPE declaration"); } } } @@ -156,7 +156,7 @@ public void testInvalidStructure() sw.writeEndElement(); // for root fail(modeDesc+" Expected a validation exception when omitting non-optional element"); } catch (XMLValidationException vex) { - // expected... + assertMessageContains(vex, "Validation error, element : Expected or "); } // should not continue after exception; state may not be valid @@ -169,7 +169,7 @@ public void testInvalidStructure() sw.writeEmptyElement("end"); fail(modeDesc+" Expected a validation exception when omitting non-optional element"); } catch (XMLValidationException vex) { - // expected... + assertMessageContains(vex, "Validation error, encountered element as a child of : Expected "); } } } @@ -234,7 +234,7 @@ public void testInvalidNsElem() sw.writeStartElement(NS_PREFIX2, "root", NS_URI); fail(modeDesc+" Expected a validation exception when passing wrong (unexpected) ns for element"); } catch (XMLValidationException vex) { - // expected... + assertMessageContains(vex, "Undefined element encountered"); } // should not continue after exception; state may not be valid @@ -245,7 +245,7 @@ public void testInvalidNsElem() sw.writeEmptyElement(NS_PREFIX2, NS_URI, "root"); fail(modeDesc+" Expected a validation exception when passing wrong (unexpected) ns for element"); } catch (XMLValidationException vex) { - // expected... + assertMessageContains(vex, "Undefined element encountered"); } // Oh, and finally, using non-ns DTD: @@ -255,7 +255,7 @@ public void testInvalidNsElem() sw.writeEmptyElement(NS_PREFIX, NS_URI, "root"); fail(modeDesc+" Expected a validation exception when passing wrong (unexpected) ns for element"); } catch (XMLValidationException vex) { - // expected... + assertMessageContains(vex, "Undefined element encountered"); } } } diff --git a/src/test/java/wstxtest/BaseWstxTest.java b/src/test/java/wstxtest/BaseWstxTest.java index 8bcb5966..0361333e 100644 --- a/src/test/java/wstxtest/BaseWstxTest.java +++ b/src/test/java/wstxtest/BaseWstxTest.java @@ -234,38 +234,6 @@ protected static void setFixContent(XMLOutputFactory f, boolean state) ////////////////////////////////////////////////// */ - /** - * Method that will iterate through contents of an XML document - * using specified stream reader; will also access some of data - * to make sure reader reads most of lazy-loadable data. - * Method is usually called to try to get an exception for invalid - * content. - * - * @return Dummy value calculated on contents; used to make sure - * no dead code is eliminated - */ - @Override - protected int streamThrough(XMLStreamReader sr) - throws XMLStreamException - { - int result = 0; - - while (sr.hasNext()) { - int type = sr.next(); - result += type; - if (sr.hasText()) { - // will also do basic verification for text content, to - // see that all text accessor methods return same content - result += getAndVerifyText(sr).hashCode(); - } - if (sr.hasName()) { - result += sr.getName().hashCode(); - } - } - - return result; - } - @Override protected int streamThroughFailing(XMLInputFactory f, String contents, String msg) diff --git a/src/test/java/wstxtest/msv/TestW3CSchema.java b/src/test/java/wstxtest/msv/TestW3CSchema.java index 579d6967..d894cba5 100644 --- a/src/test/java/wstxtest/msv/TestW3CSchema.java +++ b/src/test/java/wstxtest/msv/TestW3CSchema.java @@ -1,10 +1,17 @@ package wstxtest.msv; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.Writer; + import javax.xml.stream.*; import org.codehaus.stax2.*; import org.codehaus.stax2.validation.*; +import com.ctc.wstx.stax.WstxInputFactory; +import com.ctc.wstx.stax.WstxOutputFactory; + import wstxtest.vstream.BaseValidationTest; /** @@ -17,7 +24,7 @@ public class TestW3CSchema /** * Sample schema, using sample 'personal.xsd' found from the web */ - final static String SIMPLE_NON_NS_SCHEMA = "\n" + protected final static String SIMPLE_NON_NS_SCHEMA = "\n" + "\n" + "\n" + "\n" @@ -78,10 +85,10 @@ public class TestW3CSchema final static String SIMPLE_XML = "" + "" + " " + "FamilyFred" + " " - + " " + " " + + " " + " " + " " + " BlowJoe" - + " " + " " + " " + ""; + + " " + " " + " " + ""; /** * Test validation against a simple document valid according to a very @@ -90,40 +97,59 @@ public class TestW3CSchema public void testSimpleNonNs() throws XMLStreamException { XMLValidationSchema schema = parseW3CSchema(SIMPLE_NON_NS_SCHEMA); - XMLStreamReader2 sr = getReader(SIMPLE_XML); + String XML = SIMPLE_XML; + XMLStreamReader2 sr = getReader(XML); sr.validateAgainst(schema); + StringWriter writer = new StringWriter(); + XMLStreamWriter2 sw = (XMLStreamWriter2) getOutputFactory().createXMLStreamWriter(writer); + sw.validateAgainst(schema); + sw.copyEventFromReader(sr, false); + try { assertTokenType(START_ELEMENT, sr.next()); assertEquals("personnel", sr.getLocalName()); + sw.copyEventFromReader(sr, false); while (sr.hasNext()) { /* int type = */sr.next(); + sw.copyEventFromReader(sr, false); } } catch (XMLValidationException vex) { fail("Did not expect validation exception, got: " + vex); } assertTokenType(END_DOCUMENT, sr.getEventType()); + assertEquals(XML.replace("'", "\""), writer.toString()); } public void testSimplePartialNonNs() throws XMLStreamException { XMLValidationSchema schema = parseW3CSchema(SIMPLE_NON_NS_SCHEMA); - XMLStreamReader2 sr = getReader(SIMPLE_XML); + String XML = SIMPLE_XML; + XMLStreamReader2 sr = getReader(XML); + StringWriter writer = new StringWriter(); + XMLStreamWriter2 sw = (XMLStreamWriter2) getOutputFactory().createXMLStreamWriter(writer); + sw.copyEventFromReader(sr, false); + assertTokenType(START_ELEMENT, sr.next()); assertEquals("personnel", sr.getLocalName()); + sw.copyEventFromReader(sr, false); sr.validateAgainst(schema); + sw.validateAgainst(schema); try { assertTokenType(START_ELEMENT, sr.next()); assertEquals("person", sr.getLocalName()); + sw.copyEventFromReader(sr, false); while (sr.hasNext()) { /* int type = */sr.next(); + sw.copyEventFromReader(sr, false); } } catch (XMLValidationException vex) { fail("Did not expect validation exception, got: " + vex); } assertTokenType(END_DOCUMENT, sr.getEventType()); + assertEquals(XML.replace("'", "\""), writer.toString()); } /** @@ -147,7 +173,7 @@ public void testSimpleNonNsUndefinedId() throws XMLStreamException + "FG" + ""; verifyFailure(XML, schema, "undefined referenced id ('m3')", - "Undefined ID 'm3'"); + "Undefined ID 'm3'", true, true, false); } public void testSimpleDataTypes() throws XMLStreamException @@ -192,6 +218,18 @@ public void testSimpleDataTypes() throws XMLStreamException } sr.close(); + // validate the same document on the writer side + sr = getReader(XML); + StringWriter writer = new StringWriter(); + XMLStreamWriter2 sw = (XMLStreamWriter2) getOutputFactory().createXMLStreamWriter(writer); + sw.validateAgainst(schema); + sw.copyEventFromReader(sr, true); + while (sr.hasNext()) { + /* int type = */sr.next(); + sw.copyEventFromReader(sr, true); + } + assertEquals(XML.replace("\r", ""), writer.toString()); + // Then invalid (wrong type for value) XML = "34b1.00"; sr.validateAgainst(schema); @@ -224,33 +262,28 @@ public void testSimpleText() throws XMLStreamException + ""; XMLValidationSchema schema = parseW3CSchema(SCHEMA); - // First, 3 valid docs: - String XML = "xyz"; - XMLStreamReader2 sr = getReader(XML); - sr.validateAgainst(schema); - streamThrough(sr); - sr.close(); - - XML = ""; - sr = getReader(XML); - sr.validateAgainst(schema); - streamThrough(sr); - sr.close(); + String XML = null; + for (ValidationMode mode : ValidationMode.values()) { + // First, 3 valid docs: + XML = "xyz"; + mode.validate(schema, XML); + + XML = ""; + mode.validate(schema, XML, ""); + + XML = ""; + mode.validate(schema, XML, ""); + } - XML = ""; - sr = getReader(XML); - sr.validateAgainst(schema); - streamThrough(sr); - sr.close(); // Then invalid? XML = ""; - sr = getReader(XML); + XMLStreamReader2 sr = getReader(XML); sr.validateAgainst(schema); verifyFailure(XML, schema, "should warn about wrong root element", "tag name \"foobar\" is not allowed", false); } - + /** * Test for reproducing [WSTX-191] */ @@ -283,20 +316,24 @@ public void testConstrainedText() throws XMLStreamException ""); _testValidDesc(schema, "??"); - _testValidDesc(schema, ""); - _testValidDesc(schema, ""); + _testValidDesc(schema, "", ""); + _testValidDesc(schema, "", ""); _testValidDesc(schema, ""); } - private void _testValidDesc(XMLValidationSchema schema, String descSnippet) throws XMLStreamException + private void _testValidDesc(XMLValidationSchema schema, String descSnippet) throws XMLStreamException { + _testValidDesc(schema, descSnippet, descSnippet); + } + private void _testValidDesc(XMLValidationSchema schema, String descSnippet, String expectedSnippet) throws XMLStreamException { - // These should all be valid according to the schema - String XML = "" - + descSnippet + ""; - XMLStreamReader2 sr = getReader(XML); - sr.validateAgainst(schema); - streamThrough(sr); - sr.close(); + for (ValidationMode mode : ValidationMode.values()) { + // These should all be valid according to the schema + String XML = "" + + descSnippet + ""; + String expectedXML = "" + + expectedSnippet + ""; + mode.validate(schema, XML, expectedXML.replace("'", "\"")); + } } public void testValidationHandler() throws XMLStreamException @@ -318,15 +355,14 @@ public void reportProblem(XMLValidationProblem problem) } }); sr.validateAgainst(schema); - boolean threw = false; try { while (sr.hasNext()) { /* int type = */sr.next(); } + fail("Expected LocalValidationError"); } catch (LocalValidationError lve) { - threw = true; + assertEquals("tag name \"foobar\" is not allowed. Possible tag names are: ", lve.problem.getMessage()); } - assertTrue(threw); } /* @@ -362,4 +398,5 @@ public XMLValidationProblem getProblem() { return problem; } } + } diff --git a/src/test/java/wstxtest/msv/TestW3CSchemaTypes.java b/src/test/java/wstxtest/msv/TestW3CSchemaTypes.java index 3295b62d..d669de53 100644 --- a/src/test/java/wstxtest/msv/TestW3CSchemaTypes.java +++ b/src/test/java/wstxtest/msv/TestW3CSchemaTypes.java @@ -6,6 +6,7 @@ import org.codehaus.stax2.validation.*; import wstxtest.vstream.BaseValidationTest; +import wstxtest.vstream.BaseValidationTest.ValidationMode; import java.io.StringWriter; @@ -45,9 +46,9 @@ public class TestW3CSchemaTypes public void testSimpleValidInt() throws Exception { XMLValidationSchema schema = parseW3CSchema(SCHEMA_INT); - XMLStreamReader2 sr = getReader("129"); - sr.validateAgainst(schema); - streamThrough(sr); + for (ValidationMode mode : ValidationMode.values()) { + mode.validate(schema, "129"); + } } public void testSimpleInvalidInt() throws Exception @@ -62,9 +63,9 @@ public void testSimpleInvalidInt() throws Exception public void testSimpleValidFloat() throws Exception { XMLValidationSchema schema = parseW3CSchema(SCHEMA_FLOAT); - XMLStreamReader2 sr = getReader("1.00"); - sr.validateAgainst(schema); - streamThrough(sr); + for (ValidationMode mode : ValidationMode.values()) { + mode.validate(schema, "1.00"); + } } public void testSimpleInvalidFloat() throws Exception diff --git a/src/test/java/wstxtest/stream/TestXmlId.java b/src/test/java/wstxtest/stream/TestXmlId.java index c55370a8..0a3dbc5c 100644 --- a/src/test/java/wstxtest/stream/TestXmlId.java +++ b/src/test/java/wstxtest/stream/TestXmlId.java @@ -159,7 +159,7 @@ private void doTestInvalid(boolean nsAware, boolean coal) assertTokenType(START_ELEMENT, sr.next()); fail("Expected a validation exception for invalid Xml:id attribute declaration"); } catch (XMLValidationException vex) { - //System.err.println("VLD exc -> "+vex); + assertMessageContains(vex, "Attribute xml:id has to have attribute type of ID, as per Xml:id specification"); } } diff --git a/src/test/java/wstxtest/vstream/BaseValidationTest.java b/src/test/java/wstxtest/vstream/BaseValidationTest.java index b9d0c544..4bdf6492 100644 --- a/src/test/java/wstxtest/vstream/BaseValidationTest.java +++ b/src/test/java/wstxtest/vstream/BaseValidationTest.java @@ -1,13 +1,18 @@ package wstxtest.vstream; import java.io.StringReader; +import java.io.StringWriter; import java.net.URL; import javax.xml.stream.XMLStreamException; import org.codehaus.stax2.XMLStreamReader2; +import org.codehaus.stax2.XMLStreamWriter2; import org.codehaus.stax2.validation.*; +import com.ctc.wstx.stax.WstxInputFactory; +import com.ctc.wstx.stax.WstxOutputFactory; + public abstract class BaseValidationTest extends wstxtest.stream.BaseStreamTest { @@ -51,13 +56,32 @@ protected void verifyFailure(String xml, XMLValidationSchema schema, String fail } protected void verifyFailure(String xml, XMLValidationSchema schema, String failMsg, - String failPhrase, boolean strict) throws XMLStreamException + String failPhrase, boolean strict) throws XMLStreamException + { + verifyFailure(xml, schema, failMsg, failPhrase, strict, true, false); + verifyFailure(xml, schema, failMsg, failPhrase, strict, false, true); + } + + protected void verifyFailure(String xml, XMLValidationSchema schema, String failMsg, + String failPhrase, boolean strict, + boolean validateReader, boolean validateWriter) throws XMLStreamException { XMLStreamReader2 sr = constructStreamReader(getInputFactory(), xml); - sr.validateAgainst(schema); + if (validateReader) { + sr.validateAgainst(schema); + } + XMLStreamWriter2 sw = null; + if (validateWriter) { + sw = (XMLStreamWriter2) getOutputFactory().createXMLStreamWriter(new StringWriter()); + sw.validateAgainst(schema); + sw.copyEventFromReader(sr, false); + } try { while (sr.hasNext()) { /* int type = */sr.next(); + if (validateWriter) { + sw.copyEventFromReader(sr, false); + } } fail("Expected validity exception for " + failMsg); } catch (XMLValidationException vex) { @@ -79,4 +103,46 @@ protected void verifyFailure(String xml, XMLValidationSchema schema, String fail + "; instead got " + sex.getMessage()); } } + + public enum ValidationMode { + reader() { + @Override + public void validate(XMLValidationSchema schema, String XML, String expectedXML) throws XMLStreamException { + XMLStreamReader2 sr = (XMLStreamReader2) new WstxInputFactory().createXMLStreamReader(new StringReader(XML)); + sr.validateAgainst(schema); + streamThrough(sr); + assertTokenType(END_DOCUMENT, sr.getEventType()); + sr.close(); + } + + }, + writerNsSimple() { + + @Override + public void validate(XMLValidationSchema schema, String XML, String expectedXML) + throws XMLStreamException { + XMLStreamReader2 sr = (XMLStreamReader2) new WstxInputFactory().createXMLStreamReader(new StringReader(XML)); + + StringWriter writer = new StringWriter(); + WstxOutputFactory f = new WstxOutputFactory(); + f.getConfig().doSupportNamespaces(true); + f.getConfig().enableAutomaticNamespaces(false); + XMLStreamWriter2 sw = (XMLStreamWriter2) f.createXMLStreamWriter(writer); + sw.validateAgainst(schema); + sw.copyEventFromReader(sr, false); + while (sr.hasNext()) { + /* int type = */sr.next(); + sw.copyEventFromReader(sr, false); + } + assertTokenType(END_DOCUMENT, sr.getEventType()); + sr.close(); + sw.close(); + assertEquals(expectedXML, writer.toString()); + } + }; + public void validate(XMLValidationSchema schema, String XML) throws XMLStreamException { + validate(schema, XML, XML); + } + public abstract void validate(XMLValidationSchema schema, String XML, String expectedXML) throws XMLStreamException; + } } diff --git a/src/test/java/wstxtest/vstream/TestDTD.java b/src/test/java/wstxtest/vstream/TestDTD.java index b1d10ba3..2f96f7d5 100644 --- a/src/test/java/wstxtest/vstream/TestDTD.java +++ b/src/test/java/wstxtest/vstream/TestDTD.java @@ -57,10 +57,9 @@ public void testFullValidationOk() throws XMLStreamException { String XML = ""; XMLValidationSchema schema = parseDTDSchema(SIMPLE_DTD); - XMLStreamReader2 sr = getReader(XML); - sr.validateAgainst(schema); - while (sr.next() != END_DOCUMENT) { } - sr.close(); + for (ValidationMode mode : ValidationMode.values()) { + mode.validate(schema, XML, ""); + } } // [woodstox#23] @@ -70,7 +69,6 @@ public void testFullValidationIssue23() throws XMLStreamException +"\n" ; String XML = "foobar"; - XMLInputFactory f = getInputFactory(); /* Resolver resolver = new XMLResolver() { @@ -85,19 +83,9 @@ public Object resolveEntity(String publicID, String systemID, String baseURI, St XMLValidationSchemaFactory schemaFactory = XMLValidationSchemaFactory.newInstance(XMLValidationSchema.SCHEMA_ID_DTD); XMLValidationSchema schema = schemaFactory.createSchema(new StringReader(INPUT_DTD)); - XMLStreamReader2 sr = (XMLStreamReader2)f.createXMLStreamReader( - new StringReader(XML)); - - sr.validateAgainst(schema); - while (sr.next() != END_DOCUMENT) { - /* - System.err.println("Curr == "+sr.getEventType()); - if (sr.getEventType() == CHARACTERS) { - System.err.println(" text: "+sr.getText()); - } - */ + for (ValidationMode mode : ValidationMode.values()) { + mode.validate(schema, XML, "foobar"); } - sr.close(); } /** @@ -107,13 +95,11 @@ public Object resolveEntity(String publicID, String systemID, String baseURI, St public void testPartialValidationOk() throws XMLStreamException { - String XML = ""; + String XML = ""; XMLValidationSchema schema = parseDTDSchema(SIMPLE_DTD); - XMLStreamReader2 sr = getReader(XML); - assertTokenType(START_ELEMENT, sr.next()); - sr.validateAgainst(schema); - while (sr.next() != END_DOCUMENT) { } - sr.close(); + for (ValidationMode mode : ValidationMode.values()) { + mode.validate(schema, XML); + } } /* @@ -168,14 +154,6 @@ public void testSchemaWithFunnyFilename() ////////////////////////////////////////////////////// */ - private XMLStreamReader2 getReader(String contents) - throws XMLStreamException - { - XMLInputFactory f = getInputFactory(); - setValidating(f, false); - return constructStreamReader(f, contents); - } - private XMLStreamReader getValidatingReader(String contents, XMLReporter rep) throws XMLStreamException { diff --git a/src/test/java/wstxtest/vstream/TestDTDErrorCollection104Test.java b/src/test/java/wstxtest/vstream/TestDTDErrorCollection104Test.java index 739f42bf..0e0ce4fe 100644 --- a/src/test/java/wstxtest/vstream/TestDTDErrorCollection104Test.java +++ b/src/test/java/wstxtest/vstream/TestDTDErrorCollection104Test.java @@ -3,18 +3,27 @@ import stax2.BaseStax2Test; import java.io.StringReader; +import java.io.StringWriter; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import javax.xml.stream.*; import org.codehaus.stax2.XMLStreamReader2; +import org.codehaus.stax2.XMLStreamWriter2; import org.codehaus.stax2.validation.ValidationProblemHandler; import org.codehaus.stax2.validation.XMLValidationException; import org.codehaus.stax2.validation.XMLValidationProblem; import org.codehaus.stax2.validation.XMLValidationSchema; import org.codehaus.stax2.validation.XMLValidationSchemaFactory; +import com.ctc.wstx.stax.WstxOutputFactory; +import com.ctc.wstx.sw.RepairingNsStreamWriter; +import com.ctc.wstx.sw.SimpleNsStreamWriter; + public class TestDTDErrorCollection104Test extends BaseStax2Test { @@ -26,78 +35,97 @@ public void testValidationBeyondUnknownElement() throws Exception " \n" + " \n" + " \n" + - "\n"; + ""; final String INPUT_DTD = "\n" +"\n" ; + final List probs = new ArrayList(); + XMLInputFactory f = getInputFactory(); setCoalescing(f, true); XMLValidationSchemaFactory schemaFactory = XMLValidationSchemaFactory.newInstance(XMLValidationSchema.SCHEMA_ID_DTD); XMLValidationSchema schema = schemaFactory.createSchema(new StringReader(INPUT_DTD)); - XMLStreamReader2 sr = (XMLStreamReader2)f.createXMLStreamReader( - new StringReader(DOC)); - - final List probs = new ArrayList(); - - sr.validateAgainst(schema); - sr.setValidationProblemHandler(new ValidationProblemHandler() { - @Override - public void reportProblem(XMLValidationProblem problem) - throws XMLValidationException { - probs.add(problem); - } - }); - - assertTokenType(START_ELEMENT, sr.next()); - assertEquals("map", sr.getLocalName()); - - sr.next(); // SPACE or CHARACTERS - assertTokenType(START_ELEMENT, sr.next()); - assertEquals("val", sr.getLocalName()); - assertEquals(1, probs.size()); - assertEquals("Undefined element encountered", - probs.get(0).getMessage()); - - sr.next(); // SPACE or CHARACTERS - assertEquals(1, probs.size()); - - // From this point on, however, behavior bit unclear except - // that for DTD I guess we can at least check for undefined - // cases.... + { + XMLStreamReader2 sr = (XMLStreamReader2)f.createXMLStreamReader( + new StringReader(DOC)); + + sr.validateAgainst(schema); + sr.setValidationProblemHandler(new ValidationProblemHandler() { + @Override + public void reportProblem(XMLValidationProblem problem) + throws XMLValidationException { + probs.add(problem); + } + }); + + assertTokenType(START_ELEMENT, sr.next()); + assertEquals("map", sr.getLocalName()); + + sr.next(); // SPACE or CHARACTERS + assertTokenType(START_ELEMENT, sr.next()); + assertEquals("val", sr.getLocalName()); + assertEquals(1, probs.size()); + assertEquals("Undefined element encountered", + probs.get(0).getMessage()); + + sr.next(); // SPACE or CHARACTERS + assertEquals(1, probs.size()); + + // From this point on, however, behavior bit unclear except + // that for DTD I guess we can at least check for undefined + // cases.... + + assertTokenType(START_ELEMENT, sr.next()); + assertEquals("prop", sr.getLocalName()); + // not defined either so: + assertEquals(2, probs.size()); + assertEquals("Undefined element encountered", + probs.get(1).getMessage()); + + assertTokenType(END_ELEMENT, sr.next()); + assertEquals("prop", sr.getLocalName()); + assertEquals(2, probs.size()); + + sr.next(); // SPACE or CHARACTERS + assertEquals(2, probs.size()); + assertTokenType(END_ELEMENT, sr.next()); + assertEquals("val", sr.getLocalName()); + assertEquals(2, probs.size()); + + sr.next(); // SPACE or CHARACTERS + assertTokenType(END_ELEMENT, sr.next()); + assertEquals("map", sr.getLocalName()); + assertEquals(3, probs.size()); + assertEquals("Validation error, element : Expected at least one element ", + probs.get(2).getMessage()); + + // Plus content model now missing (s) + assertTokenType(END_DOCUMENT, sr.next()); + assertEquals(3, probs.size()); + + sr.close(); + } - assertTokenType(START_ELEMENT, sr.next()); - assertEquals("prop", sr.getLocalName()); - // not defined either so: - assertEquals(2, probs.size()); - assertEquals("Undefined element encountered", - probs.get(1).getMessage()); - - assertTokenType(END_ELEMENT, sr.next()); - assertEquals("prop", sr.getLocalName()); - assertEquals(2, probs.size()); - - sr.next(); // SPACE or CHARACTERS - assertEquals(2, probs.size()); - assertTokenType(END_ELEMENT, sr.next()); - assertEquals("val", sr.getLocalName()); - assertEquals(2, probs.size()); - - sr.next(); // SPACE or CHARACTERS - assertTokenType(END_ELEMENT, sr.next()); - assertEquals("map", sr.getLocalName()); - assertEquals(3, probs.size()); - assertEquals("Validation error, element : Expected at least one element ", - probs.get(2).getMessage()); - - // Plus content model now missing (s) - assertTokenType(END_DOCUMENT, sr.next()); - assertEquals(3, probs.size()); - - sr.close(); + // now do the same on the writer side + // and make sure that the reported problems are the same + + { + // SimpleNsStreamWriter + StringWriter writer = new StringWriter(); + SimpleNsStreamWriter sw = (SimpleNsStreamWriter) stax2.BaseStax2Test.constructStreamWriter(writer, true, false); + validateWriter(DOC, probs, f, schema, writer, sw); + } + { + // RepairingNsStreamWriter + StringWriter writer = new StringWriter(); + RepairingNsStreamWriter sw = (RepairingNsStreamWriter) stax2.BaseStax2Test.constructStreamWriter(writer, true, true); + validateWriter(DOC, probs, f, schema, writer, sw); + } } + } diff --git a/src/test/java/wstxtest/vstream/TestInvalidAttributeValue.java b/src/test/java/wstxtest/vstream/TestInvalidAttributeValue.java index 0bf9554a..cd9c4001 100644 --- a/src/test/java/wstxtest/vstream/TestInvalidAttributeValue.java +++ b/src/test/java/wstxtest/vstream/TestInvalidAttributeValue.java @@ -3,6 +3,7 @@ import stax2.BaseStax2Test; import java.io.StringReader; +import java.io.StringWriter; import java.util.ArrayList; import java.util.List; @@ -15,12 +16,14 @@ import org.codehaus.stax2.validation.XMLValidationSchema; import org.codehaus.stax2.validation.XMLValidationSchemaFactory; +import com.ctc.wstx.sw.SimpleNsStreamWriter; + public class TestInvalidAttributeValue extends BaseStax2Test { public void testInvalidAttributeValue() throws Exception { - final String DOC = "\n"; + final String DOC = ""; final String INPUT_DTD = "\n" @@ -53,5 +56,17 @@ public void reportProblem(XMLValidationProblem problem) final String verboseValue = sr.getAttributeValue(null, "verbose"); assertEquals("yes", verboseValue); + + assertEquals(1, probs.size()); + assertEquals("Element has no attribute \"verbose\"", probs.get(0).getMessage()); + + // now do the same on the writer side + // and make sure that the reported problems are the same + { + // SimpleNsStreamWriter + StringWriter writer = new StringWriter(); + SimpleNsStreamWriter sw = (SimpleNsStreamWriter) stax2.BaseStax2Test.constructStreamWriter(writer, true, false); + validateWriter(DOC, probs, f, schema, writer, sw); + } } } diff --git a/src/test/java/wstxtest/vstream/TestRelaxNG.java b/src/test/java/wstxtest/vstream/TestRelaxNG.java index 705ab693..9817d318 100644 --- a/src/test/java/wstxtest/vstream/TestRelaxNG.java +++ b/src/test/java/wstxtest/vstream/TestRelaxNG.java @@ -1,10 +1,16 @@ package wstxtest.vstream; +import java.io.StringWriter; + import javax.xml.stream.*; import org.codehaus.stax2.*; import org.codehaus.stax2.validation.*; +import com.ctc.wstx.sw.NonNsStreamWriter; +import com.ctc.wstx.sw.RepairingNsStreamWriter; +import com.ctc.wstx.sw.SimpleNsStreamWriter; + /** * This is a simple base-line "smoke test" that checks that RelaxNG * validation works at least minimally. @@ -12,7 +18,7 @@ public class TestRelaxNG extends BaseValidationTest { - final static String SIMPLE_RNG_SCHEMA = + protected final static String SIMPLE_RNG_SCHEMA = "\n" +" \n" +" \n" @@ -58,11 +64,11 @@ public void testSimpleNonNs() String XML = "" +"\n" - +" \n" + +" \n" +" foobar\n" +" Foo Bar\n" +" " - +" \n" + +" \n" +" fuzzy\n" +" adjective\n" +" " @@ -70,21 +76,9 @@ public void testSimpleNonNs() ; XMLValidationSchema schema = parseRngSchema(SIMPLE_RNG_SCHEMA); - XMLStreamReader2 sr = getReader(XML); - sr.validateAgainst(schema); - - try { - assertTokenType(START_ELEMENT, sr.next()); - assertEquals("dict", sr.getLocalName()); - - while (sr.hasNext()) { - sr.next(); - } - } catch (XMLValidationException vex) { - fail("Did not expect validation exception, got: "+vex); + for (ValidationMode mode : ValidationMode.values()) { + mode.validate(schema, XML); } - - assertTokenType(END_DOCUMENT, sr.getEventType()); } /** @@ -102,7 +96,7 @@ public void testInvalidNonNs() +" foobar\n" +" Foo Bar\n" +""; - verifyRngFailure(XML, schema, "wrong root element", + verifyFailure(XML, schema, "wrong root element", "is not allowed. Possible tag names are"); // Then, wrong child ordering: @@ -111,21 +105,21 @@ public void testInvalidNonNs() +" Foo Bar\n" +" foobar\n" +""; - verifyRngFailure(XML, schema, "illegal child element ordering", + verifyFailure(XML, schema, "illegal child element ordering", "tag name \"description\" is not allowed. Possible tag names are"); // Then, missing children: XML = "\n" +"\n" +""; - verifyRngFailure(XML, schema, "missing children", + verifyFailure(XML, schema, "missing children", "uncompleted content model. expecting: "); XML = "\n" +"\n" +"word" +""; - verifyRngFailure(XML, schema, "incomplete children", + verifyFailure(XML, schema, "incomplete children", "uncompleted content model. expecting: "); // Then illegal text in non-mixed element @@ -134,7 +128,7 @@ public void testInvalidNonNs() +" foobar\n" +" Foo Bar\n" +""; - verifyRngFailure(XML, schema, "invalid non-whitespace text", + verifyFailure(XML, schema, "invalid non-whitespace text", "Element has non-mixed content specification; can not contain non-white space text"); // missing attribute @@ -149,14 +143,14 @@ public void testInvalidNonNs() +" foobar\n" +" Foo Bar\n" +""; - verifyRngFailure(XML, schema, "undeclared attribute", + verifyFailure(XML, schema, "undeclared attribute", "unexpected attribute \"attr\""); XML = "\n" +"" +" foobar\n" +" Foo Bar\n" +""; - verifyRngFailure(XML, schema, "undeclared attribute", + verifyFailure(XML, schema, "undeclared attribute", "unexpected attribute \"type\""); } @@ -164,27 +158,15 @@ public void testSimpleNs() throws XMLStreamException { String XML = "\n" - +" \n" - +" \n" + +" \n" + +" \n" +"" ; XMLValidationSchema schema = parseRngSchema(SIMPLE_RNG_NS_SCHEMA); - XMLStreamReader2 sr = getReader(XML); - sr.validateAgainst(schema); - - try { - assertTokenType(START_ELEMENT, sr.next()); - assertEquals("root", sr.getLocalName()); - - while (sr.hasNext()) { - sr.next(); - } - } catch (XMLValidationException vex) { - fail("Did not expect validation exception, got: "+vex); + for (ValidationMode mode : ValidationMode.values()) { + mode.validate(schema, XML); } - - assertTokenType(END_DOCUMENT, sr.getEventType()); } /** @@ -200,21 +182,21 @@ public void testInvalidNs() String XML = "\n" +"\n" +""; - verifyRngFailure(XML, schema, "wrong root element", + verifyFailure(XML, schema, "wrong root element", "namespace URI of tag \"root\" is wrong"); // Wrong child namespace XML = "\n" +"\n" +""; - verifyRngFailure(XML, schema, "wrong child element namespace", + verifyFailure(XML, schema, "wrong child element namespace", "namespace URI of tag \"leaf\" is wrong."); // Wrong attribute namespace XML = "\n" +"\n" +""; - verifyRngFailure(XML, schema, "wrong attribute namespace", + verifyFailure(XML, schema, "wrong attribute namespace", "unexpected attribute \"attr1\""); } @@ -232,66 +214,87 @@ public void testSimplePartialNonNs() String XML = "" +"" - +"" + +"" +"" +"" ; XMLValidationSchema schema = parseRngSchema(SIMPLE_RNG_SCHEMA); + for (StopValidatingMethod method : StopValidatingMethod.values()) { + { + StringWriter writer = new StringWriter(); + SimpleNsStreamWriter sw = (SimpleNsStreamWriter) constructStreamWriter(writer, true, false); + _testSimplePartialNonNS(XML, schema, sw, writer, method); + } + { + StringWriter writer = new StringWriter(); + RepairingNsStreamWriter sw = (RepairingNsStreamWriter) constructStreamWriter(writer, true, true); + _testSimplePartialNonNS(XML, schema, sw, writer, method); + } + { + StringWriter writer = new StringWriter(); + NonNsStreamWriter sw = (NonNsStreamWriter) constructStreamWriter(writer, false, false); + _testSimplePartialNonNS(XML, schema, sw, writer, method); + } + } + } + + private enum StopValidatingMethod {schema, validator} + + private void _testSimplePartialNonNS(String XML, XMLValidationSchema schema, XMLStreamWriter2 sw, + StringWriter writer, StopValidatingMethod method) throws XMLStreamException { XMLStreamReader2 sr = getReader(XML); XMLValidator vtor = sr.validateAgainst(schema); + + XMLValidator wVtor = sw.validateAgainst(schema); + sw.copyEventFromReader(sr, false); assertTokenType(START_ELEMENT, sr.next()); assertEquals("dict", sr.getLocalName()); + sw.copyEventFromReader(sr, false); assertTokenType(START_ELEMENT, sr.next()); assertEquals("term", sr.getLocalName()); + sw.copyEventFromReader(sr, false); /* So far so good; but here we'd get an exception... so * let's stop validating */ - assertSame(vtor, sr.stopValidatingAgainst(schema)); - try { - // And should be good to go - assertTokenType(START_ELEMENT, sr.next()); - assertEquals("invalid", sr.getLocalName()); - assertTokenType(END_ELEMENT, sr.next()); - assertEquals("invalid", sr.getLocalName()); - assertTokenType(END_ELEMENT, sr.next()); - assertEquals("term", sr.getLocalName()); - assertTokenType(END_ELEMENT, sr.next()); - assertEquals("dict", sr.getLocalName()); - assertTokenType(END_DOCUMENT, sr.next()); - } catch (XMLValidationException vex) { - fail("Did not expect validation exception after stopping validation, got: "+vex); + switch (method) { + case schema: + assertSame(vtor, sr.stopValidatingAgainst(schema)); + assertSame(wVtor, sw.stopValidatingAgainst(schema)); + break; + case validator: + assertSame(vtor, sr.stopValidatingAgainst(vtor)); + assertSame(wVtor, sw.stopValidatingAgainst(wVtor)); + break; + default: + throw new IllegalStateException(); } - sr.close(); - - // And let's do the same, just using the other stopValidatingAgainst method - sr = getReader(XML); - vtor = sr.validateAgainst(schema); - - assertTokenType(START_ELEMENT, sr.next()); - assertEquals("dict", sr.getLocalName()); - assertTokenType(START_ELEMENT, sr.next()); - assertEquals("term", sr.getLocalName()); - - assertSame(vtor, sr.stopValidatingAgainst(vtor)); try { // And should be good to go assertTokenType(START_ELEMENT, sr.next()); assertEquals("invalid", sr.getLocalName()); + sw.copyEventFromReader(sr, false); assertTokenType(END_ELEMENT, sr.next()); assertEquals("invalid", sr.getLocalName()); + sw.copyEventFromReader(sr, false); assertTokenType(END_ELEMENT, sr.next()); assertEquals("term", sr.getLocalName()); + sw.copyEventFromReader(sr, false); assertTokenType(END_ELEMENT, sr.next()); assertEquals("dict", sr.getLocalName()); + sw.copyEventFromReader(sr, false); assertTokenType(END_DOCUMENT, sr.next()); + sw.copyEventFromReader(sr, false); } catch (XMLValidationException vex) { fail("Did not expect validation exception after stopping validation, got: "+vex); } sr.close(); + sw.close(); + + assertEquals(XML, writer.toString()); } public void testSimpleEnumAttr() @@ -311,15 +314,14 @@ public void testSimpleEnumAttr() XMLValidationSchema schema = parseRngSchema(schemaDef); // First, simple valid document - String XML = ""; - XMLStreamReader2 sr = getReader(XML); - sr.validateAgainst(schema); - while (sr.next() != END_DOCUMENT) { } - sr.close(); + String XML = ""; + for (ValidationMode mode : ValidationMode.values()) { + mode.validate(schema, XML); + } // And then invalid one, with unrecognized value XML = ""; - verifyRngFailure(XML, schema, "enum attribute with unknown value", + verifyFailure(XML, schema, "enum attribute with unknown value", "attribute \"enumAttr\" has a bad value"); } @@ -351,19 +353,18 @@ public void testSimpleIdAttrs() // First, a simple valid document String XML = "" - +" \n" - +" \n" - +" \n" + +" \n" + +" \n" + +" \n" +"" ; - XMLStreamReader2 sr = getReader(XML); - sr.validateAgainst(schema); - while (sr.next() != END_DOCUMENT) { } - sr.close(); + for (ValidationMode mode : ValidationMode.values()) { + mode.validate(schema, XML); + } // Then one with malformed id XML = ""; - verifyRngFailure(XML, schema, "malformed id", + verifyFailure(XML, schema, "malformed id", "attribute \"id\" has a bad value"); // Then with malformed IDREF value (would be valid IDREFS) @@ -372,7 +373,7 @@ public void testSimpleIdAttrs() +" \n" +"" ; - verifyRngFailure(XML, schema, "malformed id", + verifyFailure(XML, schema, "malformed id", "attribute \"ref\" has a bad value"); // And then invalid one, with dangling ref @@ -380,16 +381,16 @@ public void testSimpleIdAttrs() +" \n" +"" ; - verifyRngFailure(XML, schema, "reference to undefined id", - "Undefined ID"); + verifyFailure(XML, schema, "reference to undefined id", + "Undefined ID", true, true, false); // and another one with some of refs undefined XML = "" +" \n" +"" ; - verifyRngFailure(XML, schema, "reference to undefined id", - "Undefined ID"); + verifyFailure(XML, schema, "reference to undefined id", + "Undefined ID", true, true, false); } public void testSimpleIntAttr() @@ -407,25 +408,25 @@ public void testSimpleIntAttr() XMLValidationSchema schema = parseRngSchema(schemaDef); // First, a simple valid document - XMLStreamReader2 sr = getReader(""); - sr.validateAgainst(schema); - while (sr.next() != END_DOCUMENT) { } - sr.close(); + String XML = ""; + for (ValidationMode mode : ValidationMode.values()) { + mode.validate(schema, XML); + } // Then one with invalid element value - verifyRngFailure("", + verifyFailure("", schema, "invalid integer attribute value", "does not satisfy the \"integer\" type"); // And missing attribute - verifyRngFailure("", + verifyFailure("", schema, "missing integer attribute value", "is missing \"nr\" attribute"); // And then two variations of having empty value - verifyRngFailure("", + verifyFailure("", schema, "missing integer attribute value", "does not satisfy the \"integer\" type"); - verifyRngFailure("", + verifyFailure("", schema, "missing integer attribute value", "does not satisfy the \"integer\" type"); } @@ -450,19 +451,19 @@ public void testSimpleBooleanElem2() XMLValidationSchema schema = parseRngSchema(schemaDef); // First, a simple valid document - XMLStreamReader2 sr = getReader("abctrue"); - sr.validateAgainst(schema); - while (sr.next() != END_DOCUMENT) { } - sr.close(); + String XML = "abctrue"; + for (ValidationMode mode : ValidationMode.values()) { + mode.validate(schema, XML); + } // Then another valid, but with empty tag for leaf1 - sr = getReader("false"); - sr.validateAgainst(schema); - while (sr.next() != END_DOCUMENT) { } - sr.close(); + XML = "false"; + for (ValidationMode mode : ValidationMode.values()) { + mode.validate(schema, XML); + } // And then one more invalid case - verifyRngFailure("true false", + verifyFailure("true false", schema, "missing boolean element value", "does not satisfy the \"boolean\" type"); } @@ -478,20 +479,42 @@ public void testPartialValidationOk() * wrap the doc... */ String XML = - "\n" - +"\n" - +"\n" - +" foobar\n" - +" Foo Bar\n" - +"\n" - +"" - ; + "\n" + +"\n" + +"\n" + +" foobar\n" + +" Foo Bar\n" + +"\n" + +"" + ; XMLValidationSchema schema = parseRngSchema(SIMPLE_RNG_SCHEMA); + { + StringWriter writer = new StringWriter(); + SimpleNsStreamWriter sw = (SimpleNsStreamWriter) constructStreamWriter(writer, true, false); + _testPartialValidationOk(XML, schema, sw, writer); + } + { + StringWriter writer = new StringWriter(); + NonNsStreamWriter sw = (NonNsStreamWriter) constructStreamWriter(writer, false, false); + _testPartialValidationOk(XML, schema, sw, writer); + } + } + + protected void _testPartialValidationOk(String XML, XMLValidationSchema schema, XMLStreamWriter2 sw, StringWriter writer) throws XMLStreamException { XMLStreamReader2 sr = getReader(XML); assertTokenType(START_ELEMENT, sr.next()); + sw.copyEventFromReader(sr, false); + sr.validateAgainst(schema); - while (sr.next() != END_DOCUMENT) { } + sw.validateAgainst(schema); + while (sr.hasNext()) { + sr.next(); + sw.copyEventFromReader(sr, false); + } sr.close(); + sw.close(); + + assertEquals(XML, writer.toString()); } @@ -508,37 +531,4 @@ private XMLStreamReader2 getReader(String contents) throws XMLStreamException return constructStreamReader(f, contents); } - private void verifyRngFailure(String xml, XMLValidationSchema schema, String failMsg, String failPhrase) - throws XMLStreamException - { - // By default, yes we are strict... - verifyRngFailure(xml, schema, failMsg, failPhrase, true); - } - - private void verifyRngFailure(String xml, XMLValidationSchema schema, String failMsg, String failPhrase, - boolean strict) - throws XMLStreamException - { - XMLStreamReader2 sr = getReader(xml); - sr.validateAgainst(schema); - try { - while (sr.hasNext()) { - /*int type =*/ sr.next(); - } - fail("Expected validity exception for "+failMsg); - } catch (XMLValidationException vex) { - String origMsg = vex.getMessage(); - String msg = (origMsg == null) ? "" : origMsg.toLowerCase(); - if (msg.indexOf(failPhrase.toLowerCase()) < 0) { - String actualMsg = "Expected validation exception for "+failMsg+", containing phrase '"+failPhrase+"': got '"+origMsg+"'"; - if (strict) { - fail(actualMsg); - } - warn("suppressing failure due to MSV bug, failure: '"+actualMsg+"'"); - } - // should get this specific type; not basic stream exception - } catch (XMLStreamException sex) { - fail("Expected XMLValidationException for "+failMsg); - } - } } diff --git a/src/test/java/wstxtest/vstream/TestW3CSchemaComplexTypes.java b/src/test/java/wstxtest/vstream/TestW3CSchemaComplexTypes.java index 23c1c32b..bc84f9dd 100644 --- a/src/test/java/wstxtest/vstream/TestW3CSchemaComplexTypes.java +++ b/src/test/java/wstxtest/vstream/TestW3CSchemaComplexTypes.java @@ -1,12 +1,18 @@ package wstxtest.vstream; +import java.io.StringWriter; + import javax.xml.stream.XMLStreamException; import org.codehaus.stax2.XMLInputFactory2; import org.codehaus.stax2.XMLStreamReader2; -import org.codehaus.stax2.validation.XMLValidationException; +import org.codehaus.stax2.XMLStreamWriter2; import org.codehaus.stax2.validation.XMLValidationSchema; +import com.ctc.wstx.sw.NonNsStreamWriter; +import com.ctc.wstx.sw.RepairingNsStreamWriter; +import com.ctc.wstx.sw.SimpleNsStreamWriter; + public class TestW3CSchemaComplexTypes extends BaseValidationTest { @@ -44,24 +50,54 @@ public void testMSVGithubIssue2() throws Exception +"" +"" +""); - XMLStreamReader2 sr = getReader("" - +"" + String XML = "" + +"" +"" - +""); - sr.validateAgainst(schema); + +""; - try { - assertTokenType(START_ELEMENT, sr.next()); - assertEquals("Root", sr.getLocalName()); - assertTokenType(START_ELEMENT, sr.next()); - assertEquals("Child", sr.getLocalName()); - assertTokenType(END_ELEMENT, sr.next()); - assertTokenType(END_ELEMENT, sr.next()); - assertTokenType(END_DOCUMENT, sr.next()); - } catch (XMLValidationException vex) { - fail("Did not expect validation exception, got: " + vex); + { + StringWriter writer = new StringWriter(); + SimpleNsStreamWriter sw = (SimpleNsStreamWriter) constructStreamWriter(writer, true, false); + _testMSVGithubIssue2(schema, XML, sw, writer); + } + { + StringWriter writer = new StringWriter(); + RepairingNsStreamWriter sw = (RepairingNsStreamWriter) constructStreamWriter(writer, true, true); + _testMSVGithubIssue2(schema, XML, sw, writer); } - assertTokenType(END_DOCUMENT, sr.getEventType()); + } + + private void _testMSVGithubIssue2(XMLValidationSchema schema, String XML, XMLStreamWriter2 sw, StringWriter writer) throws XMLStreamException { + XMLStreamReader2 sr = getReader(XML); + sr.validateAgainst(schema); + sw.validateAgainst(schema); + + + assertTokenType(START_ELEMENT, sr.next()); + assertEquals("Root", sr.getLocalName()); + sw.copyEventFromReader(sr, false); + + assertTokenType(START_ELEMENT, sr.next()); + assertEquals("Child", sr.getLocalName()); + sw.copyEventFromReader(sr, false); + + assertTokenType(END_ELEMENT, sr.next()); + sw.copyEventFromReader(sr, false); + + assertTokenType(END_ELEMENT, sr.next()); + sw.copyEventFromReader(sr, false); + + assertTokenType(END_DOCUMENT, sr.next()); + sw.copyEventFromReader(sr, false); + + assertTokenType(END_DOCUMENT, sr.getEventType()); + + sr.close(); + sw.close(); + + // the writers collapse empty elements + String expectedXML = XML.replace(">", "/>"); + assertEquals(expectedXML, writer.toString()); } /* diff --git a/src/test/java/wstxtest/vstream/TestXmlSpace.java b/src/test/java/wstxtest/vstream/TestXmlSpace.java index f1f6b325..b818e591 100644 --- a/src/test/java/wstxtest/vstream/TestXmlSpace.java +++ b/src/test/java/wstxtest/vstream/TestXmlSpace.java @@ -55,7 +55,7 @@ public void testSimpleNonNs() assertTokenType(START_ELEMENT, type); fail("Expected a validity exception for invalid xml:space declaration (ns-aware: "+nsAware+")"); } catch (XMLValidationException vex) { - ; // good + assertMessageContains(vex, "Attribute xml:space has to be defined of type enumerated, and have 1 or 2 values, 'default' and/or 'preserve'"); } sr.close(); @@ -71,7 +71,7 @@ public void testSimpleNonNs() assertTokenType(START_ELEMENT, type); fail("Expected a validity exception for invalid xml:space declaration (ns-aware: "+nsAware+")"); } catch (XMLValidationException vex) { - ; // good + assertMessageContains(vex, "Attribute xml:space has to be defined of type enumerated, and have 1 or 2 values, 'default' and/or 'preserve'"); } sr.close(); }