/** * Run a test case * * @param testCase the test case element in the catalog * @param xpc the XPath compiler to be used for compiling XPath expressions against the catalog * @throws SaxonApiException */ private void runTestCase(XdmNode testCase, XPathCompiler xpc) { string testCaseName = testCase.GetAttributeValue(new QName("name")); feedback.Message("Test case " + testCaseName + Environment.NewLine, false); XdmNode exceptionElement = null; try { exceptionElement = exceptionsMap[testCaseName]; } catch (Exception) { } XdmNode alternativeResult = null; XdmNode optimization = null; if (exceptionElement != null) { string runAtt = exceptionElement.GetAttributeValue(new QName("run")); if ("no".Equals(runAtt)) { WriteTestCaseElement(testCaseName, "notRun", "see exceptions file"); return; } if (unfolded && "not-unfolded".Equals(runAtt)) { WriteTestCaseElement(testCaseName, "notRun", "see exceptions file"); return; } alternativeResult = (XdmNode)xpc.EvaluateSingle("result", exceptionElement); optimization = (XdmNode)xpc.EvaluateSingle("optimization", exceptionElement); } XdmNode environmentNode = (XdmNode)xpc.EvaluateSingle("environment", testCase); TestEnvironment env = null; if (environmentNode == null) { env = localEnvironments["default"]; } else { string envName = environmentNode.GetAttributeValue(new QName("ref")); if (envName == null) { env = processEnvironment(xpc, environmentNode, null); } else { try { env = localEnvironments[envName]; } catch (Exception) { } if (env == null) { try { env = globalEnvironments[envName]; } catch (Exception) { } } if (env == null) { Console.WriteLine("*** Unknown environment " + envName); WriteTestCaseElement(testCaseName, "fail", "Environment " + envName + " not found"); failures++; return; } } } env.xpathCompiler.BackwardsCompatible = false; env.processor.XmlVersion = (decimal)1.0; bool run = true; bool xpDependency = false; string hostLang; string langVersion; if (preferQuery) { hostLang = "XQ"; langVersion = "1.0"; } else { hostLang = "XP"; langVersion = "2.0"; } XdmValue dependencies = xpc.Evaluate("/*/dependency, ./dependency", testCase); foreach (XdmItem dependency in dependencies) { string type = ((XdmNode)dependency).GetAttributeValue(new QName("type")); if (type == null) { throw new Exception("dependency/@type is missing"); } string value = ((XdmNode)dependency).GetAttributeValue(new QName("value")); if (value == null) { throw new Exception("dependency/@value is missing"); } if (type.Equals("spec")) { if (value.Contains("XP") && !value.Contains("XQ")) { hostLang = "XP"; langVersion = (value.Equals("XP20") ? "2.0" : "3.0"); xpDependency = true; } else if (value.Contains("XP") && value.Contains("XQ") && preferQuery) { hostLang = "XQ"; langVersion = (value.Contains("XQ10+") || value.Contains("XQ30") ? "3.0" : "1.0"); } else if (value.Contains("XT")) { hostLang = "XT"; langVersion = (value.Contains("XT30+") || value.Contains("XT30") ? "3.0" : "1.0"); } else { hostLang = "XQ"; langVersion = (value.Contains("XQ10+") || value.Contains("XQ30") ? "3.0" : "1.0"); } } if (type.Equals("feature") && value.Equals("xpath-1.0-compatibility")) { hostLang = "XP"; langVersion = "3.0"; xpDependency = true; } if (type.Equals("feature") && value.Equals("namespace-axis")) { hostLang = "XP"; langVersion = "3.0"; xpDependency = true; } if (!DependencyIsSatisfied((XdmNode)dependency, env)) { Console.WriteLine("*** Dependency not satisfied: " + ((XdmNode)dependency).GetAttributeValue(new QName("type"))); WriteTestCaseElement(testCaseName, "notRun", "Dependency not satisfied"); run = false; } } if ((unfolded && !xpDependency) || optimization != null) { hostLang = "XQ"; if (langVersion.Equals("2.0")) { langVersion = "1.0"; } } if (run) { Outcome outcome = null; string exp = null; try { exp = xpc.Evaluate("if (test/@file) then unparsed-text(resolve-uri(test/@file, base-uri(.))) else string(test)", testCase).ToString(); } catch (DynamicError err) { Console.WriteLine("*** Failed to read query: " + err.Message); outcome = new Outcome(err); } if (outcome == null) { if (hostLang.Equals(("XP"))) { XPathCompiler testXpc = env.xpathCompiler; testXpc.XPathLanguageVersion = langVersion; testXpc.DeclareNamespace("fn", JNamespaceConstant.FN); testXpc.DeclareNamespace("xs", JNamespaceConstant.SCHEMA); testXpc.DeclareNamespace("math", JNamespaceConstant.MATH); testXpc.DeclareNamespace("map", JNamespaceConstant.MAP_FUNCTIONS); try { XPathSelector selector = testXpc.Compile(exp).Load(); foreach (QName varName in env.params1.Keys) { selector.SetVariable(varName, env.params1[varName]); } if (env.contextNode != null) { selector.ContextItem = env.contextNode; } selector.InputXmlResolver = new TestUriResolver(env); XdmValue result = selector.Evaluate(); outcome = new Outcome(result); } catch (DynamicError err) { Console.WriteLine(err.Message); outcome = new Outcome(err); } catch (StaticError err) { Console.WriteLine(err.Message); outcome = new Outcome(err); } catch (Exception err) { Console.WriteLine("*** Failed to read query: " + err.Message); outcome = new Outcome(new DynamicError("*** Failed to read query: " + err.Message)); } } else { XQueryCompiler testXqc = env.xqueryCompiler; testXqc.XQueryLanguageVersion = langVersion; testXqc.DeclareNamespace("fn", JNamespaceConstant.FN); testXqc.DeclareNamespace("xs", JNamespaceConstant.SCHEMA); testXqc.DeclareNamespace("math", JNamespaceConstant.MATH); testXqc.DeclareNamespace("map", JNamespaceConstant.MAP_FUNCTIONS); ErrorCollector errorCollector = new ErrorCollector(); //testXqc.setErrorListener(errorCollector); string decVars = env.paramDecimalDeclarations.ToString(); if (decVars.Length != 0) { int x = (exp.IndexOf("(:%DECL%:)")); if (x < 0) { exp = decVars + exp; } else { exp = exp.Substring(0, x) + decVars + exp.Substring(x + 13); } } string vars = env.paramDeclarations.ToString(); if (vars.Length != 0) { int x = (exp.IndexOf("(:%VARDECL%:)")); if (x < 0) { exp = vars + exp; } else { exp = exp.Substring(0, x) + vars + exp.Substring(x + 13); } } ModuleResolver mr = new ModuleResolver(xpc); mr.setTestCase(testCase); testXqc.QueryResolver = (IQueryResolver)mr; try { XQueryExecutable q = testXqc.Compile(exp); if (optimization != null) { /* XdmDestination expDest = new XdmDestination(); net.sf.saxon.Configuration config = driverProc.Implementation; net.sf.saxon.trace.ExpressionPresenter presenter = new net.sf.saxon.trace.ExpressionPresenter(driverProc.Implementation, expDest.getReceiver(config)); //q.getUnderlyingCompiledQuery().explain(presenter); presenter.close(); XdmNode explanation = expDest.XdmNode; XdmItem optResult = xpc.EvaluateSingle(optimization.GetAttributeValue(new QName("assert")), explanation); if ((bool)((XdmAtomicValue)optResult).Value) { Console.WriteLine("Optimization result OK"); } else { Console.WriteLine("Failed optimization test"); Serializer serializer = new Serializer(); serializer.SetOutputWriter(Console.Error); driverProc.WriteXdmValue(explanation, serializer); WriteTestCaseElement(testCaseName, "fail", "Failed optimization assertions"); failures++; return; }*/ } XQueryEvaluator selector = q.Load(); foreach (QName varName in env.params1.Keys) { selector.SetExternalVariable(varName, env.params1[varName]); } if (env.contextNode != null) { selector.ContextItem = env.contextNode; } selector.InputXmlResolver= new TestUriResolver(env); XdmValue result = selector.Evaluate(); outcome = new Outcome(result); } catch (DynamicError err) { Console.WriteLine("TestSet" + testFuncSet); Console.WriteLine(err.Message); outcome = new Outcome(err); outcome.setErrorsReported(errorCollector.getErrorCodes()); } catch(StaticError err){ Console.WriteLine("TestSet" + testFuncSet); Console.WriteLine(err.Message); outcome = new Outcome(err); outcome.setErrorsReported(errorCollector.getErrorCodes()); } catch(Exception err){ Console.WriteLine("TestSet" + testFuncSet); Console.WriteLine(err.Message); outcome = new Outcome(new DynamicError(err.Message)); outcome.setErrorsReported(errorCollector.getErrorCodes()); } } } XdmNode assertion; if (alternativeResult != null) { assertion = (XdmNode)xpc.EvaluateSingle("*[1]", alternativeResult); } else { assertion = (XdmNode)xpc.EvaluateSingle("result/*[1]", testCase); } if (assertion == null) { Console.WriteLine("*** No assertions found for test case " + testCaseName); WriteTestCaseElement(testCaseName, "fail", "No assertions in test case"); failures++; return; } XPathCompiler assertXpc = env.processor.NewXPathCompiler(); assertXpc.XPathLanguageVersion = "3.0"; assertXpc.DeclareNamespace("fn", JNamespaceConstant.FN); assertXpc.DeclareNamespace("xs", JNamespaceConstant.SCHEMA); assertXpc.DeclareNamespace("math", JNamespaceConstant.MATH); assertXpc.DeclareNamespace("map", JNamespaceConstant.MAP_FUNCTIONS); assertXpc.DeclareVariable(new QName("result")); bool b = testAssertion(assertion, outcome, assertXpc, xpc, debug); if (b) { Console.WriteLine("OK"); successes++; feedback.Message("OK" + Environment.NewLine, false); WriteTestCaseElement(testCaseName, "full", null); } else { if (outcome.isException()) { XdmItem expectedError = xpc.EvaluateSingle("result//error/@code", testCase); if (expectedError == null) { // if (debug) { // outcome.getException().printStackTrace(System.out); // } if (outcome.getException() is StaticError) { WriteTestCaseElement(testCaseName, "fail", "Expected success, got " + ((StaticError)outcome.getException()).ErrorCode); feedback.Message("*** fail, result " + ((StaticError)outcome.getException()).ErrorCode.LocalName + " Expected success." + Environment.NewLine, false); } else { WriteTestCaseElement(testCaseName, "fail", "Expected success, got " + ((DynamicError)outcome.getException()).ErrorCode); feedback.Message("*** fail, result " + ((DynamicError)outcome.getException()).ErrorCode.LocalName + " Expected success." + Environment.NewLine, false); } failures++; } else { if (outcome.getException() is StaticError) { WriteTestCaseElement(testCaseName, "different-error", "Expected error:" + expectedError.ToString() /*.GetstringValue()*/ + ", got " + ((StaticError)outcome.getException()).ErrorCode.ToString()); feedback.Message("*** fail, result " + ((StaticError)outcome.getException()).ErrorCode.LocalName + " Expected error:" + expectedError.ToString() + Environment.NewLine, false); } else { WriteTestCaseElement(testCaseName, "different-error", "Expected error:" + expectedError.ToString() /*.GetstringValue()*/ + ", got " + ((DynamicError)outcome.getException()).ErrorCode.ToString()); feedback.Message("*** fail, result " + ((DynamicError)outcome.getException()).ErrorCode.LocalName + " Expected error:" + expectedError.ToString() + Environment.NewLine, false); } wrongErrorResults++; } } else { try { WriteTestCaseElement(testCaseName, "fail", "Wrong results, got " + truncate(outcome.serialize(assertXpc.Processor))); }catch (Exception) { WriteTestCaseElement(testCaseName, "fail", "Wrong results, got "); } failures++; if (debug) { try { feedback.Message("Result:" + Environment.NewLine, false); // driverProc.WriteXdmValue(outcome.getResult(), driverSerializer); feedback.Message("=======" + Environment.NewLine, false); } catch (Exception) { } feedback.Message(outcome.getResult() + Environment.NewLine, false); } else { feedback.Message("*** fail (use -debug to show actual result)" + Environment.NewLine, false); } } } feedback.Feedback(successes, failures, 25693); } }
private void processTestSet(DocumentBuilder catbuilder, XPathCompiler xpc, XdmNode funcSetNode) { string testName; try { results.WriteLine("<test-set name='" + funcSetNode.GetAttributeValue(new QName("name")) + "'>"); } catch (Exception e) { } string testSetFile = testSuiteDir + "\\" + funcSetNode.GetAttributeValue(new QName("file")); xpc.BaseUri = testSetFile; XdmNode testSetDocNode = catbuilder.Build(new Uri(testSetFile)); localEnvironments.Clear(); TestEnvironment defaultEnvironment = createLocalEnvironment(testSetDocNode.BaseUri); localEnvironments.Add("default", defaultEnvironment); bool run = true; IEnumerator dependency = xpc.Evaluate("/test-set/dependency", testSetDocNode).GetEnumerator(); while (dependency.MoveNext()) { if (!DependencyIsSatisfied((XdmNode)dependency.Current, defaultEnvironment)) { run = false; } } if (run) { IEnumerator iter = xpc.Evaluate("//environment[@name]", testSetDocNode).GetEnumerator(); while (iter.MoveNext()) { processEnvironment(xpc, (XdmNode)iter.Current, localEnvironments); } IEnumerator testCases = xpc.Evaluate("//test-case", testSetDocNode).GetEnumerator(); while (testCases.MoveNext()) { testName = ((XdmNode)xpc.EvaluateSingle("@name", (XdmItem)testCases.Current)).StringValue; if (testPattern != null && !testPattern.Match(testName).Success) { continue; } feedback.Message("Test set " + funcSetNode.GetAttributeValue(new QName("name")) + " ", false); runTestCase((XdmNode)testCases.Current, xpc); } } try { results.WriteLine("</test-set>"); } catch (Exception e) { } }
/** * Construct an Environment * * @param xpc the XPathCompiler used to process the catalog file * @param env the Environment element in the catalog file * @param environments the set of environments to which this one should be added (may be null) * @return the constructed Environment object * @throws SaxonApiException */ private TestEnvironment processEnvironment(XPathCompiler xpc, XdmItem env, Dictionary<string, TestEnvironment> environments) { TestEnvironment environment = new TestEnvironment(); string name = ((XdmNode)env).GetAttributeValue(new QName("name")); environment.processor = new Processor(true); XmlUrlResolver res = new XmlUrlResolver(); if (generateByteCode == 1) { environment.processor.SetProperty(JFeatureKeys.GENERATE_BYTE_CODE, "true"); environment.processor.SetProperty(JFeatureKeys.DEBUG_BYTE_CODE, "false"); } else if (generateByteCode == 2) { environment.processor.SetProperty(JFeatureKeys.GENERATE_BYTE_CODE, "true"); environment.processor.SetProperty(JFeatureKeys.DEBUG_BYTE_CODE, "true"); } else { environment.processor.SetProperty(JFeatureKeys.GENERATE_BYTE_CODE, "false"); environment.processor.SetProperty(JFeatureKeys.DEBUG_BYTE_CODE, "false"); } environment.xpathCompiler = environment.processor.NewXPathCompiler(); environment.xpathCompiler.BaseUri = (((XdmNode)env).BaseUri).ToString(); environment.xqueryCompiler = environment.processor.NewXQueryCompiler(); environment.xqueryCompiler.BaseUri = (((XdmNode)env).BaseUri).ToString(); if (unfolded) { //environment.xqueryCompiler.getUnderlyingStaticContext().setCodeInjector(new LazyLiteralInjector()); } DocumentBuilder builder = environment.processor.NewDocumentBuilder(); environment.sourceDocs = new Dictionary<string, XdmNode>(); if (environments != null && name != null) { try { environments.Add(name, environment); }catch(Exception e){} } System.Collections.IEnumerator dependency = xpc.Evaluate("dependency", env).GetEnumerator(); while (dependency.MoveNext()) { if (!DependencyIsSatisfied((XdmNode)dependency.Current, environment)) { environment.usable = false; } } // set the base Uri if specified IEnumerator base1 = xpc.Evaluate("static-base-uri", env).GetEnumerator(); while (base1.MoveNext()) { string Uri = ((XdmNode)base1.Current).GetAttributeValue(new QName("uri")); try { environment.xpathCompiler.BaseUri = Uri; environment.xqueryCompiler.BaseUri = Uri; } catch (Exception e) { Console.WriteLine("**** invalid base Uri " + Uri); } } // set any requested collations base1 = xpc.Evaluate("collation", env).GetEnumerator(); while (base1.MoveNext()) { string uriStr = ((XdmNode)base1.Current).GetAttributeValue(new QName("uri")); string defaultAtt = ((XdmNode)base1.Current).GetAttributeValue(new QName("default")); Boolean defaultCol = false; if (defaultAtt != null && (defaultAtt.Trim().Equals("true") || defaultAtt.Trim().Equals("1"))) { defaultCol = true; } if (uriStr.Equals("http://www.w3.org/2010/09/qt-fots-catalog/collation/caseblind")) { net.sf.saxon.Configuration config = xpc.Processor.Implementation; net.sf.saxon.lib.StringCollator collator = config.getCollationURIResolver().resolve("http://saxon.sf.net/collation?ignore-case=yes", "", config); CompareInfo compareInfo = CultureInfo.CurrentCulture.CompareInfo; CompareOptions options = CompareOptions.IgnoreCase; environment.xpathCompiler.DeclareCollation(new Uri(uriStr), compareInfo, options, defaultCol); environment.xqueryCompiler.DeclareCollation(new Uri(uriStr), compareInfo, options, defaultCol); } } // declare the requested namespaces IEnumerator nsElement = xpc.Evaluate("namespace", env).GetEnumerator(); while (nsElement.MoveNext()) { string prefix = ((XdmNode)nsElement.Current).GetAttributeValue(new QName("prefix")); string uri = ((XdmNode)nsElement.Current).GetAttributeValue(new QName("uri")); environment.xpathCompiler.DeclareNamespace(prefix, uri); environment.xqueryCompiler.DeclareNamespace(prefix, uri); } // load the requested schema documents SchemaManager manager = environment.processor.SchemaManager; System.Collections.IEnumerator schema = xpc.Evaluate("schema", env).GetEnumerator(); while (schema.MoveNext()) { string href = ((XdmNode)schema.Current).GetAttributeValue(new QName("file")); manager.Compile((new Uri(((XdmNode)env).BaseUri, href))); } // load the requested source documents //IEnumerator source = xpc.Evaluate("source", env).GetEnumerator(); foreach (XdmItem source in xpc.Evaluate("source", env)) { Uri href = res.ResolveUri(((XdmNode)env).BaseUri, ((XdmNode)source).GetAttributeValue(new QName("file"))); string Uri = ((XdmNode)source).GetAttributeValue(new QName("uri")); string validation = ((XdmNode)source).GetAttributeValue(new QName("", "validation")); XdmNode doc = null; if (validation == null || validation.Equals("skip")) { try { doc = builder.Build(href); } catch (Exception e) { feedback.Message("Error:" + e.Message+" *** failed to build source document " + href, false); } } else { try { SchemaValidator validator = manager.NewSchemaValidator(); XdmDestination xdmDest = new XdmDestination(); validator.IsLax = validation.Equals("lax"); validator.SetDestination(xdmDest); validator.SetSource(href); validator.Run(); doc = xdmDest.XdmNode; environment.xpathCompiler.SchemaAware = true; environment.xqueryCompiler.SchemaAware = true; } catch(Exception e) { feedback.Message("Error:" + e.Message+" *** failed to build source document " + href, false); } } if (Uri != null) { environment.sourceDocs.Add(Uri, doc); } string role = ((XdmNode)source).GetAttributeValue(new QName("role")); if (role != null) { if (".".Equals(role)) { environment.contextNode = doc; } else if (role.StartsWith("$")) { string varName = role.Substring(1); environment.params1.Add(new QName(varName), doc); environment.xpathCompiler.DeclareVariable(new QName(varName)); environment.paramDeclarations.Append("declare variable $" + varName + " external; "); } } } // create a collection Uri resolved to handle the requested collections Hashtable collections = new Hashtable(); foreach (XdmItem coll in xpc.Evaluate("collection", env)) { string collectionUri = ((XdmNode)coll).GetAttributeValue(new QName("uri")); if (collectionUri == null || collectionUri.Equals("")) { collectionUri = "http://www.saxonica.com/defaultCollection"; } IList<Uri> docs = new List<Uri>(); foreach (XdmItem source in xpc.Evaluate("source", coll)) { Uri href = res.ResolveUri(((XdmNode)env).BaseUri, ((XdmNode)source).GetAttributeValue(new QName("file"))); //File file = new File((((XdmNode) env).GetBaseUri().resolve(href))); string id = ((XdmNode)source).GetAttributeValue(new QName(JNamespaceConstant.XML, "id")); XdmNode doc = builder.Build(href); if (id != null) { environment.sourceDocs.Add(id, doc); } environment.processor.RegisterCollection(href, getCollection(doc, href.AbsoluteUri)); environment.sourceDocs.Add(href.ToString(), doc); docs.Add(doc.DocumentUri); } try { collections.Add(new Uri(collectionUri), docs); } catch (Exception e) { feedback.Message("**** Invalid collection Uri " + collectionUri, false); } } if (collections.Count != 0) { environment.processor.Implementation.setCollectionURIResolver(new CollectionResolver(collections)); /* new net.sf.saxon.lib.CollectionURIResolver() { public SequenceIterator resolve(string href, string base, XPathContext context) { try { List<AnyUriValue> docs; if (href == null) { docs = collections.get(new Uri("")); } else { Uri abs = new Uri(base).resolve(href); docs = collections.get(abs); } if (docs == null) { return EmptyIterator.getInstance(); } else { return new ListIterator(docs); } } catch (UriSyntaxException e) { Console.WriteLine("** Invalid Uri: " + e.Message); return EmptyIterator.getInstance(); } } } )*/ } // register any required decimal formats IEnumerator decimalFormat = xpc.Evaluate("decimal-format", env).GetEnumerator(); while (decimalFormat.MoveNext()) { XdmNode formatElement = (XdmNode) decimalFormat.Current; string formatName = formatElement.GetAttributeValue(new QName("name")); QName formatQName = null; if (formatName != null) { if (formatName.IndexOf(':') < 0) { formatQName = new QName("", "", formatName); } else { try { formatQName = new QName(environment.xpathCompiler.GetNamespaceURI(formatName, false), formatName.Substring(formatName.IndexOf(':')+1)); } catch (Exception) { feedback.Message("**** Invalid QName as decimal-format name", false); formatQName = new QName("", "", "error-name"); } } environment.paramDecimalDeclarations.Append("declare decimal-format " + formatName + " "); } else { environment.paramDecimalDeclarations.Append("declare default decimal-format "); } foreach (XdmItem decimalFormatAtt in xpc.Evaluate("@* except @name", formatElement)) { XdmNode formatAttribute = (XdmNode) decimalFormatAtt; string property = formatAttribute.NodeName.LocalName; string value = formatAttribute.StringValue; environment.paramDecimalDeclarations.Append(property + "=\"" + value + "\" "); environment.xpathCompiler.SetDecimalFormatProperty(formatQName, property, value); } environment.paramDecimalDeclarations.Append(";"); } // declare any variables IEnumerator param = xpc.Evaluate("param", env).GetEnumerator(); while (param.MoveNext()) { string varName = ((XdmNode)param.Current).GetAttributeValue(new QName("name")); XdmValue value = null; string sourceStr = ((XdmNode)param.Current).GetAttributeValue(new QName("source")); if (sourceStr != null) { XdmNode sourceDoc = (XdmNode)(environment.sourceDocs[sourceStr]); if (sourceDoc == null) { Console.WriteLine("**** Unknown source document " + sourceDoc.ToString()); } value = sourceDoc; } else { string select = ((XdmNode)param.Current).GetAttributeValue(new QName("select")); value = xpc.Evaluate(select, null); } environment.params1.Add(new QName(varName), value); environment.xpathCompiler.DeclareVariable(new QName(varName)); string declared = ((XdmNode)param.Current).GetAttributeValue(new QName("declared")); if (declared != null && "true".Equals(declared) || "1".Equals(declared)) { // no action } else { environment.paramDeclarations.Append("declare variable $" + varName + " external; "); } } return environment; }
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); }