Project

Profile

Help

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

he / tags / 9.4.0.7 / hen / csource / samples / FileComparer.cs @ b0b00ab2

1
using System;
2
using System.IO;
3
using System.Collections;
4
using System.Xml;
5
using System.Collections.Generic;
6
using System.Text;
7
using Saxon.Api;
8

    
9
namespace TestRunner
10
{
11
    /// <summary>
12
    /// Code to compare actual results of a test (outfile) with reference results (reffile).
13
    /// The parameter comparator is the name of a comparison method: xml, html, xml-frag, xhtml, inspect.
14
    /// The return value is "OK" if the files compare equal. Any string starting with "#" indicates the files are
15
    /// considered equal but with a comment (e.g. that they are equal after removing whitespace). Any other string indicates
16
    /// not equal, with an explanation of why.
17
    /// </summary>
18

    
19
    
20
    class FileComparer
21
    {
22
        private Processor processor;
23
        private String comparerDir = "e:/tests/comparers/";
24
        bool debug = false;
25

    
26
        public FileComparer(Processor processor, String testSuiteDir)
27
        {
28
            this.processor = processor;
29
            //this.testSuiteDir = testSuiteDir;
30
        }
31

    
32
        public String compare(String outfile, String reffile, String comparator)
33
        {
34
            if (comparator == "Ignore")
35
            {
36
                return "OK";
37
            }
38
            if (reffile == null || !File.Exists(reffile))
39
            {
40
                Console.WriteLine("*** No reference results available");
41
                return "No reference results available";
42
            }
43

    
44
            // try direct comparison first
45

    
46
            String refResult = null;
47
            String actResult = null;
48

    
49
            try
50
            {
51
                // This is decoding bytes assuming the platform default encoding
52
                StreamReader reader1;
53
                try
54
                {
55
                    reader1 = new StreamReader(outfile);
56
                }
57
                catch (Exception err)
58
                {
59
                    Console.WriteLine("Failed to read output file " + outfile + ": " + err);
60
                    return "Failed to read output file " + outfile + ": " + err;
61
                }
62
                StreamReader reader2;
63
                try
64
                {
65
                    reader2 = new StreamReader(reffile);
66
                }
67
                catch (Exception err)
68
                {
69
                    Console.WriteLine("Failed to read reference file " + reffile + ": " + err);
70
                    return "Failed to read reference file " + reffile + ": " + err;
71
                }
72

    
73
                char[] contents1 = new char[65536];
74
                char[] contents2 = new char[65536];
75
                int size1 = reader1.Read(contents1, 0, 65536);
76
                int size2 = reader2.Read(contents2, 0, 65536);
77
                reader1.Close();
78
                reader2.Close();
79

    
80
                int offset1 = 0;
81
                int offset2 = 0;
82
                if (contents1[0] == '\u00ef' && contents1[1] == '\u00bb' && contents1[2] == '\u00bf')
83
                {
84
                    offset1 += 3;
85
                }
86
                if (contents2[0] == '\u00ef' && contents2[1] == '\u00bb' && contents2[2] == '\u00bf')
87
                {
88
                    offset2 += 3;
89
                }
90
                actResult = (size1 == -1 ? "" : new String(contents1, offset1, size1 - offset1));
91
                refResult = (size2 == -1 ? "" : new String(contents2, offset2, size2 - offset2));
92

    
93
                actResult = actResult.Replace("\r\n", "\n");
94
                refResult = refResult.Replace("\r\n", "\n");
95
                if (actResult.Equals(refResult))
96
                {
97
                    return "OK";
98
                }
99
                if (size1 == 0)
100
                {
101
                    Console.WriteLine("** ACTUAL RESULTS EMPTY; REFERENCE RESULTS LENGTH " + size2);
102
                    return "** ACTUAL RESULTS EMPTY; REFERENCE RESULTS LENGTH " + size2;
103
                }
104
                if (size2 == 0)
105
                {
106
                    Console.WriteLine("** REFERENCED RESULTS EMPTY; ACTUAL RESULTS LENGTH " + size2);
107
                    return "** REFERENCED RESULTS EMPTY; ACTUAL RESULTS LENGTH " + size2;
108
                }
109

    
110
            }
111
            catch (Exception e)
112
            {
113
                Console.Write(e.StackTrace);
114
                return "Exception: " + e.Message;
115
            }
116

    
117
            // HTML: can't do logical comparison
118

    
119
            if (comparator.Equals("html-output"))
120
            {
121

    
122
                Console.WriteLine("*** Compare HTML outputs by hand");
123
                return "Compare HTML outputs by hand";
124

    
125
            }
126
            else if (comparator.Equals("xhtml-output"))
127
            {
128
                refResult = canonizeXhtml(processor, refResult);
129
                actResult = canonizeXhtml(processor, actResult);
130
                return (actResult.Equals(refResult)) ? "OK" : "XHTML canonical results differ";
131

    
132
            }
133
            else if (comparator.Equals("xml-frag") || comparator.Equals("Text") || comparator.Equals("Fragment"))
134
            {
135
                try
136
                {
137
                    return compareFragments(actResult, refResult);
138
                }
139
                catch (Exception err2)
140
                {
141
                    Console.WriteLine("Failed to compare results for: " + outfile);
142
                    Console.Write(err2.StackTrace);
143
                    return "Failure while comparing fragments: " + err2.Message;
144
                }
145
            }
146
            else
147
            {
148
                // convert both files to Canonical XML and compare them again
149
                return compareXML(outfile, reffile);
150

    
151
            }
152
        }
153

    
154
        XsltExecutable xhtmlCanonizer;
155

    
156
        private String canonizeXhtml(Processor p, String input)
157
        {
158
            try
159
            {
160
                XsltExecutable canonizer = getXhtmlCanonizer(p);
161
                XsltTransformer t = canonizer.Load();
162
                StringWriter sw = new StringWriter();
163
                Serializer r = new Serializer();
164
                r.SetOutputWriter(sw);
165
                t.InitialContextNode = p.NewDocumentBuilder().Build(
166
                    new FileStream(input, FileMode.Open));
167
                t.Run(r);
168
                return sw.ToString();
169
            }
170
            catch (Exception err)
171
            {
172
                Console.WriteLine("*** Failed to compile or run XHTML canonicalizer stylesheet: " + err.ToString());
173
            }
174
            return "";
175
        }
176

    
177
        private XsltExecutable getXhtmlCanonizer(Processor p)
178
        {
179
            if (xhtmlCanonizer == null)
180
            {
181
                xhtmlCanonizer = p.NewXsltCompiler().Compile(
182
                    new FileStream(comparerDir + "/canonizeXhtml.xsl", FileMode.Open));
183
            }
184
            return xhtmlCanonizer;
185
        }
186

    
187
        /// <summary>
188
        /// Compare XML fragments
189
        /// </summary>
190
        /// <param name="actual">Actual results (the results, not the filename)</param>
191
        /// <param name="gold">Reference results (the results, not the filename)</param>
192
        /// <returns>"OK" if equivalent</returns>
193

    
194
        private String compareFragments(String actual, String gold)
195
        {
196

    
197
            String a = "<d>" + expandSpecialChars(actual) + "</d>";
198
            String g = "<d>" + expandSpecialChars(gold) + "</d>";
199
            XdmNode doc1;
200
            try
201
            {
202
                doc1 = processor.NewDocumentBuilder().Build(
203
                    new XmlTextReader(new StringReader(a)));
204
            }
205
            catch (Exception e)
206
            {
207
                //Console.WriteLine(e.StackTrace);
208
                Console.WriteLine("*** Error parsing actual results " + e.Message);
209
                Console.WriteLine(a);
210
                return "*** Error parsing actual results " + e.Message;
211
            }
212
            XdmNode doc2;
213
            try
214
            {
215
                doc2 = processor.NewDocumentBuilder().Build(
216
                    new XmlTextReader(new StringReader(g)));
217
            }
218
            catch (Exception e)
219
            {
220
                //Console.WriteLine(e.StackTrace);
221
                Console.WriteLine("*** Error parsing gold results " + e.Message);
222
                Console.WriteLine(g);
223
                return "*** Error parsing gold results " + e.Message;
224
            }
225
            try
226
            {
227
                return compareDocs(doc1, doc2);
228
            }
229
            catch (Exception e)
230
            {
231
                //Console.WriteLine(e.StackTrace);
232
                Console.WriteLine("*** Error comparing results " + e.Message);
233
                return "*** Error comparing results " + e.Message;
234
            }
235
        }
236

    
237
        private String expandSpecialChars(String s)
238
        {
239
            StringBuilder sb = new StringBuilder();
240
            int start = 0;
241
            if (s.StartsWith("<?xml"))
242
            {
243
                start = s.IndexOf("?>") + 2;
244
            }
245
            for (int i = start; i < s.Length; i++)
246
            {
247
                char c = s[i];
248
                if (c < 127)
249
                {
250
                    sb.Append(c);
251
                }
252
                else if (c >= 55296 && c <= 56319)
253
                {
254
                    // we'll trust the data to be sound
255
                    int charval = ((c - 55296) * 1024) + ((int)s[i + 1] - 56320) + 65536;
256
                    sb.Append("&#" + charval + ";");
257
                    i++;
258
                }
259
                else
260
                {
261
                    sb.Append("&#" + ((int)c) + ";");
262
                }
263
            }
264
            return sb.ToString();
265
        }
266

    
267
        private static String truncate(String s)
268
        {
269
            if (s.Length > 200) return s.Substring(0, 200);
270
            return s;
271
        }
272

    
273
        private static void findDiff(String s1, String s2)
274
        {
275
            int i = 0;
276
            while (true)
277
            {
278
                if (s1[i] != s2[i])
279
                {
280
                    int j = (i < 50 ? 0 : i - 50);
281
                    int k = (i + 50 > s1.Length || i + 50 > s2.Length ? i + 1 : i + 50);
282
                    Console.WriteLine("Different at char " + i + "\n+" + s1.Substring(j, k) +
283
                                       "\n+" + s2.Substring(j, k));
284
                    break;
285
                }
286
                if (i >= s1.Length) break;
287
                if (i >= s2.Length) break;
288
                i++;
289
            }
290
        }
291

    
292

    
293

    
294
        private XsltExecutable xmlComparer = null;
295

    
296
        /// <summary>
297
        /// Compare two XML files
298
        /// </summary>
299
        /// <param name="actual">The URI of the first file</param>
300
        /// <param name="gold">The URI of the second file</param>
301
        /// <returns></returns>
302

    
303
        private String compareXML(String actual, String gold)
304
        {
305
            try
306
            {
307
                if (xmlComparer == null)
308
                {
309
                    xmlComparer = processor.NewXsltCompiler().Compile(new Uri(comparerDir + "/compare.xsl"));
310
                }
311
                XdmNode doc1 = processor.NewDocumentBuilder().Build(new Uri(actual));
312
                XdmNode doc2 = processor.NewDocumentBuilder().Build(new Uri(gold));
313
                return compareDocs(doc1, doc2);
314
            }
315
            catch (Exception e)
316
            {
317
                Console.WriteLine("***" + e.Message);
318
                return "XML comparison failure: " + e.Message;
319
            }
320
        }
321

    
322
        private String compareDocs(XdmNode doc1, XdmNode doc2) {
323
            try {
324
                XsltTransformer t = xmlComparer.Load();
325
                t.InitialTemplate = new QName("", "compare");
326
                t.SetParameter(new QName("", "actual"), doc1);
327
                t.SetParameter(new QName("", "gold"), doc2);
328
                t.SetParameter(new QName("", "debug"), new XdmAtomicValue(debug));
329

    
330
                StringWriter sw = new StringWriter();
331
                Serializer sr = new Serializer();
332
                sr.SetOutputWriter(sw);
333

    
334
                t.Run(sr);
335
                String result = sw.ToString();
336
                if (result.StartsWith("true"))
337
                {
338
                    return "OK";
339
                }
340
                else
341
                {
342
                    return "XML comparison - not equal";
343
                }
344
            }
345
            catch (Exception e)
346
            {
347
                Console.WriteLine("***" + e.Message);
348
                return "XML comparison failure: " + e.Message;
349
            }
350
        }
351

    
352
    }
353
}
(6-6/14)