Project

Profile

Help

How to connect?
Download (91.8 KB) Statistics
| Branch: | Tag: | Revision:

he / latest9.4 / hen / csource / samples / FOTestSuiteDriver.cs @ c3c84ba2

1
using System;
2
using System.Collections;
3
using System.Collections.Generic;
4
using System.Text;
5
using Saxon.Api;
6
using System.Xml;
7
using System.IO;
8
using System.Text.RegularExpressions;
9
using JFeatureKeys=net.sf.saxon.lib.FeatureKeys;
10
using JNamespaceConstant=net.sf.saxon.lib.NamespaceConstant;
11
using JStandardModuleURIResolver=net.sf.saxon.lib.StandardModuleURIResolver;
12
using TestRunner;
13
using System.Globalization;
14

    
15

    
16

    
17
    /**
18
     * Test Driver for the Functions and Operators test suite
19
     */
20
    public class FOTestSuiteDriver
21
    {
22

    
23
        static void MainXXX(string[] args)
24
        {
25
            if (args.Length == 0 || args[0].Equals("-?"))
26
            {
27
                Console.WriteLine("FOTestSuiteDriver testsuiteDir resultsDir testName?");
28
            }
29
            try
30
            {
31
                new FOTestSuiteDriver().go(args);
32
            }
33
            catch (Exception e)
34
            {
35
                Console.WriteLine(e.Message);
36
                Console.WriteLine(e.StackTrace);
37
            }
38
        }
39

    
40

    
41
        public static string RNS = "http://www.w3.org/2010/09/qt-fots-catalog";
42

    
43
        String testSuiteDir;
44
        Processor driverProc = new Processor(true);
45
        Serializer driverSerializer = new Serializer();
46
        Dictionary<string, TestEnvironment> globalEnvironments = new Dictionary<string, TestEnvironment>();
47
        Dictionary<string, TestEnvironment> localEnvironments = new Dictionary<string, TestEnvironment>();
48
        Regex testPattern = null;
49
        string testFuncSet = null;
50
        string resultsDir = null;
51
        private bool debug = false;
52
        StreamWriter results;
53
        private int successes = 0;
54
        private int failures = 0;
55
        private int wrongErrorResults = 0;
56
        private bool unfolded = false;
57
        private int generateByteCode = 0;
58
        private bool preferQuery = false;
59
        private TreeModel treeModel = TreeModel.TinyTree;
60
        private Dictionary<string, XdmNode> exceptionsMap = new Dictionary<string, XdmNode>();
61
        IFeedbackListener feedback;
62
        
63

    
64

    
65
        /*public static void main(string[] args) throws Exception {
66
            if (args.length == 0 || args[0].Equals("-?")) {
67
                Console.WriteLine("java com.saxonica.testdriver.FOTestSuiteDriver catalog [-o:resultsdir] [-s:testSetName]" +
68
                        " [-t:testNamePattern] [-unfolded] [-bytecode:on|off|debug] [-xquery] [-tree]");
69
            }
70

    
71
            Console.WriteLine("Testing Saxon " + Version.getProductVersion());
72
            new FOTestSuiteDriver().go(args);
73
        }*/
74

    
75
        /**
76
         * An environment captures the content of an &lt;environment&gt; element in the catalog: a named set
77
         * of source documents, schemas, etc
78
         */
79

    
80
        public class TestEnvironment
81
        {
82
            public Processor processor;
83
            public Dictionary<string, XdmNode> sourceDocs;
84
            public XPathCompiler xpathCompiler;
85
            public XQueryCompiler xqueryCompiler;
86
            public XdmNode contextNode;
87
            public Dictionary<QName, XdmValue> params1 = new Dictionary<QName, XdmValue>();
88
            public bool xml11 = false;
89
            public bool usable = true;
90
            public StringBuilder paramDeclarations = new StringBuilder(256);
91
            public StringBuilder paramDecimalDeclarations = new StringBuilder(256);
92
        }
93

    
94
        /**
95
         * The outcome of a test is either an XDM value or an exception.
96
         */
97

    
98
        private class Outcome
99
        {
100
            private XdmValue value;
101
            private Hashtable errorsReported;
102
            private DynamicError exception; /*SaxonApiException*/
103
            private StaticError staticException;
104

    
105
            public Outcome(XdmValue value)
106
            {
107
                this.value = value;
108
            }
109

    
110
            public Outcome(DynamicError exception)
111
            {
112
                this.exception = exception;
113
            }
114

    
115
            public Outcome(StaticError exception)
116
            {
117
                this.staticException = exception;
118
            }
119

    
120
            public bool isException()
121
            {
122
                return exception != null || staticException != null;
123
            }
124

    
125
            public Exception getException()
126
            {
127
                if (exception != null)
128
                {
129
                    return exception;
130
                }else {
131
                    return staticException;
132
                }
133
            }
134

    
135
            public XdmValue getResult()
136
            {
137
                return value;
138
            }
139

    
140
            public void setErrorsReported(Hashtable errors)
141
            {
142
                errorsReported = errors;
143
            }
144

    
145
            public bool hasReportedError(string errorCode)
146
            {
147
                return errorsReported != null && errorsReported.Contains(errorCode);
148
            }
149

    
150
            public string ToString()
151
            {
152
                return (isException() ? "EXCEPTION " + exception.Message : value.ToString());
153
            }
154

    
155
            public string serialize(Processor p)
156
            {
157
                if (isException())
158
                {
159
                    return "EXCEPTION " + exception.Message;
160
                }
161
                else
162
                {
163
                    StringWriter sw = new StringWriter();
164
                    Serializer s = new Serializer();
165
                    s.SetOutputWriter(sw);
166
                    s.SetOutputProperty(Serializer.METHOD, "xml");
167
                    s.SetOutputProperty(Serializer.INDENT, "yes");
168
                    s.SetOutputProperty(Serializer.OMIT_XML_DECLARATION, "yes");
169
                    try
170
                    {
171

    
172
                        (new Processor()).WriteXdmValue(value, s);                       
173
                    }
174
                    catch (DynamicError err)
175
                    {
176
                        return ("SERIALIZATION FAILED: " + err.Message);
177
                    }
178
                    return sw.ToString();
179
                }
180
            }
181
        }
182

    
183
        public void setFeedbackListener(IFeedbackListener f)
184
        {
185
            feedback = f;
186
        }
187

    
188
        public void go(string[] args)
189
        {
190
            testSuiteDir = args[0];
191
            if (testSuiteDir.EndsWith("/"))
192
            {
193
                testSuiteDir = testSuiteDir.Substring(0, testSuiteDir.Length - 1);
194
            }
195

    
196
            resultsDir = args[1];
197
            if (resultsDir.EndsWith("/"))
198
            {
199
                resultsDir = resultsDir.Substring(0, resultsDir.Length - 1);
200
            }
201

    
202
            string catalog = testSuiteDir + "\\catalog.xml";
203

    
204
            Hashtable exceptions = new Hashtable();
205

    
206
            for (int i = 1; i < args.Length; i++)
207
            {
208
                if (args[i].StartsWith("-t:"))
209
                {
210
                    testPattern = new Regex(args[i].Substring(3));
211
                }
212
                if (args[i].StartsWith("-s:"))
213
                {
214
                    testFuncSet = args[i].Substring(3);
215
                }
216
                if (args[i].StartsWith("-o"))
217
                {
218
                    resultsDir = args[i].Substring(3);
219
                }
220
                if (args[i].StartsWith("-debug"))
221
                {
222
                    debug = true;
223
                }
224
                if (args[i].Equals("-unfolded"))
225
                {
226
                    unfolded = true;
227
                }
228
                if (args[i].StartsWith("-bytecode"))
229
                {
230
                    if (args[i].Substring(10).Equals("on"))
231
                    {
232
                        generateByteCode = 1;
233
                    }
234
                    else if (args[i].Substring(10).Equals("debug"))
235
                    {
236
                        generateByteCode = 2;
237
                    }
238
                    else
239
                    {
240
                        generateByteCode = 0;
241
                    }
242
                }
243
                if (args[i].StartsWith("-xquery"))
244
                {
245
                    preferQuery = true;
246
                }
247
                /*if (args[i].StartsWith("-tree")) {
248
                    if (args[i].Substring(6).Equals("jdom") || args[i].Substring(6).Equals("JDOM")) {
249
                        treeModel = new JDOMObjectModel();
250
                    } else if (args[i].Substring(6).Equals("jdom2") || args[i].Substring(6).Equals("JDOM2")) {
251
                        treeModel = new JDOM2ObjectModel();
252
                    } else if (args[i].Substring(6).Equals("tinytree") || args[i].Substring(6).Equals("TINYTREE")) {
253
                        treeModel = TreeModel.TinyTree;
254
                    }else {
255
                        throw new Exception("The TreeModel specified does not exist");
256
                    }
257
                } */
258
            }
259
            if (resultsDir == null)
260
            {
261
                Console.WriteLine("No results directory specified (use -o:dirname)");
262
                System.Environment.Exit(2);
263
            }
264

    
265
            //driverSerializer.SetOutputStream(Console.Error);
266
            // driverSerializer.SetOutputProperty(Serializer.OMIT_XML_DECLARATION, "yes");
267

    
268
            processCatalog(catalog);
269
            Console.WriteLine(successes + " successes, " + failures + " failures, " + wrongErrorResults + " incorrect ErrorCode");
270
            feedback.Message(successes + " successes, " + failures + " failures, " + wrongErrorResults + " incorrect ErrorCode"+ Environment.NewLine, false);
271
        }
272

    
273
        public void processCatalog(string catalogFile)
274
        {
275
            DocumentBuilder builder = driverProc.NewDocumentBuilder();
276
            XdmNode catalog = builder.Build(new Uri(catalogFile));
277
            DocumentBuilder catbuilder = driverProc.NewDocumentBuilder();
278
            //catbuilder.SetTreeModel(treeModel);
279
            XPathCompiler xpc = driverProc.NewXPathCompiler();
280
            xpc.BaseUri = "";// catalogFile;
281
            xpc.XPathLanguageVersion = "3.0";
282
            xpc.Caching = true;
283
            xpc.DeclareNamespace("", "http://www.w3.org/2010/09/qt-fots-catalog");
284
            IEnumerator en = xpc.Evaluate("//environment", catalog).GetEnumerator();
285
            while (en.MoveNext())
286
            {
287
                XdmNode envi = (XdmNode)en.Current;
288
                processEnvironment(xpc, envi, globalEnvironments);
289
            }
290

    
291
            try
292
            {
293
                WriteResultFilePreamble(driverProc, catalog, DateTime.Today.ToString());
294
            }
295
            catch (Exception e)
296
            {
297
                feedback.Message(e.StackTrace, false);
298
            }
299

    
300
            /**
301
             * Look for an exceptions.xml document with the general format:
302
             *
303
             * <exceptions xmlns="...test catalog namespace...">
304
             *   <exception test-set ="testset1" test-case="testcase" run="yes/no/not-unfolded"
305
             *       bug="bug-reference" reason="">
306
             *     <results>
307
             *         ... alternative expected results ...
308
             *     </results>
309
             *     <optimization>
310
             *         ... assertions about the "explain" tree
311
             *     </optimization>
312
             *   </exception>
313
             * </exceptions>
314
             *
315
             */
316
            XdmNode exceptionsDoc = null;
317
            DocumentBuilder exceptBuilder = driverProc.NewDocumentBuilder();
318
            QName testCase = new QName("", "test-case");
319
            try
320
            {
321
                exceptionsDoc = exceptBuilder.Build(new Uri(resultsDir + "/exceptions.xml"));
322
                //XdmSequenceIterator iter
323
                IEnumerator iter = exceptionsDoc.EnumerateAxis(XdmAxis.Descendant, new QName(RNS, "exception"));
324
                while (iter.MoveNext())
325
                {
326
                    XdmNode entry = (XdmNode)iter.Current;
327
                    string test = entry.GetAttributeValue(testCase);
328
                    if (test != null)
329
                    {
330
                        exceptionsMap.Add(test, entry);
331
                    }
332
                }
333
            }
334
            catch (Exception e)
335
            {
336
                Console.WriteLine("*** Failed to process exceptions file: " + e.Message);
337
            }
338

    
339
            if (testFuncSet != null)
340
            {
341
                try
342
                {
343
                    XdmNode funcSetNode = (XdmNode)xpc.EvaluateSingle("//test-set[@name='" + testFuncSet + "']", catalog);
344
                    if (funcSetNode == null)
345
                    {
346
                        throw new Exception("Test-set " + testFuncSet + " not found!");
347
                    }
348
                    processTestSet(catbuilder, xpc, funcSetNode);
349
                }
350
                catch (Exception e1)
351
                {
352
                    //   e1.printStackTrace();
353
                }
354
            }
355
            else
356
            {
357
                en = xpc.Evaluate("//test-set", catalog).GetEnumerator();
358
                while (en.MoveNext())
359
                {
360
                    processTestSet(catbuilder, xpc, ((XdmNode)en.Current));
361
                }
362
            }
363
            try
364
            {
365
              writeResultFilePostamble();
366
            }
367
            catch (Exception e)
368
            {
369
                //  e.printStackTrace();
370
            }
371

    
372

    
373
        }
374

    
375
        private void processTestSet(DocumentBuilder catbuilder, XPathCompiler xpc, XdmNode funcSetNode)
376
        {
377
            string testName;
378
            try
379
            {
380
                results.WriteLine("<test-set name='" + funcSetNode.GetAttributeValue(new QName("name")) + "'>");
381
            }
382
            catch (Exception e)
383
            {
384
            }
385
            string testSetFile = testSuiteDir + "\\" + funcSetNode.GetAttributeValue(new QName("file"));
386
            xpc.BaseUri = testSetFile;
387
            XdmNode testSetDocNode = catbuilder.Build(new Uri(testSetFile));
388
            localEnvironments.Clear();
389
            TestEnvironment defaultEnvironment = createLocalEnvironment(testSetDocNode.BaseUri);
390
            localEnvironments.Add("default", defaultEnvironment);
391
            bool run = true;
392
            IEnumerator dependency = xpc.Evaluate("/test-set/dependency", testSetDocNode).GetEnumerator();
393
            while (dependency.MoveNext())
394
            {
395
                if (!DependencyIsSatisfied((XdmNode)dependency.Current, defaultEnvironment))
396
                {
397
                    run = false;
398
                }
399
            }
400
            if (run)
401
            {
402
                IEnumerator iter = xpc.Evaluate("//environment[@name]", testSetDocNode).GetEnumerator();
403
                while (iter.MoveNext())
404
                {
405
                    processEnvironment(xpc, (XdmNode)iter.Current, localEnvironments);
406
                }
407
                IEnumerator testCases = xpc.Evaluate("//test-case", testSetDocNode).GetEnumerator();
408
                while (testCases.MoveNext())
409
                {
410
                    testName = ((XdmNode)xpc.EvaluateSingle("@name", (XdmItem)testCases.Current)).StringValue;
411
                    if (testPattern != null && !testPattern.Match(testName).Success)
412
                    {
413
                        continue;
414
                    }
415
                    feedback.Message("Test set " + funcSetNode.GetAttributeValue(new QName("name")) + " ", false);
416
                    runTestCase((XdmNode)testCases.Current, xpc);
417
                }
418
            }
419
            try
420
            {
421
                results.WriteLine("</test-set>");
422
            }
423
            catch (Exception e)
424
            {
425
            }
426
        }
427

    
428
        /**
429
         * Construct a local default environment for a test set
430
         */
431

    
432
        private TestEnvironment createLocalEnvironment(Uri baseUri)
433
        {
434
            TestEnvironment environment = new TestEnvironment();
435
            environment.processor = new Processor(true);
436
            //activate(environment.processor);
437
            if (generateByteCode == 1)
438
            {
439
                environment.processor.SetProperty("http://saxon.sf.net/feature/generateByteCode", "true");
440
                environment.processor.SetProperty("http://saxon.sf.net/feature/debugByteCode", "false");
441
            }
442
            else if (generateByteCode == 2)
443
            {
444
                environment.processor.SetProperty("http://saxon.sf.net/feature/generateByteCode", "true");
445
                environment.processor.SetProperty("http://saxon.sf.net/feature/debugByteCode", "true");
446
            }
447
            else
448
            {
449
                environment.processor.SetProperty("http://saxon.sf.net/feature/generateByteCode", "false");
450
                environment.processor.SetProperty("http://saxon.sf.net/feature/debugByteCode", "false");
451
            }
452
            environment.xpathCompiler = environment.processor.NewXPathCompiler();
453
            environment.xpathCompiler.BaseUri = baseUri.ToString();
454
            environment.xqueryCompiler = environment.processor.NewXQueryCompiler();
455
            environment.xqueryCompiler.BaseUri = baseUri.ToString();
456
            if (unfolded)
457
            {
458
                //TODO  environment.xqueryCompiler.getUnderlyingStaticContext().setCodeInjector(new LazyLiteralInjector());
459
            }
460
            //environment.processor.getUnderlyingConfiguration().setDefaultCollection(null);
461
            return environment;
462
        }
463

    
464
        /**
465
         * Construct an Environment
466
         *
467
         * @param xpc          the XPathCompiler used to process the catalog file
468
         * @param env          the Environment element in the catalog file
469
         * @param environments the set of environments to which this one should be added (may be null)
470
         * @return the constructed Environment object
471
         * @throws SaxonApiException
472
         */
473

    
474
        private TestEnvironment processEnvironment(XPathCompiler xpc, XdmItem env, Dictionary<string, TestEnvironment> environments)
475
        {
476
            TestEnvironment environment = new TestEnvironment();
477
            string name = ((XdmNode)env).GetAttributeValue(new QName("name"));
478
            environment.processor = new Processor(true);
479
            XmlUrlResolver res = new XmlUrlResolver();
480
            if (generateByteCode == 1)
481
            {
482
                environment.processor.SetProperty(JFeatureKeys.GENERATE_BYTE_CODE, "true");
483
                environment.processor.SetProperty(JFeatureKeys.DEBUG_BYTE_CODE, "false");
484
            }
485
            else if (generateByteCode == 2)
486
            {
487
                environment.processor.SetProperty(JFeatureKeys.GENERATE_BYTE_CODE, "true");
488
                environment.processor.SetProperty(JFeatureKeys.DEBUG_BYTE_CODE, "true");
489
            }
490
            else
491
            {
492
                environment.processor.SetProperty(JFeatureKeys.GENERATE_BYTE_CODE, "false");
493
                environment.processor.SetProperty(JFeatureKeys.DEBUG_BYTE_CODE, "false");
494
            }
495
            environment.xpathCompiler = environment.processor.NewXPathCompiler();
496
            environment.xpathCompiler.BaseUri = (((XdmNode)env).BaseUri).ToString();
497
            environment.xqueryCompiler = environment.processor.NewXQueryCompiler();
498
            environment.xqueryCompiler.BaseUri = (((XdmNode)env).BaseUri).ToString();
499
            if (unfolded)
500
            {
501
                //environment.xqueryCompiler.getUnderlyingStaticContext().setCodeInjector(new LazyLiteralInjector());
502
            }
503
            DocumentBuilder builder = environment.processor.NewDocumentBuilder();
504
            environment.sourceDocs = new Dictionary<string, XdmNode>();
505
            if (environments != null && name != null)
506
            {
507
                try
508
                {
509
                    environments.Add(name, environment);
510
                }catch(Exception e){}
511
            }
512
            System.Collections.IEnumerator dependency = xpc.Evaluate("dependency", env).GetEnumerator();
513

    
514
            while (dependency.MoveNext())
515
            {
516
                if (!DependencyIsSatisfied((XdmNode)dependency.Current, environment))
517
                {
518
                    environment.usable = false;
519
                }
520
            }
521

    
522
            // set the base Uri if specified
523
            IEnumerator base1 = xpc.Evaluate("static-base-uri", env).GetEnumerator();
524
            while (base1.MoveNext())
525
            {
526
                string Uri = ((XdmNode)base1.Current).GetAttributeValue(new QName("uri"));
527
                try
528
                {
529
                    environment.xpathCompiler.BaseUri = Uri;
530
                    environment.xqueryCompiler.BaseUri = Uri;
531
                }
532
                catch (Exception e)
533
                {
534
                    Console.WriteLine("**** invalid base Uri " + Uri);
535
                }
536
            }
537
            // set any requested collations
538
            base1 = xpc.Evaluate("collation", env).GetEnumerator();
539
            while (base1.MoveNext())
540
            {
541
                string uriStr = ((XdmNode)base1.Current).GetAttributeValue(new QName("uri"));
542
                string defaultAtt = ((XdmNode)base1.Current).GetAttributeValue(new QName("default"));
543
                Boolean defaultCol = false;
544
                if (defaultAtt != null && (defaultAtt.Trim().Equals("true") || defaultAtt.Trim().Equals("1")))
545
                {
546
                    defaultCol = true;
547
                }
548
                if (uriStr.Equals("http://www.w3.org/2010/09/qt-fots-catalog/collation/caseblind"))
549
                {
550
                    net.sf.saxon.Configuration config = xpc.Processor.Implementation;
551
                    net.sf.saxon.lib.StringCollator collator = config.getCollationURIResolver().resolve("http://saxon.sf.net/collation?ignore-case=yes", "", config);
552

    
553
                    CompareInfo compareInfo = CultureInfo.CurrentCulture.CompareInfo;
554
                    CompareOptions options = CompareOptions.IgnoreCase;
555

    
556
                    environment.xpathCompiler.DeclareCollation(new Uri(uriStr), compareInfo, options, defaultCol);
557
                    environment.xqueryCompiler.DeclareCollation(new Uri(uriStr), compareInfo, options, defaultCol);
558
                }
559
               
560
            }
561

    
562
            // declare the requested namespaces
563
            IEnumerator nsElement = xpc.Evaluate("namespace", env).GetEnumerator();
564
            while (nsElement.MoveNext())
565
            {
566
                string prefix = ((XdmNode)nsElement.Current).GetAttributeValue(new QName("prefix"));
567
                string uri = ((XdmNode)nsElement.Current).GetAttributeValue(new QName("uri"));
568
                environment.xpathCompiler.DeclareNamespace(prefix, uri);
569
                environment.xqueryCompiler.DeclareNamespace(prefix, uri);
570
            }
571

    
572
            // load the requested schema documents
573
            SchemaManager manager = environment.processor.SchemaManager;
574
            System.Collections.IEnumerator schema = xpc.Evaluate("schema", env).GetEnumerator();
575
            while (schema.MoveNext())
576
            {
577
                string href = ((XdmNode)schema.Current).GetAttributeValue(new QName("file"));
578
                manager.Compile((new Uri(((XdmNode)env).BaseUri, href)));
579
            }
580

    
581
            // load the requested source documents
582
            //IEnumerator source = xpc.Evaluate("source", env).GetEnumerator();
583
            foreach (XdmItem source in xpc.Evaluate("source", env))
584
            {
585
                Uri href = res.ResolveUri(((XdmNode)env).BaseUri, ((XdmNode)source).GetAttributeValue(new QName("file")));
586
                string Uri = ((XdmNode)source).GetAttributeValue(new QName("uri"));
587
                string validation = ((XdmNode)source).GetAttributeValue(new QName("", "validation"));
588
                XdmNode doc = null;
589
                
590
                if (validation == null || validation.Equals("skip"))
591
                {
592
                    try
593
                    {
594
                        doc = builder.Build(href);
595
                       
596
                    }
597
                    catch (Exception e)
598
                    {
599
                        feedback.Message("Error:" + e.Message+" *** failed to build source document " + href, false);
600
                    }
601
                }
602
                else
603
                {
604
                    try
605
                    {
606
                        SchemaValidator validator = manager.NewSchemaValidator();
607
                        XdmDestination xdmDest = new XdmDestination();
608
                        validator.IsLax = validation.Equals("lax");
609
                        validator.SetDestination(xdmDest);
610
                        validator.SetSource(href);
611
                        validator.Run();
612
                        doc = xdmDest.XdmNode;
613
                        environment.xpathCompiler.SchemaAware = true;
614
                        environment.xqueryCompiler.SchemaAware = true;
615
                    }
616
                    catch(Exception e) {
617
                        feedback.Message("Error:" + e.Message+" *** failed to build source document " + href, false);
618
                    }
619

    
620
                }
621

    
622
                if (Uri != null)
623
                {
624
                    environment.sourceDocs.Add(Uri, doc);
625
                }
626
                string role = ((XdmNode)source).GetAttributeValue(new QName("role"));
627
                if (role != null)
628
                {
629
                    if (".".Equals(role))
630
                    {
631
                        environment.contextNode = doc;
632
                    }
633
                    else if (role.StartsWith("$"))
634
                    {
635
                        string varName = role.Substring(1);
636
                        environment.params1.Add(new QName(varName), doc);
637
                        environment.xpathCompiler.DeclareVariable(new QName(varName));
638
                        environment.paramDeclarations.Append("declare variable $" + varName + " external; ");
639
                    }
640
                }
641
              
642
            }
643

    
644
            // create a collection Uri resolved to handle the requested collections
645
            Hashtable collections = new Hashtable();
646
          
647

    
648
            foreach (XdmItem coll in xpc.Evaluate("collection", env))
649
            {
650
                string collectionUri = ((XdmNode)coll).GetAttributeValue(new QName("uri"));
651
                if (collectionUri == null || collectionUri.Equals(""))
652
                {
653
                    collectionUri = "http://www.saxonica.com/defaultCollection";
654
                }
655

    
656
                IList<Uri> docs = new List<Uri>();
657
                
658
                foreach (XdmItem source in xpc.Evaluate("source", coll))
659
                {
660
                   
661

    
662
                    Uri href = res.ResolveUri(((XdmNode)env).BaseUri, ((XdmNode)source).GetAttributeValue(new QName("file")));
663
                    //File file = new File((((XdmNode) env).GetBaseUri().resolve(href)));
664
                    string id = ((XdmNode)source).GetAttributeValue(new QName(JNamespaceConstant.XML, "id"));
665
                    XdmNode doc = builder.Build(href);
666
                    if (id != null)
667
                    {
668
                        environment.sourceDocs.Add(id, doc);
669
                    }
670
                    
671
                    environment.processor.RegisterCollection(href, getCollection(doc, href.AbsoluteUri));
672
                    environment.sourceDocs.Add(href.ToString(), doc);
673
                     docs.Add(doc.DocumentUri);
674
                }
675
                try {
676
                    collections.Add(new Uri(collectionUri), docs);
677
                } catch (Exception e) {
678
                    feedback.Message("**** Invalid collection Uri " + collectionUri, false);
679
                }
680

    
681
            }
682
            if (collections.Count != 0) {
683
                environment.processor.Implementation.setCollectionURIResolver(new CollectionResolver(collections));
684
               /*     new net.sf.saxon.lib.CollectionURIResolver() {
685
                            public SequenceIterator resolve(string href, string base, XPathContext context)  {
686
                                try {
687
                                    List<AnyUriValue> docs;
688
                                    if (href == null) {
689
                                        docs = collections.get(new Uri(""));
690
                                    } else {
691
                                        Uri abs = new Uri(base).resolve(href);
692
                                        docs = collections.get(abs);
693
                                    }
694
                                    if (docs == null) {
695
                                        return EmptyIterator.getInstance();
696
                                    } else {
697
                                        return new ListIterator(docs);
698
                                    }
699
                                } catch (UriSyntaxException e) {
700
                                    Console.WriteLine("** Invalid Uri: " + e.Message);
701
                                    return EmptyIterator.getInstance();
702
                                }
703
                            }
704
                        }
705
                )*/
706
            }
707

    
708
            // register any required decimal formats
709
            IEnumerator decimalFormat = xpc.Evaluate("decimal-format", env).GetEnumerator();
710
            while (decimalFormat.MoveNext())
711
            {
712

    
713
                   XdmNode formatElement = (XdmNode) decimalFormat.Current;
714
                   string formatName = formatElement.GetAttributeValue(new QName("name"));
715
                   QName formatQName = null;
716
                   if (formatName != null) {
717
                       if (formatName.IndexOf(':') < 0) {
718
                           formatQName = new QName("", "", formatName);
719
                       } else {
720
                           try {
721
                               formatQName =  new QName(environment.xpathCompiler.GetNamespaceURI(formatName, false), formatName.Substring(formatName.IndexOf(':')+1));
722
                           } catch (Exception) {
723
                               feedback.Message("**** Invalid QName as decimal-format name", false);
724
                               formatQName = new QName("", "", "error-name");
725
                           }
726
                       }
727
                       environment.paramDecimalDeclarations.Append("declare decimal-format " + formatName + " ");
728
                   } else {
729
                       environment.paramDecimalDeclarations.Append("declare default decimal-format ");
730
                   }
731
                   foreach (XdmItem decimalFormatAtt in xpc.Evaluate("@* except @name", formatElement)) {
732
                       XdmNode formatAttribute = (XdmNode) decimalFormatAtt;
733
                       string property = formatAttribute.NodeName.LocalName;
734
                       string value = formatAttribute.StringValue;
735
                       environment.paramDecimalDeclarations.Append(property + "=\"" + value + "\" ");
736
                       environment.xpathCompiler.SetDecimalFormatProperty(formatQName, property, value);
737
                      
738
                   }
739
                   environment.paramDecimalDeclarations.Append(";");
740
            }
741

    
742
            // declare any variables
743
            IEnumerator param = xpc.Evaluate("param", env).GetEnumerator();
744
            while (param.MoveNext())
745
            {
746
                string varName = ((XdmNode)param.Current).GetAttributeValue(new QName("name"));
747
                XdmValue value = null;
748
                string sourceStr = ((XdmNode)param.Current).GetAttributeValue(new QName("source"));
749
                if (sourceStr != null)
750
                {
751
                    XdmNode sourceDoc = (XdmNode)(environment.sourceDocs[sourceStr]);
752
                    if (sourceDoc == null)
753
                    {
754
                        Console.WriteLine("**** Unknown source document " + sourceDoc.ToString());
755
                    }
756
                    value = sourceDoc;
757
                }
758
                else
759
                {
760
                    string select = ((XdmNode)param.Current).GetAttributeValue(new QName("select"));
761
                    value = xpc.Evaluate(select, null);
762
                }
763
                environment.params1.Add(new QName(varName), value);
764
                environment.xpathCompiler.DeclareVariable(new QName(varName));
765
                string declared = ((XdmNode)param.Current).GetAttributeValue(new QName("declared"));
766
                if (declared != null && "true".Equals(declared) || "1".Equals(declared))
767
                {
768
                    // no action
769
                }
770
                else
771
                {
772
                    environment.paramDeclarations.Append("declare variable $" + varName + " external; ");
773
                }
774
            }
775

    
776
            return environment;
777
        }
778

    
779
        public class CollectionResolver: net.sf.saxon.lib.CollectionURIResolver {
780
            Hashtable collections;
781
            public CollectionResolver(Hashtable collections)
782
            { 
783
                this.collections = collections;
784
            }
785
                            public net.sf.saxon.om.SequenceIterator resolve(string href, string baseStr, net.sf.saxon.expr.XPathContext context)  {
786
                                try {
787
                                    List<Uri> docs;
788
                                    if (href == null) {
789
                                        docs = (List<Uri>)collections[new Uri("http://www.saxonica.com/defaultCollection")];
790
                                    } else {
791
                                        XmlUrlResolver res = new XmlUrlResolver();
792
                                        Uri abs= res.ResolveUri(new Uri(baseStr), href);
793
                                        docs = (List<Uri>)collections[abs];
794
                                    }
795
                                    if (docs == null) {
796
                                        return net.sf.saxon.tree.iter.EmptyIterator.getInstance();
797
                                    } else {
798
                                        java.util.List list = new java.util.ArrayList();
799
                                        foreach(Uri uri in docs){
800
                                            list.add(new net.sf.saxon.value.AnyURIValue(uri.ToString()));
801
                                        }
802
                                        
803
                                        return new net.sf.saxon.tree.iter.ListIterator(list);
804
                                    }
805
                                } catch (java.net.URISyntaxException e) {
806
                                    Console.WriteLine("** Invalid Uri: " + e.Message);
807
                                    return net.sf.saxon.tree.iter.EmptyIterator.getInstance();
808
                                }
809
                            }
810
                        }
811

    
812
        private IList getCollection(XdmNode collectionNode, string href)
813
        {
814
            ArrayList list = new ArrayList(10);
815
            IEnumerator e = collectionNode.EnumerateAxis(
816
                XdmAxis.Child, new QName("input-document"));
817
            while (e.MoveNext())
818
            {
819
                XdmNode node = (XdmNode)e.Current;
820
                list.Add(new Uri(href));
821
            }
822
            return list;
823
        }
824

    
825
        /**
826
         * Get the Unicode codepoint corresponding to a string, which must represent a single Unicode character
827
         *
828
         * @param s the input string, representing a single Unicode character, perhaps as a surrogate pair
829
         * @return
830
         * @throws net.sf.saxon.trans.XPathException
831
         *
832
         */
833
        private int toChar(string s)
834
        {
835
            /*TODO int[] e = StringValue.expand(s);
836
            if (e.length != 1) {
837
                Console.WriteLine("Attribute \"" + s + "\" should be a single character");
838
            }
839
            return e[0];*/
840
            return 0;
841
        }
842

    
843
        /**
844
         * Decide whether a dependency is satisfied
845
         *
846
         * @param dependency the dependency element in the catalog
847
         * @param env        an environment in the catalog, which can be modified to satisfy the dependency if necessary.
848
         *                   May be null.
849
         * @return true if the environment satisfies the dependency, else false
850
         */
851

    
852
        private bool DependencyIsSatisfied(XdmNode dependency, TestEnvironment env)
853
        {
854
            string type = dependency.GetAttributeValue(new QName("type"));
855
            string value = dependency.GetAttributeValue(new QName("value"));
856
            bool inverse = "false".Equals(dependency.GetAttributeValue(new QName("satisfied")));
857
            if ("xml-version".Equals(type))
858
            {
859
                if ("1.1".Equals(value) && !inverse)
860
                {
861
                    if (env != null)
862
                    {
863
                        env.processor.XmlVersion = (decimal)1.1;
864
                    }
865
                    else
866
                    {
867
                        return false;
868
                    }
869
                }
870
                return true;
871
            }
872
            else if ("xsd-version".Equals(type))
873
            {
874
                if ("1.1".Equals(value))
875
                {
876
                    if (env != null)
877
                    {
878

    
879
                        env.processor.SetProperty(JFeatureKeys.XSD_VERSION, (inverse ? "1.0" : "1.1"));
880
                    }
881
                    else
882
                    {
883
                        return false;
884
                    }
885
                }
886
                else if ("1.0".Equals(value))
887
                {
888
                    if (env != null)
889
                    {
890
                        env.processor.SetProperty(JFeatureKeys.XSD_VERSION, (inverse ? "1.1" : "1.0"));
891
                    }
892
                    else
893
                    {
894
                        return false;
895
                    }
896
                }
897
                return true;
898
            }
899
            else if ("limits".Equals(type))
900
            {
901
                if ("year_lt_0".Equals(value) && !inverse)
902
                {
903
                    return true;
904
                }
905
                else
906
                {
907
                    return false;
908
                }
909
            }
910
            else if ("spec".Equals(type))
911
            {
912
                return true;
913
            }
914
            else if ("collection-stability".Equals(type))
915
            {
916
                // SAXON has a problem here - we don't support stable collections
917
                return ("false".Equals(value) != inverse);
918
            }
919
            else if ("default-language".Equals(type))
920
            {
921
                return ("en".Equals(value) != inverse);
922
            }
923
            else if ("directory-as-collection-Uri".Equals(type))
924
            {
925
                return ("true".Equals(value) != inverse);
926
            }
927
            else if ("language".Equals(type))
928
            {
929
                return (("en".Equals(value) || "de".Equals(value) || "fr".Equals(value)) != inverse);
930
            }
931
            else if ("calendar".Equals(type))
932
            {
933
                return (("AD".Equals(value) || "ISO".Equals(value)) != inverse);
934
            }
935
            else if ("format-integer-sequence".Equals(type))
936
            {
937
                return !inverse;
938
            }
939
            else if ("feature".Equals(type))
940
            {
941
                if ("namespace-axis".Equals(value))
942
                {
943
                    return !inverse;
944
                }
945
                else if ("schemaImport".Equals(value) || "schemaValidation".Equals(value))
946
                {
947
                    // Need to reset these after use for this query??
948
                    if (env != null)
949
                    {
950
                        env.xpathCompiler.SchemaAware  = true;
951
                        env.xqueryCompiler.SchemaAware = true;
952
                    }
953
                    return true;
954
                }
955
                else if ("xpath-1.0-compatibility".Equals(value))
956
                {
957
                    if (env != null)
958
                    {
959
                        env.xpathCompiler.BackwardsCompatible = !inverse;
960
                        return true;
961
                    }
962
                    else
963
                    {
964
                        return false;
965
                    }
966
                }
967
                else if ("schema-location-hint".Equals(value))
968
                {
969
                    return !inverse;
970
                }
971
                else
972
                {
973
                    Console.WriteLine("**** feature = " + value + "  ????");
974
                    return false;
975
                }
976
            }
977
            else
978
            {
979
                Console.WriteLine("**** dependency not recognized: " + type);
980
                return false;
981
            }
982
        }
983

    
984
        /**
985
         * Run a test case
986
         *
987
         * @param testCase the test case element in the catalog
988
         * @param xpc      the XPath compiler to be used for compiling XPath expressions against the catalog
989
         * @throws SaxonApiException
990
         */
991

    
992
        private void runTestCase(XdmNode testCase, XPathCompiler xpc)
993
        {
994
            string testCaseName = testCase.GetAttributeValue(new QName("name"));
995
            feedback.Message("Test case " + testCaseName + Environment.NewLine, false);
996

    
997
            XdmNode exceptionElement = null;
998
            try
999
            {
1000
                exceptionElement = exceptionsMap[testCaseName];
1001
            }
1002
            catch (Exception) { }
1003

    
1004
            XdmNode alternativeResult = null;
1005
            XdmNode optimization = null;
1006
            if (exceptionElement != null)
1007
            {
1008
                string runAtt = exceptionElement.GetAttributeValue(new QName("run"));
1009
                if ("no".Equals(runAtt))
1010
                {
1011
                    WriteTestCaseElement(testCaseName, "notRun", "see exceptions file");
1012
                    return;
1013
                }
1014
                if (unfolded && "not-unfolded".Equals(runAtt))
1015
                {
1016
                    WriteTestCaseElement(testCaseName, "notRun", "see exceptions file");
1017
                    return;
1018
                }
1019

    
1020
                alternativeResult = (XdmNode)xpc.EvaluateSingle("result", exceptionElement);
1021
                optimization = (XdmNode)xpc.EvaluateSingle("optimization", exceptionElement);
1022
            }
1023

    
1024
            XdmNode environmentNode = (XdmNode)xpc.EvaluateSingle("environment", testCase);
1025
            TestEnvironment env = null;
1026
            if (environmentNode == null)
1027
            {
1028
                env = localEnvironments["default"];
1029
            }
1030
            else
1031
            {
1032
                string envName = environmentNode.GetAttributeValue(new QName("ref"));
1033
                if (envName == null)
1034
                {
1035
                    env = processEnvironment(xpc, environmentNode, null);
1036
                }
1037
                else
1038
                {
1039
                    try
1040
                    {
1041
                        env = localEnvironments[envName];
1042
                    }
1043
                    catch (Exception) { }
1044
                    if (env == null)
1045
                    {
1046
                        try
1047
                        {
1048
                            env = globalEnvironments[envName];
1049
                        }
1050
                        catch (Exception) { }
1051
                    }
1052
                    if (env == null)
1053
                    {
1054
                        Console.WriteLine("*** Unknown environment " + envName);
1055
                        WriteTestCaseElement(testCaseName, "fail", "Environment " + envName + " not found");
1056
                        failures++;
1057
                        return;
1058
                    }
1059
                }
1060
            }
1061
            env.xpathCompiler.BackwardsCompatible = false;
1062
            env.processor.XmlVersion = (decimal)1.0;
1063

    
1064
            bool run = true;
1065
            bool xpDependency = false;
1066
            string hostLang;
1067
            string langVersion;
1068
            if (preferQuery)
1069
            {
1070
                hostLang = "XQ";
1071
                langVersion = "1.0";
1072
            }
1073
            else
1074
            {
1075
                hostLang = "XP";
1076
                langVersion = "2.0";
1077
            }
1078
            XdmValue dependencies = xpc.Evaluate("/*/dependency, ./dependency", testCase);
1079
            foreach (XdmItem dependency in dependencies)
1080
            {
1081
                string type = ((XdmNode)dependency).GetAttributeValue(new QName("type"));
1082
                if (type == null)
1083
                {
1084
                    throw new Exception("dependency/@type is missing");
1085
                }
1086
                string value = ((XdmNode)dependency).GetAttributeValue(new QName("value"));
1087
                if (value == null)
1088
                {
1089
                    throw new Exception("dependency/@value is missing");
1090
                }
1091
                if (type.Equals("spec"))
1092
                {
1093
                    if (value.Contains("XP") && !value.Contains("XQ"))
1094
                    {
1095
                        hostLang = "XP";
1096
                        langVersion = (value.Equals("XP20") ? "2.0" : "3.0");
1097
                        xpDependency = true;
1098
                    }
1099
                    else if (value.Contains("XP") && value.Contains("XQ") && preferQuery)
1100
                    {
1101
                        hostLang = "XQ";
1102
                        langVersion = (value.Contains("XQ10+") || value.Contains("XQ30") ? "3.0" : "1.0");
1103
                    }
1104
                    else if (value.Contains("XT"))
1105
                    {
1106
                        hostLang = "XT";
1107
                        langVersion = (value.Contains("XT30+") || value.Contains("XT30") ? "3.0" : "1.0");
1108
                    }
1109
                    else
1110
                    {
1111
                        hostLang = "XQ";
1112
                        langVersion = (value.Contains("XQ10+") || value.Contains("XQ30") ? "3.0" : "1.0");
1113
                    }
1114
                }
1115
                if (type.Equals("feature") && value.Equals("xpath-1.0-compatibility"))
1116
                {
1117
                    hostLang = "XP";
1118
                    langVersion = "3.0";
1119
                    xpDependency = true;
1120
                }
1121
                if (type.Equals("feature") && value.Equals("namespace-axis"))
1122
                {
1123
                    hostLang = "XP";
1124
                    langVersion = "3.0";
1125
                    xpDependency = true;
1126
                }
1127

    
1128
                if (!DependencyIsSatisfied((XdmNode)dependency, env))
1129
                {
1130
                    Console.WriteLine("*** Dependency not satisfied: " + ((XdmNode)dependency).GetAttributeValue(new QName("type")));
1131
                    WriteTestCaseElement(testCaseName, "notRun", "Dependency not satisfied");
1132
                    run = false;
1133
                }
1134
            }
1135
            if ((unfolded && !xpDependency) || optimization != null)
1136
            {
1137
                hostLang = "XQ";
1138
                if (langVersion.Equals("2.0"))
1139
                {
1140
                    langVersion = "1.0";
1141
                }
1142
            }
1143
            if (run)
1144
            {
1145

    
1146
                Outcome outcome = null;
1147
                string exp = null;
1148
                try
1149
                {
1150
                    exp = xpc.Evaluate("if (test/@file) then unparsed-text(resolve-uri(test/@file, base-uri(.))) else string(test)", testCase).ToString();
1151
                }
1152
                catch (DynamicError err)
1153
                {
1154
                    Console.WriteLine("*** Failed to read query: " + err.Message);
1155
                    outcome = new Outcome(err);
1156
                }
1157
               
1158

    
1159
                if (outcome == null)
1160
                {
1161
                    if (hostLang.Equals(("XP")))
1162
                    {
1163
                        XPathCompiler testXpc = env.xpathCompiler;
1164
                        testXpc.XPathLanguageVersion = langVersion;
1165
                        testXpc.DeclareNamespace("fn", JNamespaceConstant.FN);
1166
                        testXpc.DeclareNamespace("xs", JNamespaceConstant.SCHEMA);
1167
                        testXpc.DeclareNamespace("math", JNamespaceConstant.MATH);
1168
                        testXpc.DeclareNamespace("map", JNamespaceConstant.MAP_FUNCTIONS);
1169

    
1170
                        try
1171
                        {
1172
                            XPathSelector selector = testXpc.Compile(exp).Load();
1173
                            foreach (QName varName in env.params1.Keys)
1174
                            {
1175
                                selector.SetVariable(varName, env.params1[varName]);
1176
                            }
1177
                            if (env.contextNode != null)
1178
                            {
1179
                                selector.ContextItem = env.contextNode;
1180
                            }
1181
                            
1182
                            selector.InputXmlResolver = new TestUriResolver(env);
1183
                            
1184
                            XdmValue result = selector.Evaluate();
1185
                            outcome = new Outcome(result);
1186
                        }
1187
                        catch (DynamicError err)
1188
                        {
1189
                            Console.WriteLine(err.Message);
1190
                            outcome = new Outcome(err);
1191
                            
1192
                        }
1193
                        catch (StaticError err)
1194
                        {
1195
                            Console.WriteLine(err.Message);
1196
                            outcome = new Outcome(err);
1197

    
1198
                        }
1199
                        catch (Exception err)
1200
                        {
1201
                            Console.WriteLine("*** Failed to read query: " + err.Message);
1202
                            outcome = new Outcome(new DynamicError("*** Failed to read query: " + err.Message));
1203
                        }
1204
                    }
1205
                    else
1206
                    {
1207
                        XQueryCompiler testXqc = env.xqueryCompiler;
1208
                        testXqc.XQueryLanguageVersion = langVersion;
1209
                        testXqc.DeclareNamespace("fn", JNamespaceConstant.FN);
1210
                        testXqc.DeclareNamespace("xs", JNamespaceConstant.SCHEMA);
1211
                        testXqc.DeclareNamespace("math", JNamespaceConstant.MATH);
1212
                        testXqc.DeclareNamespace("map", JNamespaceConstant.MAP_FUNCTIONS);
1213
                        ErrorCollector errorCollector = new ErrorCollector();
1214
                        //testXqc.setErrorListener(errorCollector);
1215
                        string decVars = env.paramDecimalDeclarations.ToString();
1216
                        if (decVars.Length != 0)
1217
                        {
1218
                            int x = (exp.IndexOf("(:%DECL%:)"));
1219
                            if (x < 0)
1220
                            {
1221
                                exp = decVars + exp;
1222
                            }
1223
                            else
1224
                            {
1225
                                exp = exp.Substring(0, x) + decVars + exp.Substring(x + 13);
1226
                            }
1227
                        }
1228
                        string vars = env.paramDeclarations.ToString();
1229
                        if (vars.Length != 0)
1230
                        {
1231
                            int x = (exp.IndexOf("(:%VARDECL%:)"));
1232
                            if (x < 0)
1233
                            {
1234
                                exp = vars + exp;
1235
                            }
1236
                            else
1237
                            {
1238
                                exp = exp.Substring(0, x) + vars + exp.Substring(x + 13);
1239
                            }
1240
                        }
1241
                        ModuleResolver mr = new ModuleResolver(xpc);
1242
                        mr.setTestCase(testCase);
1243
                        testXqc.QueryResolver = (IQueryResolver)mr;
1244

    
1245
                        try
1246
                        {
1247
                            XQueryExecutable q = testXqc.Compile(exp);
1248
                            if (optimization != null)
1249
                            {
1250
                             /*   XdmDestination expDest = new XdmDestination();
1251
                                net.sf.saxon.Configuration config = driverProc.Implementation;
1252
                                net.sf.saxon.trace.ExpressionPresenter presenter = new net.sf.saxon.trace.ExpressionPresenter(driverProc.Implementation, expDest.getReceiver(config));
1253
                                //q.getUnderlyingCompiledQuery().explain(presenter);
1254
                                presenter.close();
1255
                                XdmNode explanation = expDest.XdmNode;
1256
                                XdmItem optResult = xpc.EvaluateSingle(optimization.GetAttributeValue(new QName("assert")), explanation);
1257
                                if ((bool)((XdmAtomicValue)optResult).Value)
1258
                                {
1259
                                    Console.WriteLine("Optimization result OK");
1260
                                }
1261
                                else
1262
                                {
1263
                                    Console.WriteLine("Failed optimization test");
1264
                                    Serializer serializer = new Serializer();
1265
                                    serializer.SetOutputWriter(Console.Error);
1266
                                    driverProc.WriteXdmValue(explanation, serializer);
1267
                                    WriteTestCaseElement(testCaseName, "fail", "Failed optimization assertions");
1268
                                    failures++;
1269
                                    return;
1270
                                }*/
1271

    
1272
                            }
1273
                            XQueryEvaluator selector = q.Load();
1274
                            foreach (QName varName in env.params1.Keys)
1275
                            {
1276
                                selector.SetExternalVariable(varName, env.params1[varName]);
1277
                            }
1278
                            if (env.contextNode != null)
1279
                            {
1280
                                selector.ContextItem = env.contextNode;
1281
                            }
1282
                            selector.InputXmlResolver= new TestUriResolver(env);
1283
                            XdmValue result = selector.Evaluate();
1284
                            outcome = new Outcome(result);
1285
                        }
1286
                        catch (DynamicError err)
1287
                        {
1288
                            Console.WriteLine("TestSet" + testFuncSet);
1289
                            Console.WriteLine(err.Message);
1290
                            outcome = new Outcome(err);
1291
                            outcome.setErrorsReported(errorCollector.getErrorCodes());
1292
                        }
1293
                        catch(StaticError err){
1294
                            Console.WriteLine("TestSet" + testFuncSet);
1295
                            Console.WriteLine(err.Message);
1296
                            outcome = new Outcome(err);
1297
                            outcome.setErrorsReported(errorCollector.getErrorCodes());
1298
                        }
1299
                        catch(Exception err){
1300
                            Console.WriteLine("TestSet" + testFuncSet);
1301
                            Console.WriteLine(err.Message);
1302
                            outcome = new Outcome(new DynamicError(err.Message));
1303
                            outcome.setErrorsReported(errorCollector.getErrorCodes());
1304
                        }
1305
                    }
1306
                }
1307
                XdmNode assertion;
1308
                if (alternativeResult != null)
1309
                {
1310
                    assertion = (XdmNode)xpc.EvaluateSingle("*[1]", alternativeResult);
1311
                }
1312
                else
1313
                {
1314
                    assertion = (XdmNode)xpc.EvaluateSingle("result/*[1]", testCase);
1315
                }
1316
                if (assertion == null)
1317
                {
1318
                    Console.WriteLine("*** No assertions found for test case " + testCaseName);
1319
                    WriteTestCaseElement(testCaseName, "fail", "No assertions in test case");
1320
                    failures++;
1321
                    return;
1322
                }
1323
                XPathCompiler assertXpc = env.processor.NewXPathCompiler();
1324
                assertXpc.XPathLanguageVersion = "3.0";
1325
                assertXpc.DeclareNamespace("fn", JNamespaceConstant.FN);
1326
                assertXpc.DeclareNamespace("xs", JNamespaceConstant.SCHEMA);
1327
                assertXpc.DeclareNamespace("math", JNamespaceConstant.MATH);
1328
                assertXpc.DeclareNamespace("map", JNamespaceConstant.MAP_FUNCTIONS);
1329
                assertXpc.DeclareVariable(new QName("result"));
1330

    
1331
                bool b = testAssertion(assertion, outcome, assertXpc, xpc, debug);
1332
                if (b)
1333
                {
1334
                    Console.WriteLine("OK");
1335
                    successes++;
1336
                    feedback.Message("OK" + Environment.NewLine, false);
1337
                    
1338

    
1339
                    WriteTestCaseElement(testCaseName, "full", null);
1340

    
1341

    
1342
                }
1343
                else
1344
                {
1345
                    
1346

    
1347
                    if (outcome.isException())
1348
                    {
1349
                        XdmItem expectedError = xpc.EvaluateSingle("result//error/@code", testCase);
1350

    
1351
                        if (expectedError == null)
1352
                        {
1353
                            //                        if (debug) {
1354
                            //                            outcome.getException().printStackTrace(System.out);
1355
                            //                        }
1356
                            if (outcome.getException() is StaticError)
1357
                            {
1358
                                WriteTestCaseElement(testCaseName, "fail", "Expected success, got " + ((StaticError)outcome.getException()).ErrorCode);
1359
                                feedback.Message("*** fail, result " + ((StaticError)outcome.getException()).ErrorCode.LocalName +
1360
                                        " Expected success." + Environment.NewLine, false);
1361
                            }
1362
                            else
1363
                            {
1364
                                WriteTestCaseElement(testCaseName, "fail", "Expected success, got " + ((DynamicError)outcome.getException()).ErrorCode);
1365
                                feedback.Message("*** fail, result " + ((DynamicError)outcome.getException()).ErrorCode.LocalName +
1366
                                        " Expected success." + Environment.NewLine, false);
1367
                            }
1368
                            failures++;
1369
                        }
1370
                        else
1371
                        {
1372
                            if (outcome.getException() is StaticError)
1373
                            {
1374
                                WriteTestCaseElement(testCaseName, "different-error", "Expected error:" + expectedError.ToString() /*.GetstringValue()*/ + ", got " + ((StaticError)outcome.getException()).ErrorCode.ToString());
1375
                                feedback.Message("*** fail, result " + ((StaticError)outcome.getException()).ErrorCode.LocalName +
1376
                                        " Expected error:" + expectedError.ToString() + Environment.NewLine, false);
1377
                            }
1378
                            else
1379
                            {
1380
                                WriteTestCaseElement(testCaseName, "different-error", "Expected error:" + expectedError.ToString() /*.GetstringValue()*/ + ", got " + ((DynamicError)outcome.getException()).ErrorCode.ToString());
1381
                                feedback.Message("*** fail, result " + ((DynamicError)outcome.getException()).ErrorCode.LocalName +
1382
                                        " Expected error:" + expectedError.ToString() + Environment.NewLine, false);
1383
                            }
1384
                            wrongErrorResults++;
1385
                        }
1386

    
1387
                    }
1388
                    else
1389
                    {
1390
                        try
1391
                        {
1392
                            WriteTestCaseElement(testCaseName, "fail", "Wrong results, got " + truncate(outcome.serialize(assertXpc.Processor)));
1393
                        }catch (Exception) {
1394
                            WriteTestCaseElement(testCaseName, "fail", "Wrong results, got ");
1395
                        }
1396
                        failures++;
1397
                        if (debug)
1398
                        {
1399
                            try
1400
                            {
1401
                                feedback.Message("Result:" + Environment.NewLine, false);
1402
                               // driverProc.WriteXdmValue(outcome.getResult(), driverSerializer);
1403
                                feedback.Message("=======" + Environment.NewLine, false);
1404
                            }
1405
                            catch (Exception)
1406
                            {
1407
                            }
1408
                            feedback.Message(outcome.getResult() + Environment.NewLine, false);
1409
                        }
1410
                        else
1411
                        {
1412
                            feedback.Message("*** fail (use -debug to show actual result)" + Environment.NewLine, false);
1413
                        }
1414
                    }
1415
                    
1416
                }
1417
                feedback.Feedback(successes, failures, 25693);
1418
            }
1419
        }
1420

    
1421
        private string truncate(string in1)
1422
        {
1423
            if (in1.Length > 80)
1424
            {
1425
                return in1.Substring(0, 80) + "...";
1426
            }
1427
            else
1428
            {
1429
                return in1;
1430
            }
1431
        }
1432

    
1433
        private bool testAssertion(XdmNode assertion, Outcome outcome, XPathCompiler assertXpc, XPathCompiler catalogXpc, bool debug)
1434
        {
1435
            try
1436
            {
1437
                string tag = assertion.NodeName.LocalName;
1438
                bool result = testAssertion2(assertion, outcome, assertXpc, catalogXpc, debug);
1439
                if (debug && !("all-of".Equals(tag)) && !("any-of".Equals(tag)))
1440
                {
1441
                    feedback.Message("Assertion " + tag + " (" + assertion.StringValue + ") " + (result ? " succeeded" : " failed"), false);
1442
                    if (tag.Equals("error"))
1443
                    {
1444
                        Console.WriteLine("Expected exception " + assertion.GetAttributeValue(new QName("code")) +
1445
                                ", got " + (outcome.isException() ? ((DynamicError)outcome.getException()).ErrorCode.ToString() : "success"));
1446
                    }
1447
                }
1448
                return result;
1449
            }
1450
            catch (Exception e)
1451
            {
1452
                //e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
1453
                return false;
1454
            }
1455
        }
1456

    
1457
        private bool testAssertion2(XdmNode assertion, Outcome outcome, XPathCompiler assertXpc, XPathCompiler catalogXpc, bool debug)
1458
        {
1459
            string tag = assertion.NodeName.LocalName;
1460

    
1461
            if (tag.Equals("assert-eq"))
1462
            {
1463
                if (outcome.isException())
1464
                {
1465
                    return false;
1466
                }
1467
                else
1468
                {
1469
                    XPathSelector s = assertXpc.Compile("$result eq " + assertion.StringValue).Load();
1470
                    s.SetVariable(new QName("result"), outcome.getResult());
1471
                    XdmAtomicValue item = (XdmAtomicValue)s.EvaluateSingle();
1472
                    if (s == null)
1473
                    {
1474
                        return false;
1475
                    }
1476
                    return (bool)item.Value;
1477
                }
1478
            }
1479
            if (tag.Equals("assert-deep-eq"))
1480
            {
1481
                if (outcome.isException())
1482
                {
1483
                    return false;
1484
                }
1485
                else
1486
                {
1487
                    XPathSelector s = assertXpc.Compile("deep-equal($result , (" + assertion.StringValue + "))").Load();
1488
                    s.SetVariable(new QName("result"), outcome.getResult());
1489
                    return (bool)((XdmAtomicValue)s.Evaluate()).Value;
1490
                }
1491
            }
1492
            else if (tag.Equals("assert-permutation"))
1493
            {
1494
                // TODO: extend this to handle nodes (if required)
1495
                if (outcome.isException())
1496
                {
1497
                    return false;
1498
                }
1499
                else
1500
                {
1501
                    try
1502
                    {
1503
                        int expectedItems = 0;
1504
                        Hashtable expected = new Hashtable();
1505
                        XPathSelector s = assertXpc.Compile("(" + assertion.StringValue + ")").Load();
1506
                        s.SetVariable(new QName("result"), outcome.getResult()); // not used, but we declared it
1507
                        net.sf.saxon.lib.StringCollator collator = net.sf.saxon.expr.sort.CodepointCollator.getInstance();
1508
                        net.sf.saxon.expr.XPathContext context = new net.sf.saxon.expr.XPathContextMajor(net.sf.saxon.value.StringValue.EMPTY_STRING, assertXpc.Processor.Implementation);
1509
                    /*    foreach (XdmItem item in s) {
1510
                            expectedItems++;
1511
                            XdmValue value = (XdmValue) item;
1512
                            Object comparable = value.isNaN() ?
1513
                                    AtomicSortComparer.COLLATION_KEY_NaN :
1514
                                    value.getXPathComparable(false, collator, context);
1515
                            expected.add(comparable);
1516
                        } */
1517
                        int actualItems = 0;
1518
                        /*foreach (XdmItem item in outcome.getResult()) {
1519
                            actualItems++;
1520
                            AtomicValue value = (AtomicValue) item.getUnderlyingValue();
1521
                            Object comparable = value.isNaN() ?
1522
                                    AtomicSortComparer.COLLATION_KEY_NaN :
1523
                                    value.getXPathComparable(false, collator, context);
1524
                            if (!expected.Contains(comparable)) {
1525
                                return false;
1526
                            }
1527
                        }*/
1528
                        return actualItems == expectedItems;
1529
                    }
1530
                    catch (DynamicError e)
1531
                    {
1532
                        return false;
1533
                    }
1534
                }
1535
            }
1536
            else if (tag.Equals("assert-serialization"))
1537
            {
1538
                if (outcome.isException())
1539
                {
1540
                    return false;
1541
                }
1542
                else
1543
                {
1544
                    string normalizeAtt = assertion.GetAttributeValue(new QName("normalize-space"));
1545
                    bool normalize = normalizeAtt != null && ("true".Equals(normalizeAtt.Trim()) || "1".Equals(normalizeAtt.Trim()));
1546
                    string ignoreAtt = assertion.GetAttributeValue(new QName("ignore-prefixes"));
1547
                    bool ignorePrefixes = ignoreAtt != null && ("true".Equals(ignoreAtt.Trim()) || "1".Equals(ignoreAtt.Trim()));
1548
                    catalogXpc.BaseUri = "";
1549
                    string comparand = catalogXpc.Evaluate("if (@file) then unparsed-text(resolve-uri(@file, base-uri(.))) else string(.)", assertion).ToString();
1550
                    if (normalize)
1551
                    {
1552
                        comparand = net.sf.saxon.value.Whitespace.collapseWhitespace(comparand).ToString();
1553
                    }
1554
                    StringWriter tw = new StringWriter();
1555
                    
1556
                    Serializer serializer = new Serializer();
1557
                    serializer.SetOutputWriter(tw);
1558
                    serializer.SetOutputProperty(Serializer.METHOD, "xml");
1559
                    serializer.SetOutputProperty(Serializer.INDENT, "no");
1560
                    serializer.SetOutputProperty(Serializer.OMIT_XML_DECLARATION, "yes");
1561
                    assertXpc.Processor.WriteXdmValue(outcome.getResult(), serializer);
1562
                    if (comparand.Equals(tw.ToString())) {
1563
                        return true;
1564
                    }
1565
                    DocumentBuilder builder = assertXpc.Processor.NewDocumentBuilder();
1566
                    StringReader reader = new StringReader("<z>" + comparand + "</z>");
1567
                    builder.BaseUri = assertion.BaseUri;
1568
                    XdmNode expected = builder.Build(reader);
1569
                    
1570
                    int flag = 0;
1571

    
1572
                    flag |= net.sf.saxon.functions.DeepEqual.INCLUDE_COMMENTS;
1573
                    flag |= net.sf.saxon.functions.DeepEqual.INCLUDE_PROCESSING_INSTRUCTIONS;
1574
                    if (!ignorePrefixes)
1575
                    {
1576
                        flag |= net.sf.saxon.functions.DeepEqual.INCLUDE_NAMESPACES;
1577
                        flag |= net.sf.saxon.functions.DeepEqual.INCLUDE_PREFIXES;
1578
                    }
1579
                    flag |= net.sf.saxon.functions.DeepEqual.COMPARE_STRING_VALUES;
1580
                    flag |= net.sf.saxon.functions.DeepEqual.WARNING_IF_FALSE;
1581
                    try
1582
                    {
1583
                       net.sf.saxon.om.SequenceIterator iter0;
1584
                       XdmValue v = outcome.getResult();
1585
                       if (v.Count == 1 && v is XdmNode && ((XdmNode)v).NodeKind == XmlNodeType.Document)
1586
                         {
1587
                             iter0 = ((XdmNode)v).Implementation.iterateAxis(net.sf.saxon.om.Axis.CHILD);
1588
                         } else {
1589
                             iter0 = net.sf.saxon.value.Value.asIterator(outcome.getResult().Unwrap());
1590
                         }
1591
                         net.sf.saxon.om.SequenceIterator iter1 = (expected.Implementation.iterateAxis(net.sf.saxon.om.Axis.CHILD).next()).iterateAxis(net.sf.saxon.om.Axis.CHILD);
1592
                         return net.sf.saxon.functions.DeepEqual.deepEquals(
1593
                                 iter0, iter1,
1594
                                 new net.sf.saxon.expr.sort.GenericAtomicComparer(net.sf.saxon.expr.sort.CodepointCollator.getInstance(), null),
1595
                                 assertXpc.Processor.Implementation, flag);
1596
                    }
1597
                    catch (DynamicError e)
1598
                    {
1599
                        // e.printStackTrace();
1600
                        return false;
1601
                    }
1602
                }
1603
            }
1604
            else if (tag.Equals("assert-serialization-error"))
1605
            {
1606
                  if (outcome.isException()) {
1607
                      return false;
1608
                  } else {
1609
                      string expectedError = assertion.GetAttributeValue(new QName("code"));
1610
                      StringWriter sw = new StringWriter();
1611
                      Serializer serializer = new Serializer();
1612
                      serializer.SetOutputWriter(sw);
1613
                      serializer.SetOutputProperty(Serializer.METHOD, "xml");
1614
                      serializer.SetOutputProperty(Serializer.INDENT, "no");
1615
                      serializer.SetOutputProperty(Serializer.OMIT_XML_DECLARATION, "yes");
1616
                      try {
1617
                          assertXpc.Processor.WriteXdmValue(outcome.getResult(), serializer);
1618
                          return false;
1619
                      } catch (DynamicError err) {
1620
                          bool b = expectedError.Equals(err.ErrorCode.LocalName);
1621
                          if (!b)
1622
                          {
1623
                            feedback.Message("Expected " + expectedError + ", got " + err.ErrorCode.LocalName, false);
1624
                          }
1625
                          return true;
1626
                      }
1627
                  }
1628
            }
1629
            else if (tag.Equals("assert-empty"))
1630
            {
1631
                if (outcome.isException())
1632
                {
1633
                    return false;
1634
                }
1635
                else
1636
                {
1637
                    XdmValue result = outcome.getResult();
1638
                    return result.Count == 0;
1639
                }
1640
            }
1641
            else if (tag.Equals("assert-count"))
1642
            {
1643
                if (outcome.isException())
1644
                {
1645
                    return false;
1646
                }
1647
                else
1648
                {
1649
                    XdmValue result = outcome.getResult();
1650
                    return result.Count == int.Parse(assertion.StringValue);
1651
                }
1652
            }
1653
            else if (tag.Equals("assert"))
1654
            {
1655
                if (outcome.isException())
1656
                {
1657
                    return false;
1658
                }
1659
                else
1660
                {
1661
                    XPathSelector s = assertXpc.Compile(assertion.StringValue).Load();
1662
                    s.SetVariable(new QName("result"), outcome.getResult());
1663
                    return (bool)((XdmAtomicValue)s.EvaluateSingle()).Value;
1664
                }
1665
            }
1666
            else if (tag.Equals("assert-string-value"))
1667
            {
1668
                if (outcome.isException())
1669
                {
1670
                    return false;
1671
                }
1672
                else
1673
                {
1674
                    XdmValue resultValue = outcome.getResult();
1675
                    string resultstring;
1676
                    string assertionstring = assertion.StringValue;
1677
                    if (resultValue is XdmNode)
1678
                    {
1679
                        resultstring = ((XdmNode)resultValue).StringValue;
1680
                    }else if(resultValue is XdmAtomicValue){
1681
                        resultstring = ((XdmAtomicValue)resultValue).ToString();
1682
                    }
1683
                    else
1684
                    {
1685
                        bool first = true;
1686
                        StringBuilder fsb = new StringBuilder(256);
1687
                        foreach (XdmItem item in resultValue)
1688
                        {
1689
                            if (first)
1690
                            {
1691
                                first = false;
1692
                            }
1693
                            else
1694
                            {
1695
                                fsb.Append(' ');
1696
                            }
1697
                            fsb.Append(item.Unwrap().getStringValue());
1698
                        }
1699
                        resultstring = fsb.ToString();
1700
                    }
1701
                    string normalizeAtt = assertion.GetAttributeValue(new QName("normalize-space"));
1702
                    if (normalizeAtt != null && (normalizeAtt.Trim().Equals("true") || normalizeAtt.Trim().Equals("1")))
1703
                    {
1704
                        assertionstring = net.sf.saxon.value.Whitespace.collapseWhitespace(assertionstring).ToString();
1705
                        resultstring = net.sf.saxon.value.Whitespace.collapseWhitespace(resultstring).ToString();
1706
                    }
1707
                    if (resultstring.Equals(assertionstring))
1708
                    {
1709
                        return true;
1710
                    }
1711
                    else
1712
                    {
1713
                        if (debug)
1714
                        {
1715
                            if (resultstring.Length != assertionstring.Length)
1716
                            {
1717
                                Console.WriteLine("Result length " + resultstring.Length + "; expected length " + assertionstring.Length);
1718
                            }
1719
                            int len = Math.Min(resultstring.Length, assertionstring.Length);
1720
                            for (int i = 0; i < len; i++)
1721
                            {
1722
                                if (resultstring[i] != assertionstring[i])
1723
                                {
1724
                                    feedback.Message("Results differ at index " + i +
1725
                                            "(\"" + resultstring.Substring(i, (i + 10 > len ? len : i + 10)) + "\") vs (\"" +
1726
                                            assertionstring.Substring(i, (i + 10 > len ? len : i + 10)) + "\")", false);
1727
                                    break;
1728
                                }
1729
                            }
1730
                        }
1731
                        return false;
1732
                    }
1733
                }
1734
            }
1735
            else if (tag.Equals("assert-type"))
1736
            {
1737
                if (outcome.isException())
1738
                {
1739
                    return false;
1740
                }
1741
                else
1742
                {
1743
                    XPathSelector s = assertXpc.Compile("$result instance of " + assertion.StringValue).Load();
1744
                    s.SetVariable(new QName("result"), outcome.getResult());
1745
                    return (bool)((XdmAtomicValue)s.EvaluateSingle()).Value;
1746
                }
1747
            }
1748
            else if (tag.Equals("assert-true"))
1749
            {
1750
                if (outcome.isException())
1751
                {
1752
                    return false;
1753
                }
1754
                else
1755
                {
1756
                    XdmValue result = outcome.getResult();
1757
                    return result.Count == 1  && ((XdmItem)result).IsAtomic() &&
1758
                        ((XdmAtomicValue)result).GetPrimitiveTypeName().Equals(QName.XS_BOOLEAN) &&
1759
                        (((XdmAtomicValue)result).GetBooleanValue());
1760
                }
1761
            }
1762
            else if (tag.Equals("assert-false"))
1763
            {
1764
                if (outcome.isException())
1765
                {
1766
                    return false;
1767
                }
1768
                else
1769
                {
1770
                    XdmValue result = outcome.getResult();
1771
                    return result.Count == 1 &&
1772
                           ((XdmItem)result.Simplify).IsAtomic() &&
1773
                            ((XdmAtomicValue)result.Simplify).GetPrimitiveTypeName().Equals(QName.XS_BOOLEAN) &&
1774
                            !(bool)((XdmAtomicValue)result.Simplify).Value;
1775
                }
1776
            }
1777
            else if (tag.Equals("error"))
1778
            {
1779
                string expectedError = assertion.GetAttributeValue(new QName("code"));
1780
                //noinspection ThrowableResultOfMethodCallIgnored
1781
                Exception err = outcome.getException();
1782
                QName errorCode = null;
1783
                if (err is DynamicError)
1784
                {
1785
                    errorCode = ((DynamicError)outcome.getException()).ErrorCode;
1786
                }
1787
                else {
1788
                    errorCode = ((StaticError)outcome.getException()).ErrorCode;
1789
                }
1790
                 return outcome.isException() &&
1791
                            (expectedError.Equals("*") ||
1792
                                    (errorCode != null &&
1793
                                            errorCode.LocalName.Equals(expectedError)) ||
1794
                                    (outcome.hasReportedError(expectedError)));
1795
                
1796
            }
1797
            else if (tag.Equals("all-of"))
1798
            {
1799
                XdmValue children = catalogXpc.Evaluate("*", assertion);
1800
                foreach (XdmItem child in children)
1801
                {
1802
                    if (!testAssertion((XdmNode)child, outcome, assertXpc, catalogXpc, debug))
1803
                    {
1804
                        return false;
1805
                    }
1806
                }
1807
                return true;
1808
            }
1809
            else if (tag.Equals("any-of"))
1810
            {
1811
                XdmValue children = catalogXpc.Evaluate("*", assertion);
1812
                foreach (XdmItem child in children)
1813
                {
1814
                    if (testAssertion((XdmNode)child, outcome, assertXpc, catalogXpc, debug))
1815
                    {
1816
                        return true;
1817
                    }
1818
                }
1819
                return false;
1820
            }
1821
            throw new Exception("Unknown assertion element " + tag);
1822
        }
1823

    
1824

    
1825
        public void WriteResultFilePreamble(Processor processor, XdmNode catalog, string date)/* throws IOException, SaxonApiException, XMLStreamException*/ {
1826

    
1827
            ///   results = new StreamWriter(/*TODO saxonResultsDir + */"/results"
1828
            //            + processor.ProductVersion + "n.xml");
1829

    
1830
            /*Writer resultWriter = new BufferedWriter(new FileWriter(new File(resultsDir + "/results"
1831
                    + Version.getProductVersion() + ".xml")));
1832
            Serializer serializer = processor.NewSerializer(resultWriter);
1833
            serializer.setOutputProperty(Serializer.Property.METHOD, "xml");
1834
            serializer.setOutputProperty(Serializer.Property.INDENT, "yes");
1835
            serializer.setOutputProperty(Serializer.Property.SAXON_LINE_LENGTH, "120");*/
1836
            //results = serializer.GetResult();// .getXMLStreamWriter();
1837
            
1838
            results = new StreamWriter(resultsDir + "/results"
1839
                        + processor.ProductVersion + "n.xml");
1840

    
1841
            
1842
            results.WriteLine("<FOTS-test-suite-result>");
1843
            // results.writeDefaultNamespace(RNS);
1844
            results.WriteLine("<implementation name='Saxon-EE' version='" + processor.ProductVersion + "' anonymous-result-column='false'    >");
1845
            //  results.writeAttribute("version", Version.getProductVersion());
1846
            results.WriteLine("<organization name='http://www.saxonica.com/' anonymous='false' />");
1847
            results.WriteLine("<submitter name='ONeil Delpratt' email='oneil@saxonica.com' />");
1848
            results.WriteLine("</implementation>"); //implementation
1849
            results.WriteLine("<test-run date='" + date + "' testSuiteVersion='" + catalog.GetAttributeValue(new QName("test-suite")) + " " + catalog.GetAttributeValue(new QName("version")) + "'/>");
1850

    
1851
        }
1852

    
1853
        private void writeResultFilePostamble()
1854
        {
1855
            results.WriteLine("</FOTS-test-suite-result>"); //test-suite-result
1856
            results.Close();
1857
        }
1858

    
1859
        private void WriteTestCaseElement(string name, string result, string comment)
1860
        {
1861
            try
1862
            {
1863
                results.WriteLine("<testcase name='" + name + "' result='" + result + "' " + (comment != null ? "comment='" + comment + "'" : "") + " />");
1864
                /*if (comment != null) {
1865
                    results.writeAttribute("comment", comment);
1866
                }*/
1867
            }
1868
            catch (DynamicError ex)
1869
            {
1870
            }
1871
        }
1872

    
1873
        /**
1874
         * Implement extension function fots:copy() which copies an existing node to create
1875
         * a new parentless node. Needed because XPath cannot create parentless nodes directly
1876
         */
1877

    
1878
        private class FotsCopyFunction /*: ExtensionFunctionDefinition*/
1879
        {
1880

    
1881
            public QName GetFunctionQName()
1882
            {
1883
                return new QName("", "http://www.w3.org/2010/09/qt-fots-catalog", "copy");
1884
            }
1885

    
1886

    
1887
            public int GetMinimumNumberOfArguments()
1888
            {
1889
                return 1;
1890
            }
1891

    
1892

    
1893
            public int GetMaximumNumberOfArguments()
1894
            {
1895
                return 1;
1896
            }
1897

    
1898

    
1899
            /*public SequenceType[] getArgumentTypes() {
1900
                return new SequenceType[]{SequenceType.SINGLE_NODE};
1901
            }*/
1902

    
1903

    
1904
            /*public SequenceType getResultType(SequenceType[] suppliedArgumentTypes) {
1905
                return SequenceType.SINGLE_NODE;
1906
            }*/
1907

    
1908

    
1909
            public bool hasSideEffects()
1910
            {
1911
                return true;
1912
            }
1913

    
1914

    
1915
            public ExtensionFunctionCall makeCallExpression()
1916
            {
1917
                return null;
1918
                /*TODO new ExtensionFunctionCall() {
1919
                    public SequenceIterator call(SequenceIterator[] arguments, XPathContext context) throws XPathException {
1920
                        NodeInfo node = (NodeInfo) arguments[0].next();
1921
                        if (node == null) {
1922
                            return EmptyIterator.getInstance();
1923
                        } else {
1924
                            switch (node.getNodeKind()) {
1925
                                case Type.ELEMENT:
1926
                                case Type.DOCUMENT: {
1927
                                    Builder builder = context.getController().makeBuilder();
1928
                                    builder.open();
1929
                                    node.copy(builder, NodeInfo.ALL_NAMESPACES, 0);
1930
                                    builder.close();
1931
                                    return SingleNodeIterator.makeIterator(builder.getCurrentRoot());
1932
                                }
1933
                                case Type.ATTRIBUTE:
1934
                                case Type.TEXT:
1935
                                case Type.PROCESSING_INSTRUCTION:
1936
                                case Type.COMMENT:
1937
                                case Type.NAMESPACE:
1938
                                    Orphan orphan = new Orphan(context.getConfiguration());
1939
                                    orphan.setNodeKind((short) node.getNodeKind());
1940
                                    orphan.setNodeName(new NameOfNode(node));
1941
                                    orphan.setstringValue(node.getstringValue());
1942
                                    return SingleNodeIterator.makeIterator(orphan);
1943
                                default:
1944
                                    throw new IllegalArgumentException("Unknown node kind " + node.getNodeKind());
1945
                            }
1946
                        }
1947
                    }
1948
                };*/
1949
            }
1950

    
1951
        }
1952

    
1953

    
1954
            public class ModuleResolver : IQueryResolver
1955
            {
1956

    
1957
                XPathCompiler catXPC;
1958
                XdmNode testCase;
1959
                XmlUrlResolver resolver;
1960

    
1961
                public ModuleResolver(XPathCompiler xpc)
1962
                {
1963
                    this.catXPC = xpc;
1964
                    resolver = new XmlUrlResolver();
1965
                   
1966
                }
1967

    
1968
                public void setTestCase(XdmNode testCase)
1969
                {
1970
                    this.testCase = testCase;
1971
                }
1972

    
1973
                public Object GetEntity(Uri absoluteUri)
1974
                {
1975
                    String u = absoluteUri.ToString();
1976
                    if (u.StartsWith("file:///"))
1977
                    {
1978
                        u = u.Substring(8);
1979
                    }
1980
                    else if (u.StartsWith("file:/"))
1981
                    {
1982
                        u = u.Substring(6);
1983
                    }
1984
                    return new FileStream(u, FileMode.Open, FileAccess.Read, FileShare.Read);
1985
                }
1986

    
1987
                public Uri[] GetModules(string moduleUri, Uri baseUri, string[] locations)
1988
                {
1989
                       try {
1990
                           XdmValue files = catXPC.Evaluate("./module[@uri='" + moduleUri + "']/@file/string()", testCase);
1991
                           if (files.Count == 0) {
1992
                               throw new DynamicError("Failed to find module entry for " + moduleUri);
1993
                           }
1994

    
1995
                           Uri[] ss = new Uri[files.Count];
1996
                           int i = 0;
1997
                           foreach(XdmItem nodei in files){
1998
                               ss[i] = resolver.ResolveUri(testCase.BaseUri, nodei.ToString());
1999
                               i++;
2000
                           }
2001
                          
2002
                           return ss;
2003
                       } catch (Exception e) {
2004
                           throw new DynamicError(e.Message);
2005
                       }
2006
                   } 
2007
            }
2008

    
2009
            public class TestUriResolver : XmlUrlResolver
2010
            {
2011
                TestEnvironment env1;
2012

    
2013
                public TestUriResolver(TestEnvironment env)
2014
                {
2015
                    this.env1 = env;
2016
                }
2017

    
2018
                public override Uri ResolveUri(Uri base1, string href)
2019
                {
2020
                    XdmNode node = null;
2021
                    try
2022
                    {
2023
                        node = env1.sourceDocs[href];
2024
                    } catch(Exception) {
2025
                        return (new XmlUrlResolver()).ResolveUri(base1, href);
2026
                    
2027
                    }
2028
                    if (node == null)
2029
                    {
2030
                        return null;
2031
                    }
2032
                    else
2033
                    {
2034
                        return node.DocumentUri;
2035
                    }
2036
                }
2037
            }
2038

    
2039
            private class LazyLiteralInjector /*: net.sf.saxon.expr.parser.CodeInjector*/
2040
            {
2041
                /*  public Expression inject(Expression exp, StaticContext env, int construct, StructuredQName qName) {
2042
                      if (exp is Literal) {
2043
                          StructuredQName name = new StructuredQName("saxon", JNamespaceConstant.SAXON, "lazy-literal");
2044
                          JavaExtensionFunctionCall wrapper = new JavaExtensionFunctionCall();
2045
                          try {
2046
                              wrapper.init(name, FOTestSuiteDriver.class,
2047
                                      FOTestSuiteDriver.class.getMethod("lazyLiteral", ValueRepresentation.class),
2048
                                      env.getConfiguration());
2049
                              wrapper.setArguments(new Expression[]{exp});
2050
                          } catch (NoSuchMethodException e) {
2051
                              throw new IllegalStateException(e);
2052
                          }
2053
                          return wrapper;
2054
                      } else {
2055
                          return exp;
2056
                      }
2057
                  }*/
2058
            }
2059

    
2060
            /**
2061
             * Static method called as an external function call to evaluate a literal when running in "unfolded" mode.
2062
             * The function simply returns the value of its argument - but the optimizer doesn't know that, so it
2063
             * can't pre-evaluate the call at compile time.
2064
             *
2065
             * @param value the value to be returned
2066
             * @return the supplied value, unchanged
2067
             */
2068

    
2069
            /*public static ValueRepresentation lazyLiteral(ValueRepresentation value) {
2070
                return value;
2071
            }*/
2072

    
2073
            public class ErrorCollector /*: net.sf.saxon.lib.StandardErrorListener*/
2074
            {
2075

    
2076
                private Hashtable errorCodes = new Hashtable();
2077

    
2078

    
2079
                public void error(DynamicError exception)
2080
                {
2081
                    addErrorCode(exception);
2082
                   // base.error;
2083

    
2084
                }
2085

    
2086

    
2087
                public void fatalError(DynamicError exception)
2088
                {
2089
                    addErrorCode(exception);
2090
                    //super.fatalError(exception);
2091
                }
2092

    
2093
                /**
2094
                 * Make a clean copy of this ErrorListener. This is necessary because the
2095
                 * standard error listener is stateful (it remembers how many errors there have been)
2096
                 *
2097
                 * @param hostLanguage the host language (not used by this implementation)
2098
                 * @return a copy of this error listener
2099
                 */
2100

    
2101
                /*public DynamicError StandardErrorListener makeAnother(int hostLanguage)
2102
                {
2103
                    return DynamicError();
2104
                }*/
2105

    
2106
                private void addErrorCode(DynamicError exception)
2107
                {
2108
                    //if (exception is XPathException) {
2109
                    string errorCode = exception.ErrorCode.ToString();
2110
                    if (errorCode != null)
2111
                    {
2112
                        errorCodes.Add(errorCode, true);
2113
                    }
2114
                    //}
2115
                }
2116

    
2117
                public Hashtable getErrorCodes()
2118
                {
2119
                    return errorCodes;
2120
                }
2121
            }
2122

    
2123
    }
(5-5/14)