/** * 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); } }