private bool testAssertion2(XdmNode assertion, Outcome outcome, XPathCompiler assertXpc, XPathCompiler catalogXpc, bool debug) { string tag = assertion.NodeName.LocalName; if (tag.Equals("assert-eq")) { if (outcome.isException()) { return false; } else { XPathSelector s = assertXpc.Compile("$result eq " + assertion.StringValue).Load(); s.SetVariable(new QName("result"), outcome.getResult()); XdmAtomicValue item = (XdmAtomicValue)s.EvaluateSingle(); if (s == null) { return false; } return (bool)item.Value; } } if (tag.Equals("assert-deep-eq")) { if (outcome.isException()) { return false; } else { XPathSelector s = assertXpc.Compile("deep-equal($result , (" + assertion.StringValue + "))").Load(); s.SetVariable(new QName("result"), outcome.getResult()); return (bool)((XdmAtomicValue)s.Evaluate()).Value; } } else if (tag.Equals("assert-permutation")) { // TODO: extend this to handle nodes (if required) if (outcome.isException()) { return false; } else { try { int expectedItems = 0; Hashtable expected = new Hashtable(); XPathSelector s = assertXpc.Compile("(" + assertion.StringValue + ")").Load(); s.SetVariable(new QName("result"), outcome.getResult()); // not used, but we declared it net.sf.saxon.lib.StringCollator collator = net.sf.saxon.expr.sort.CodepointCollator.getInstance(); net.sf.saxon.expr.XPathContext context = new net.sf.saxon.expr.XPathContextMajor(net.sf.saxon.value.StringValue.EMPTY_STRING, assertXpc.Processor.Implementation); /* foreach (XdmItem item in s) { expectedItems++; XdmValue value = (XdmValue) item; Object comparable = value.isNaN() ? AtomicSortComparer.COLLATION_KEY_NaN : value.getXPathComparable(false, collator, context); expected.add(comparable); } */ int actualItems = 0; /*foreach (XdmItem item in outcome.getResult()) { actualItems++; AtomicValue value = (AtomicValue) item.getUnderlyingValue(); Object comparable = value.isNaN() ? AtomicSortComparer.COLLATION_KEY_NaN : value.getXPathComparable(false, collator, context); if (!expected.Contains(comparable)) { return false; } }*/ return actualItems == expectedItems; } catch (DynamicError e) { return false; } } } else if (tag.Equals("assert-serialization")) { if (outcome.isException()) { return false; } else { string normalizeAtt = assertion.GetAttributeValue(new QName("normalize-space")); bool normalize = normalizeAtt != null && ("true".Equals(normalizeAtt.Trim()) || "1".Equals(normalizeAtt.Trim())); string ignoreAtt = assertion.GetAttributeValue(new QName("ignore-prefixes")); bool ignorePrefixes = ignoreAtt != null && ("true".Equals(ignoreAtt.Trim()) || "1".Equals(ignoreAtt.Trim())); catalogXpc.BaseUri = ""; string comparand = catalogXpc.Evaluate("if (@file) then unparsed-text(resolve-uri(@file, base-uri(.))) else string(.)", assertion).ToString(); if (normalize) { comparand = net.sf.saxon.value.Whitespace.collapseWhitespace(comparand).ToString(); } StringWriter tw = new StringWriter(); Serializer serializer = new Serializer(); serializer.SetOutputWriter(tw); serializer.SetOutputProperty(Serializer.METHOD, "xml"); serializer.SetOutputProperty(Serializer.INDENT, "no"); serializer.SetOutputProperty(Serializer.OMIT_XML_DECLARATION, "yes"); assertXpc.Processor.WriteXdmValue(outcome.getResult(), serializer); if (comparand.Equals(tw.ToString())) { return true; } DocumentBuilder builder = assertXpc.Processor.NewDocumentBuilder(); StringReader reader = new StringReader("<z>" + comparand + "</z>"); builder.BaseUri = assertion.BaseUri; XdmNode expected = builder.Build(reader); int flag = 0; flag |= net.sf.saxon.functions.DeepEqual.INCLUDE_COMMENTS; flag |= net.sf.saxon.functions.DeepEqual.INCLUDE_PROCESSING_INSTRUCTIONS; if (!ignorePrefixes) { flag |= net.sf.saxon.functions.DeepEqual.INCLUDE_NAMESPACES; flag |= net.sf.saxon.functions.DeepEqual.INCLUDE_PREFIXES; } flag |= net.sf.saxon.functions.DeepEqual.COMPARE_STRING_VALUES; flag |= net.sf.saxon.functions.DeepEqual.WARNING_IF_FALSE; try { net.sf.saxon.om.SequenceIterator iter0; XdmValue v = outcome.getResult(); if (v.Count == 1 && v is XdmNode && ((XdmNode)v).NodeKind == XmlNodeType.Document) { iter0 = ((XdmNode)v).Implementation.iterateAxis(net.sf.saxon.om.Axis.CHILD); } else { iter0 = net.sf.saxon.value.Value.asIterator(outcome.getResult().Unwrap()); } net.sf.saxon.om.SequenceIterator iter1 = (expected.Implementation.iterateAxis(net.sf.saxon.om.Axis.CHILD).next()).iterateAxis(net.sf.saxon.om.Axis.CHILD); return net.sf.saxon.functions.DeepEqual.deepEquals( iter0, iter1, new net.sf.saxon.expr.sort.GenericAtomicComparer(net.sf.saxon.expr.sort.CodepointCollator.getInstance(), null), assertXpc.Processor.Implementation, flag); } catch (DynamicError e) { // e.printStackTrace(); return false; } } } else if (tag.Equals("assert-serialization-error")) { if (outcome.isException()) { return false; } else { string expectedError = assertion.GetAttributeValue(new QName("code")); StringWriter sw = new StringWriter(); Serializer serializer = new Serializer(); serializer.SetOutputWriter(sw); serializer.SetOutputProperty(Serializer.METHOD, "xml"); serializer.SetOutputProperty(Serializer.INDENT, "no"); serializer.SetOutputProperty(Serializer.OMIT_XML_DECLARATION, "yes"); try { assertXpc.Processor.WriteXdmValue(outcome.getResult(), serializer); return false; } catch (DynamicError err) { bool b = expectedError.Equals(err.ErrorCode.LocalName); if (!b) { feedback.Message("Expected " + expectedError + ", got " + err.ErrorCode.LocalName, false); } return true; } } } else if (tag.Equals("assert-empty")) { if (outcome.isException()) { return false; } else { XdmValue result = outcome.getResult(); return result.Count == 0; } } else if (tag.Equals("assert-count")) { if (outcome.isException()) { return false; } else { XdmValue result = outcome.getResult(); return result.Count == int.Parse(assertion.StringValue); } } else if (tag.Equals("assert")) { if (outcome.isException()) { return false; } else { XPathSelector s = assertXpc.Compile(assertion.StringValue).Load(); s.SetVariable(new QName("result"), outcome.getResult()); return (bool)((XdmAtomicValue)s.EvaluateSingle()).Value; } } else if (tag.Equals("assert-string-value")) { if (outcome.isException()) { return false; } else { XdmValue resultValue = outcome.getResult(); string resultstring; string assertionstring = assertion.StringValue; if (resultValue is XdmNode) { resultstring = ((XdmNode)resultValue).StringValue; }else if(resultValue is XdmAtomicValue){ resultstring = ((XdmAtomicValue)resultValue).ToString(); } else { bool first = true; StringBuilder fsb = new StringBuilder(256); foreach (XdmItem item in resultValue) { if (first) { first = false; } else { fsb.Append(' '); } fsb.Append(item.Unwrap().getStringValue()); } resultstring = fsb.ToString(); } string normalizeAtt = assertion.GetAttributeValue(new QName("normalize-space")); if (normalizeAtt != null && (normalizeAtt.Trim().Equals("true") || normalizeAtt.Trim().Equals("1"))) { assertionstring = net.sf.saxon.value.Whitespace.collapseWhitespace(assertionstring).ToString(); resultstring = net.sf.saxon.value.Whitespace.collapseWhitespace(resultstring).ToString(); } if (resultstring.Equals(assertionstring)) { return true; } else { if (debug) { if (resultstring.Length != assertionstring.Length) { Console.WriteLine("Result length " + resultstring.Length + "; expected length " + assertionstring.Length); } int len = Math.Min(resultstring.Length, assertionstring.Length); for (int i = 0; i < len; i++) { if (resultstring[i] != assertionstring[i]) { feedback.Message("Results differ at index " + i + "(\"" + resultstring.Substring(i, (i + 10 > len ? len : i + 10)) + "\") vs (\"" + assertionstring.Substring(i, (i + 10 > len ? len : i + 10)) + "\")", false); break; } } } return false; } } } else if (tag.Equals("assert-type")) { if (outcome.isException()) { return false; } else { XPathSelector s = assertXpc.Compile("$result instance of " + assertion.StringValue).Load(); s.SetVariable(new QName("result"), outcome.getResult()); return (bool)((XdmAtomicValue)s.EvaluateSingle()).Value; } } else if (tag.Equals("assert-true")) { if (outcome.isException()) { return false; } else { XdmValue result = outcome.getResult(); return result.Count == 1 && ((XdmItem)result).IsAtomic() && ((XdmAtomicValue)result).GetPrimitiveTypeName().Equals(QName.XS_BOOLEAN) && (((XdmAtomicValue)result).GetBooleanValue()); } } else if (tag.Equals("assert-false")) { if (outcome.isException()) { return false; } else { XdmValue result = outcome.getResult(); return result.Count == 1 && ((XdmItem)result.Simplify).IsAtomic() && ((XdmAtomicValue)result.Simplify).GetPrimitiveTypeName().Equals(QName.XS_BOOLEAN) && !(bool)((XdmAtomicValue)result.Simplify).Value; } } else if (tag.Equals("error")) { string expectedError = assertion.GetAttributeValue(new QName("code")); //noinspection ThrowableResultOfMethodCallIgnored Exception err = outcome.getException(); QName errorCode = null; if (err is DynamicError) { errorCode = ((DynamicError)outcome.getException()).ErrorCode; } else { errorCode = ((StaticError)outcome.getException()).ErrorCode; } return outcome.isException() && (expectedError.Equals("*") || (errorCode != null && errorCode.LocalName.Equals(expectedError)) || (outcome.hasReportedError(expectedError))); } else if (tag.Equals("all-of")) { XdmValue children = catalogXpc.Evaluate("*", assertion); foreach (XdmItem child in children) { if (!testAssertion((XdmNode)child, outcome, assertXpc, catalogXpc, debug)) { return false; } } return true; } else if (tag.Equals("any-of")) { XdmValue children = catalogXpc.Evaluate("*", assertion); foreach (XdmItem child in children) { if (testAssertion((XdmNode)child, outcome, assertXpc, catalogXpc, debug)) { return true; } } return false; } throw new Exception("Unknown assertion element " + tag); }