bd9ade36038e4d8f92bcdab088cb89a7dea1599b
[mono.git] / mcs / tools / compiler-tester / xmldocdiff.cs
1 //\r
2 // xmldocdiff.cs\r
3 //\r
4 // Author:\r
5 //   Marek Safar (marek.safar@gmail.com)\r
6 //\r
7 // Copyright (C) 2012 Xamarin Inc (http://www.xamarin.com)\r
8 //\r
9 // Permission is hereby granted, free of charge, to any person obtaining\r
10 // a copy of this software and associated documentation files (the\r
11 // "Software"), to deal in the Software without restriction, including\r
12 // without limitation the rights to use, copy, modify, merge, publish,\r
13 // distribute, sublicense, and/or sell copies of the Software, and to\r
14 // permit persons to whom the Software is furnished to do so, subject to\r
15 // the following conditions:\r
16 // \r
17 // The above copyright notice and this permission notice shall be\r
18 // included in all copies or substantial portions of the Software.\r
19 // \r
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
27 //
28 \r
29 #if !NET_2_1\r
30 \r
31 using System;\r
32 using System.Collections;\r
33 using System.Collections.Generic;\r
34 using System.Xml;\r
35 using System.Linq;\r
36 \r
37 public class XmlComparer\r
38 {\r
39         public class ComparisonException : Exception\r
40         {\r
41                 public ComparisonException (string message)\r
42                         : base (message)\r
43                 {\r
44                 }\r
45         }\r
46 \r
47         static readonly bool debug = false;\r
48         readonly string start;\r
49 \r
50         public XmlComparer (string startNode)\r
51         {\r
52                 this.start = "/" + startNode;\r
53         }\r
54 \r
55         public void Compare (string reference, string output)\r
56         {\r
57                 XmlDocument doc1 = new XmlDocument ();\r
58                 doc1.Load (reference);\r
59                 XmlDocument doc2 = new XmlDocument ();\r
60                 doc2.Load (output);\r
61 \r
62                 var memberList1 = doc1.SelectSingleNode (start);\r
63                 var memberList2 = doc2.SelectSingleNode (start);\r
64 \r
65                 CompareNodes (memberList1, memberList2);\r
66         }\r
67 \r
68         static bool CompareNodes (XmlNode reference, XmlNode output)\r
69         {\r
70                 List<Tuple<string, XmlNode>> ref_nodes = new List<Tuple<string, XmlNode>> ();\r
71                 foreach (XmlNode node in reference.ChildNodes) {\r
72                         if (node.NodeType == XmlNodeType.Comment)\r
73                                 continue;\r
74 \r
75                         ref_nodes.Add (Tuple.Create (node.Name, node));\r
76                 }\r
77 \r
78                 foreach (XmlNode node in output.ChildNodes) {\r
79                         if (node.NodeType == XmlNodeType.Comment)\r
80                                 continue;\r
81 \r
82                         Tuple<string, XmlNode> found = null;\r
83                         foreach (var entry in ref_nodes.Where (l => l.Item1 == node.Name)) {\r
84                                 if (node.Attributes == null) {\r
85                                         if (node.Attributes != entry.Item2.Attributes)\r
86                                                 continue;\r
87                                 } else {\r
88                                         List<XmlAttribute> attrs = node.Attributes.Cast<XmlAttribute> ().ToList ();\r
89                                         XmlAttribute missing = null;\r
90                                         foreach (XmlAttribute attr in entry.Item2.Attributes) {\r
91                                                 var match = attrs.Find (l => l.Name == attr.Name);\r
92                                                 if (match == null) {\r
93                                                         missing = attr;\r
94                                                         break;\r
95                                                 }\r
96 \r
97                                                 if (match.Value == attr.Value)\r
98                                                         attrs.Remove (match);\r
99                                         }\r
100 \r
101                                         if (missing != null || attrs.Count > 0) {\r
102                                                 continue;\r
103                                         }\r
104                                 }\r
105 \r
106                                 if (node.HasChildNodes != entry.Item2.HasChildNodes)\r
107                                         continue;\r
108 \r
109                                 if (!node.HasChildNodes || CompareNodes (node, entry.Item2)) {\r
110                                         found = entry;\r
111                                         break;\r
112                                 }\r
113                         }\r
114 \r
115                         if (found == null) {\r
116                                 Report ("Expected node: " + node.OuterXml);\r
117                                 return false;\r
118                         }\r
119 \r
120                         ref_nodes.Remove (found);\r
121                 }\r
122 \r
123                 if (ref_nodes.Count > 0) {\r
124                         Report ("Unexpected node: " + ref_nodes[0].Item2.OuterXml);\r
125                         return false;\r
126                 }\r
127 \r
128                 return true;\r
129         }\r
130 \r
131         static void Report (string format, params object[] args)\r
132         {\r
133                 if (debug)\r
134                         Console.WriteLine (format, args);\r
135                 else\r
136                         throw new ComparisonException (String.Format (format, args));\r
137         }\r
138 }\r
139 \r
140 #endif