}
public void testOASISMicrosoftConformanceSuite()
throws IOException, ParsingException, XSLException {
Builder builder = new Builder();
NodeFactory stripper = new StrippingFactory();
Builder strippingBuilder = new Builder(stripper);
File base = new File("data");
base = new File(base, "oasis-xslt-testsuite");
base = new File(base, "TESTS");
File catalog = new File(base, "catalog.xml");
// The test suite need to be installed separately. If we can't
// find the catalog, we just don't run these tests.
if (catalog.exists()) {
Document doc = builder.build(catalog);
Element testsuite = doc.getRootElement();
Elements submitters = testsuite.getChildElements("test-catalog");
Element submitter = submitters.get(1);
Elements testcases = submitter.getChildElements("test-case");
for (int j = 0; j < testcases.size(); j++) {
Element testcase = testcases.get(j);
String id = testcase.getAttributeValue("id");
File root = new File(base, "MSFT_Conformance_Tests");
root = new File(root, testcase.getFirstChildElement("file-path").getValue());
File input = null;
File style = null;
File output = null;
Element scenario = testcase.getFirstChildElement("scenario");
Elements inputs = scenario.getChildElements("input-file");
for (int k = 0; k < inputs.size(); k++) {
Element file = inputs.get(k);
String role = file.getAttributeValue("role");
if ("principal-data".equals(role)) {
input = new File(root, file.getValue());
}
else if ("principal-stylesheet".equals(role)) {
style = new File(root, file.getValue());
}
} // end for
Elements outputs = scenario.getChildElements("output-file");
for (int k = 0; k < outputs.size(); k++) {
Element file = outputs.get(k);
String role = file.getAttributeValue("role");
if ("principal".equals(role)) {
// Fix up OASIS catalog bugs
File parent = new File(root.getParent());
parent = new File(parent, "REF_OUT");
parent = new File(parent, root.getName());
String outputFileName = file.getValue();
output = new File(parent, outputFileName);
}
} // end for
try {
Document styleDoc = builder.build(style);
boolean strip = indentYes(styleDoc);
if ("BVTs_bvt002".equals(id) || "BVTs_bvt077".equals(id)) {
// This has been fixed at least as of Xalan 2.6.0.
// However, it's a bug in earlier versions of Xalan
// including the one bundled with the JDK 1.4.2_05
continue;
}
else if ("XSLTFunctions_Bug76984".equals(id)) {
// This has been fixed at least as of Xalan 2.6.0.
// However, it's a bug in earlier versions of Xalan
// including the one bundled with the JDK 1.4.2_05
continue;
}
else if ("BVTs_bvt020".equals(id) || "BVTs_bvt022".equals(id)
|| "BVTs_bvt024".equals(id) || "BVTs_bvt058".equals(id)) {
// Either a test suite bug, or a recoverable
// error Xalan doesn't recover from.
continue;
}
else if ("BVTs_bvt038".equals(id)
|| "Namespace-alias__91785".equals(id)
|| "Namespace-alias__91786".equals(id)) {
// a recoverable error Xalan doesn't recover from properly
// http://issues.apache.org/jira/browse/XALANJ-1957
continue;
}
else if ("Namespace_XPath_CopyNamespaceNodeToOutput".equals(id)) {
// Xalan bug
// http://issues.apache.org/jira/browse/XALANJ-1959
continue;
}
else if ("Namespace-alias_Namespace-Alias_WithinRTF".equals(id)) {
// Xalan bug
// http://issues.apache.org/jira/browse/XALANJ-1960
continue;
}
else if ("Completeness__84361".equals(id)
|| "Namespace-alias__91781".equals(id)
|| "Namespace-alias__91782".equals(id)
|| "Namespace-alias_Namespace-Alias_Test1".equals(id)
|| "Namespace-alias_Namespace-Alias_Test2".equals(id)
) {
// a recoverable error Xalan doesn't recover from
continue;
}
else if ("Output__84008".equals(id)) {
// a recoverable error Xalan doesn't recover from
continue;
}
else if ("XSLTFunctions_ElementAvailFunctionFalseTest".equals(id)) {
// Xalan bug
// http://issues.apache.org/jira/browse/XALANJ-1961
continue;
}
else if ("XSLTFunctions_GenereateIdAppliedToNamespaceNodesOnDifferentElements".equals(id)) {
// Xalan bug
// http://issues.apache.org/jira/browse/XALANJ-1962
continue;
}
else if ("XSLTFunctions__specialCharInPattern".equals(id)) {
// a recoverable error Xalan doesn't recover from
continue;
}
else if ("XSLTFunctions_DocumentFunctionWithAbsoluteArgument".equals(id)) {
// test case bug; bad URL passed to document function
continue;
}
else if ("BVTs_bvt052".equals(id) || "Keys_PerfRepro2".equals(id)) {
// Requires a non-standard extension function
continue;
}
else if ("BVTs_bvt044".equals(id)) {
// a recoverable error Xalan doesn't recover from
// http://issues.apache.org/jira/browse/XALANJ-1957
continue;
}
else if ("BVTs_bvt039".equals(id)) {
// Xalan bug
continue;
}
else if ("BVTs_bvt033".equals(id) || "BVTs_bvt034".equals(id)) {
// Test suite bug; 2.0 is not unrecognized
continue;
}
else if ("Text__78274".equals(id) || "Text__78276".equals(id)) {
// Test suite bug; no xsl:preserve-space attribute
continue;
}
else if ("XSLTFunctions__minimumValue".equals(id)
|| "XSLTFunctions__minimalValue".equals(id)) {
// test suite bug
continue;
}
else if ("Errors_err073".equals(id)) {
// Xalan bug: StackOverflowError
continue;
}
else if ("Sorting_SortExprWithCurrentInsideForEach1".equals(id)) {
// Xalan bug
// http://issues.apache.org/jira/browse/XALANJ-1970
continue;
}
else if ("BVTs_bvt041".equals(id) || "BVTs_bvt063".equals(id)
|| "BVTs_bvt070".equals(id)) {
// Xalan bundled with JDK 1.4.2_05 does not recover
// from this error involving multiple conflicting
// xsl:output at same import precedence, though
// 2.6.0 does
continue;
}
Document inputDoc = builder.build(input);
XSLTransform xform;
if (strip) xform = new XSLTransform(styleDoc, stripper);
else xform = new XSLTransform(styleDoc);
Nodes result = xform.transform(inputDoc);
if (output == null) {
if ("Attributes__89463".equals(id)
|| "Attributes__89465".equals(id)) {
// Processors are allowed to recover from
// this problem.
assertEquals(0, result.size());
}
else if ("Attributes__89464".equals(id)) {
// Processors are allowed to recover from
// this problem.
assertEquals(0, ((Element) result.get(0)).getAttributeCount());
}
else if ("Namespace-alias__91772".equals(id)
|| "Namespace-alias__91774".equals(id)
|| "Namespace-alias__91780".equals(id)
|| "Namespace-alias__91790".equals(id)
|| "Namespace-alias__91791".equals(id)
|| "Sorting__84006".equals(id)
|| "Sorting__91754".equals(id)
) {
// Processors are allowed to recover from
// this problem.
continue;
}
else if (id.startsWith("Errors_")) {
// Processors are allowed to recover from
// most of these problems.
}
else if (id.startsWith("FormatNumber")) {
// Processors are allowed to recover from
// most of these problems.
}
else if ("BVTs_bvt074".equals(id)) {
// Processors are allowed to recover from
// this problem.
assertEquals(0, result.get(0).getChildCount());
}
else if ("XSLTFunctions__currency".equals(id)
|| "XSLTFunctions__mixingInvalids".equals(id)) {
// Processors are allowed to recover from
// this problem.
continue;
}
else if ("Attributes_Attribute_UseXmlnsNsAsNamespaceForAttribute".equals(id)
|| "Attributes_Attribute_UseXmlnsAsNamespaceForAttributeImplicitly".equals(id)
|| "Elements_Element_UseXslElementWithNameSpaceAttrEqualToXmlnsUri".equalsIgnoreCase(id)
|| "Elements_Element_UseXslElementWithNameSpaceEqualToXmlnsUri".equalsIgnoreCase(id)
) {
// test follows namespace errata we don't accept
}
else if ("AttributeSets_RefToUndefinedAttributeSet".equals(id)) {
// I think the test case is wrong; I see
// nothing in the spec that says this is
// an error.
}
else if ("Namespace__77665".equals(id)
|| "Namespace__77675".equals(id)) {
// I think the test case is wrong; I see
// nothing in the spec that says this is
// an error. See
// http://lists.oasis-open.org/archives/xslt-conformance-comment/200409/msg00007.html
}
else if ("Variables__84633".equals(id)
|| "Variables__84634".equals(id)
|| "Variables__84697".equals(id)
|| "Variables__84710".equals(id)
) {
// An error. See 11.4
// but are processors allowed to recover?
// Hmm according to section 17, the
// processor must signal these errors
// and may but need not recover from them.
// Xalan recovers. Microsoft doesn't.
}
else if ("Output__78176".equals(id)) {
// I think the test case is wrong; I see
// nothing in the spec that says this is
// an error.
}
else if (id.startsWith("XSLTFunctions__100")) {
// I think these test cases are all wrong
// except perhaps XSLTFunctions__10026; I
// see nothing in the spec that says this
// is an error. These are all about the
// unparsed-entity-uri function.
}
else if ("Namespace__78027".equals(id)) {
// Test case is incorrect. This should
// operate in forwards compatible mode.
// Xalan gets this right.
}
else if ("Output_Output_UseStandAloneAttributeWithMultipleRoots".equals(id)) {
// Error only appears when document is serialized;
// not before
}
else { // transform should have failed
fail("Transformed " + style + "\n id: "
+ testcase.getAttributeValue("id"));
}
}
else {
try {
if ("Attributes_xsl_attribute_dup_attr_with_namespace_conflict".equals(id)
|| "BVTs_bvt057".equals(id)) {
// This test case requires namespace prefix rewriting,
// so the output won't be exactly the same between processors
continue;
}
else if ("Comment_DisableOutputEscaping_XslTextInXslComment".equals(id)) {
// Test case output is wrong
continue;
}
else if ("Output__77927".equals(id)
|| "Output__77928".equals(id)
|| "Output__84304".equals(id)
|| "Output__84305".equals(id)
|| "Output__84312".equals(id)
|| "Output__84619".equals(id)
|| "Output__84620".equals(id)
|| "Output_EntityRefInAttribHtml".equals(id)
) {
// These test cases have incorrect line
// breaks in the reference output.
continue;
}
else if ("Output_Modified84433".equals(id)) {
// This test case uses disable output escaping
// so the results don't match up
continue;
}
else if ("Sorting_Sort_SortTextWithNonTextCharacters".equals(id)) {
// Xalan and MSXML don't sort non alphabetic characters
// exactly the same, but that's legal
continue;
}
else if ("Text_DoeWithCdataInText".equals(id)) {
// Requires disable-output-escaping
continue;
}
else if ("Whitespaces__91443".equals(id)
|| "Whitespaces__91444".equals(id)) {
// Xalan bug
// See http://issues.apache.org/jira/browse/XALANJ-1969
continue;
}
else if ("AVTs__77591".equals(id)) {
// test suite bug; doesn't escape tabs in output. See
// http://lists.oasis-open.org/archives/xslt-conformance-comment/200409/msg00017.html
}
else if ("Keys_MultipltKeysInclude".equals(id) ) {
// Xalan bug
// http://issues.apache.org/jira/browse/XALANJ-1956
}
/* else if ("Keys_PerfRepro3".equals(id) ) {
// Suspected Xalan bug
// http://issues.apache.org/jira/browse/XALANJ-1955
} */
else if ("Number__84683".equals(id)) {
// test suite bug
}
else if ("Number__84687".equals(id)) {
// test suite bug
}
else if ("Number__84692".equals(id)) {
// test suite bug
}
else if ("Number__84694".equals(id)) {
// Test suite expects Roman number for zero
// to be the empty string while Xalan uses 0
}
else if ("Number__84699".equals(id)) {
// Xalan bug
}
else if ("Number__84700".equals(id)) {
// Xalan bug; extra whitespace. Possibly
// the same as
}
else if ("Number__84716".equals(id)) {
// Xalan doesn't support Russian
// number formatting
}
else if ("Number__84717".equals(id)) {
// Xalan supports more Japanese than the
// test case does
}
else if ("Number__84722".equals(id)
|| "Number__84723".equals(id)
|| "Number__84724".equals(id)
|| "Number__84725".equals(id)
) {
// Acceptable locale support differences
}
else if ("Number_NaNOrInvalidValue".equals(id)) {
// Double bug! Test case is wrong and
// Xalan gets this wrong!
}
else if ("Number_ValueAsNodesetTest1".equals(id)
|| "Number_ValueAsEmptyNodeset".equals(id)) {
// Another double bug! Test case is wrong and
// Xalan gets this wrong!
}
else if (id.equals("XSLTFunctions_BooleanFunction")) {
// I think the test case is wrong; or perhaps unspecified
}
else if (id.equals("XSLTFunctions_TestIdFuncInComplexStruct")) {
// I think the Xalan output white space is wrong;
// http://issues.apache.org/jira/browse/XALANJ-1947
}
else if (id.equals("XSLTFunctions__testOn-0.00")) {
// Possible test suite bug. See
// http://issues.apache.org/jira/browse/XALANJ-2226
}
else {
Document expectedResult;
if (strip) expectedResult = strippingBuilder.build(output);
else expectedResult = builder.build(output);
Document actualResult = XSLTransform.toDocument(result);
assertEquals("Mismatch with " + id,
expectedResult, actualResult);
}