Skip to content

Commit

Permalink
Extend XMLStreamWriter validation test coverage by checking the writer
Browse files Browse the repository at this point in the history
validation wherever we test the reader validation
  • Loading branch information
ppalaga committed Jan 13, 2024
1 parent 80a45b9 commit 7c10488
Show file tree
Hide file tree
Showing 11 changed files with 500 additions and 319 deletions.
6 changes: 5 additions & 1 deletion src/main/java/com/ctc/wstx/sw/SimpleOutputElement.java
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,11 @@ public String getNamespaceURI() {
}

public QName getName() {
return QNameCreator.create(mURI, mLocalName, mPrefix);
if (mPrefix != null) {
return QNameCreator.create(mURI, mLocalName, mPrefix);
} else {
return new QName(mURI, mLocalName);
}
}

/*
Expand Down
52 changes: 51 additions & 1 deletion src/test/java/stax2/BaseStax2Test.java
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -578,6 +594,40 @@ protected void verifyException(Throwable e, String match)
}
}

protected static void validateWriter(final String DOC, final List<XMLValidationProblem> probs, XMLInputFactory f,
XMLValidationSchema schema, StringWriter writer, XMLStreamWriter2 sw) throws XMLStreamException {
sw.validateAgainst(schema);
final List<XMLValidationProblem> writerProbs = new ArrayList<XMLValidationProblem>();
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
Expand Down
32 changes: 0 additions & 32 deletions src/test/java/wstxtest/BaseWstxTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
104 changes: 71 additions & 33 deletions src/test/java/wstxtest/msv/TestW3CSchema.java
Original file line number Diff line number Diff line change
@@ -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;

/**
Expand Down Expand Up @@ -78,10 +85,10 @@ public class TestW3CSchema
final static String SIMPLE_XML = "<personnel>"
+ "<person id='a123' contr='true'>" + " <name>"
+ "<family>Family</family><given>Fred</given>" + " </name>"
+ " <url href='urn:something' />" + " </person>"
+ " <url href='urn:something'/>" + " </person>"
+ " <person id='b12'>"
+ " <name><family>Blow</family><given>Joe</given>"
+ " </name>" + " <url />" + " </person>" + "</personnel>";
+ " </name>" + " <url/>" + " </person>" + "</personnel>";

/**
* Test validation against a simple document valid according to a very
Expand All @@ -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());
}

/**
Expand Down Expand Up @@ -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 = "<item><quantity>34b</quantity><price>1.00</price></item>";
sr.validateAgainst(schema);
Expand Down Expand Up @@ -224,33 +262,28 @@ public void testSimpleText() throws XMLStreamException
+ "</xs:schema>";
XMLValidationSchema schema = parseW3CSchema(SCHEMA);

// First, 3 valid docs:
String XML = "<root>xyz</root>";
XMLStreamReader2 sr = getReader(XML);
sr.validateAgainst(schema);
streamThrough(sr);
sr.close();

XML = "<root />";
sr = getReader(XML);
sr.validateAgainst(schema);
streamThrough(sr);
sr.close();
String XML = null;
for (ValidationMode mode : ValidationMode.values()) {
// First, 3 valid docs:
XML = "<root>xyz</root>";
mode.validate(schema, XML);
XML = "<root />";
mode.validate(schema, XML, "<root/>");
XML = "<root></root>";
mode.validate(schema, XML, "<root/>");
}

XML = "<root></root>";
sr = getReader(XML);
sr.validateAgainst(schema);
streamThrough(sr);
sr.close();

// Then invalid?
XML = "<foobar />";
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]
*/
Expand Down Expand Up @@ -283,20 +316,24 @@ public void testConstrainedText() throws XMLStreamException
"<description><![CDATA[Du Texte]]></description>");
_testValidDesc(schema,
"<description>??</description><description><![CDATA[...]]></description>");
_testValidDesc(schema, "<description></description>");
_testValidDesc(schema, "<description />");
_testValidDesc(schema, "<description></description>", "<description/>");
_testValidDesc(schema, "<description />", "<description/>");
_testValidDesc(schema, "<description><![CDATA[]]></description>");
}

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 = "<catalog xmlns='http://www.mondomaine.fr/framework'>"
+ descSnippet + "</catalog>";
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 = "<catalog xmlns='http://www.mondomaine.fr/framework'>"
+ descSnippet + "</catalog>";
String expectedXML = "<catalog xmlns='http://www.mondomaine.fr/framework'>"
+ expectedSnippet + "</catalog>";
mode.validate(schema, XML, expectedXML.replace("'", "\""));
}
}

public void testValidationHandler() throws XMLStreamException
Expand Down Expand Up @@ -361,4 +398,5 @@ public XMLValidationProblem getProblem() {
return problem;
}
}

}
13 changes: 7 additions & 6 deletions src/test/java/wstxtest/msv/TestW3CSchemaTypes.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.codehaus.stax2.validation.*;

import wstxtest.vstream.BaseValidationTest;
import wstxtest.vstream.BaseValidationTest.ValidationMode;

import java.io.StringWriter;

Expand Down Expand Up @@ -45,9 +46,9 @@ public class TestW3CSchemaTypes
public void testSimpleValidInt() throws Exception
{
XMLValidationSchema schema = parseW3CSchema(SCHEMA_INT);
XMLStreamReader2 sr = getReader("<price>129</price>");
sr.validateAgainst(schema);
streamThrough(sr);
for (ValidationMode mode : ValidationMode.values()) {
mode.validate(schema, "<price>129</price>");
}
}

public void testSimpleInvalidInt() throws Exception
Expand All @@ -62,9 +63,9 @@ public void testSimpleInvalidInt() throws Exception
public void testSimpleValidFloat() throws Exception
{
XMLValidationSchema schema = parseW3CSchema(SCHEMA_FLOAT);
XMLStreamReader2 sr = getReader("<price>1.00</price>");
sr.validateAgainst(schema);
streamThrough(sr);
for (ValidationMode mode : ValidationMode.values()) {
mode.validate(schema, "<price>1.00</price>");
}
}

public void testSimpleInvalidFloat() throws Exception
Expand Down
Loading

0 comments on commit 7c10488

Please sign in to comment.