1 | /* |
2 | * Copyright (c) 2001-2009, Jean Tessier |
3 | * All rights reserved. |
4 | * |
5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions |
7 | * are met: |
8 | * |
9 | * * Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. |
11 | * |
12 | * * Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. |
15 | * |
16 | * * Neither the name of Jean Tessier nor the names of his contributors |
17 | * may be used to endorse or promote products derived from this software |
18 | * without specific prior written permission. |
19 | * |
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR |
24 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
25 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
26 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
27 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
29 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
30 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
31 | */ |
32 | |
33 | package com.jeantessier.diff; |
34 | |
35 | import java.io.*; |
36 | import javax.xml.parsers.*; |
37 | import javax.xml.xpath.*; |
38 | |
39 | import org.xml.sax.*; |
40 | |
41 | import com.jeantessier.classreader.*; |
42 | |
43 | public class TestClassReport extends TestDifferencesFactoryBase implements ErrorHandler { |
44 | private static final String MODIFIED_CLASS_NAME = "ModifiedPackage.ModifiedClass"; |
45 | |
46 | private Classfile oldClassfile; |
47 | private Classfile newClassfile; |
48 | |
49 | private ClassDifferences classDifferences; |
50 | |
51 | private ClassReport classReport; |
52 | |
53 | private XMLReader reader; |
54 | |
55 | protected void setUp() throws Exception { |
56 | super.setUp(); |
57 | |
58 | oldClassfile = getOldJar().getClassfile(MODIFIED_CLASS_NAME); |
59 | newClassfile = getNewJar().getClassfile(MODIFIED_CLASS_NAME); |
60 | |
61 | classDifferences = new ClassDifferences(MODIFIED_CLASS_NAME, oldClassfile, newClassfile); |
62 | |
63 | classReport = new ClassReport(); |
64 | |
65 | boolean validate = Boolean.getBoolean("DEPENDENCYFINDER_TESTS_VALIDATE"); |
66 | |
67 | reader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); |
68 | reader.setFeature("http://xml.org/sax/features/validation", validate); |
69 | reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", validate); |
70 | reader.setErrorHandler(this); |
71 | } |
72 | |
73 | public void testXmlEscapingRemovedLessThanFieldValue() throws Exception { |
74 | String name = "REMOVED_LESS_THAN_STRING"; |
75 | addRemovedFieldDifferences(name); |
76 | |
77 | classReport.visitClassDifferences(classDifferences); |
78 | |
79 | assertAttributeValue("removed-fields/declaration", name, "<"); |
80 | } |
81 | |
82 | public void testXmlEscapingRemovedAmpersandFieldValue() throws Exception { |
83 | String name = "REMOVED_AMPERSAND_STRING"; |
84 | addRemovedFieldDifferences(name); |
85 | |
86 | classReport.visitClassDifferences(classDifferences); |
87 | |
88 | assertAttributeValue("removed-fields/declaration", name, "&"); |
89 | } |
90 | |
91 | public void testXmlEscapingRemovedGreaterThanFieldValue() throws Exception { |
92 | String name = "REMOVED_GREATER_THAN_STRING"; |
93 | addRemovedFieldDifferences(name); |
94 | |
95 | classReport.visitClassDifferences(classDifferences); |
96 | |
97 | assertAttributeValue("removed-fields/declaration", name, ">"); |
98 | } |
99 | |
100 | public void testXmlEscapingRemovedQuoteFieldValue() throws Exception { |
101 | String name = "REMOVED_QUOTE_STRING"; |
102 | addRemovedFieldDifferences(name); |
103 | |
104 | classReport.visitClassDifferences(classDifferences); |
105 | |
106 | assertAttributeValue("removed-fields/declaration", name, "\""); |
107 | } |
108 | |
109 | public void testXmlEscapingRemovedApostropheFieldValue() throws Exception { |
110 | String name = "REMOVED_APOSTROPHE_STRING"; |
111 | addRemovedFieldDifferences(name); |
112 | |
113 | classReport.visitClassDifferences(classDifferences); |
114 | |
115 | assertAttributeValue("removed-fields/declaration", name, "'"); |
116 | } |
117 | |
118 | public void testXmlEscapingRemovedNonAsciiFieldValue() throws Exception { |
119 | String name = "REMOVED_NON_ASCII_STRING"; |
120 | addRemovedFieldDifferences(name); |
121 | |
122 | classReport.visitClassDifferences(classDifferences); |
123 | |
124 | assertAttributeValue("removed-fields/declaration", name, "?"); |
125 | } |
126 | |
127 | public void testXmlEscapingModifiedLessThanFieldValue() throws Exception { |
128 | String name = "MODIFIED_LESS_THAN_STRING"; |
129 | addModifiedFieldDifferences(name); |
130 | |
131 | classReport.visitClassDifferences(classDifferences); |
132 | |
133 | assertAttributeValue("modified-fields/feature/modified-declaration/new-declaration", name, "<"); |
134 | } |
135 | |
136 | public void testXmlEscapingModifiedAmpersandFieldValue() throws Exception { |
137 | String name = "MODIFIED_AMPERSAND_STRING"; |
138 | addModifiedFieldDifferences(name); |
139 | |
140 | classReport.visitClassDifferences(classDifferences); |
141 | |
142 | assertAttributeValue("modified-fields/feature/modified-declaration/new-declaration", name, "&"); |
143 | } |
144 | |
145 | public void testXmlEscapingModifiedGreaterThanFieldValue() throws Exception { |
146 | String name = "MODIFIED_GREATER_THAN_STRING"; |
147 | addModifiedFieldDifferences(name); |
148 | |
149 | classReport.visitClassDifferences(classDifferences); |
150 | |
151 | assertAttributeValue("modified-fields/feature/modified-declaration/new-declaration", name, ">"); |
152 | } |
153 | |
154 | public void testXmlEscapingModifiedQuoteFieldValue() throws Exception { |
155 | String name = "MODIFIED_QUOTE_STRING"; |
156 | addModifiedFieldDifferences(name); |
157 | |
158 | classReport.visitClassDifferences(classDifferences); |
159 | |
160 | assertAttributeValue("modified-fields/feature/modified-declaration/new-declaration", name, "\""); |
161 | } |
162 | |
163 | public void testXmlEscapingModifiedApostropheFieldValue() throws Exception { |
164 | String name = "MODIFIED_APOSTROPHE_STRING"; |
165 | addModifiedFieldDifferences(name); |
166 | |
167 | classReport.visitClassDifferences(classDifferences); |
168 | |
169 | assertAttributeValue("modified-fields/feature/modified-declaration/new-declaration", name, "'"); |
170 | } |
171 | |
172 | public void testXmlEscapingModifiedNonAsciiFieldValue() throws Exception { |
173 | String name = "MODIFIED_NON_ASCII_STRING"; |
174 | addModifiedFieldDifferences(name); |
175 | |
176 | classReport.visitClassDifferences(classDifferences); |
177 | |
178 | assertAttributeValue("modified-fields/feature/modified-declaration/new-declaration", name, "?"); |
179 | } |
180 | |
181 | public void testXmlEscapingNewLessThanFieldValue() throws Exception { |
182 | String name = "NEW_LESS_THAN_STRING"; |
183 | addNewFieldDifferences(name); |
184 | |
185 | classReport.visitClassDifferences(classDifferences); |
186 | |
187 | assertAttributeValue("new-fields/declaration", name, "<"); |
188 | } |
189 | |
190 | public void testXmlEscapingNewAmpersandFieldValue() throws Exception { |
191 | String name = "NEW_AMPERSAND_STRING"; |
192 | addNewFieldDifferences(name); |
193 | |
194 | classReport.visitClassDifferences(classDifferences); |
195 | |
196 | assertAttributeValue("new-fields/declaration", name, "&"); |
197 | } |
198 | |
199 | public void testXmlEscapingNewGreaterThanFieldValue() throws Exception { |
200 | String name = "NEW_GREATER_THAN_STRING"; |
201 | addNewFieldDifferences(name); |
202 | |
203 | classReport.visitClassDifferences(classDifferences); |
204 | |
205 | assertAttributeValue("new-fields/declaration", name, ">"); |
206 | } |
207 | |
208 | public void testXmlEscapingNewQuoteFieldValue() throws Exception { |
209 | String name = "NEW_QUOTE_STRING"; |
210 | addNewFieldDifferences(name); |
211 | |
212 | classReport.visitClassDifferences(classDifferences); |
213 | |
214 | assertAttributeValue("new-fields/declaration", name, "\""); |
215 | } |
216 | |
217 | public void testXmlEscapingNewApostropheFieldValue() throws Exception { |
218 | String name = "NEW_APOSTROPHE_STRING"; |
219 | addNewFieldDifferences(name); |
220 | |
221 | classReport.visitClassDifferences(classDifferences); |
222 | |
223 | assertAttributeValue("new-fields/declaration", name, "'"); |
224 | } |
225 | |
226 | public void testXmlEscapingNewNonAsciiFieldValue() throws Exception { |
227 | String name = "NEW_NON_ASCII_STRING"; |
228 | addNewFieldDifferences(name); |
229 | |
230 | classReport.visitClassDifferences(classDifferences); |
231 | |
232 | assertAttributeValue("new-fields/declaration", name, "?"); |
233 | } |
234 | |
235 | private void addRemovedFieldDifferences(String name) { |
236 | Field_info oldField = oldClassfile.getField(name); |
237 | FieldDifferences fieldDifferences = new FieldDifferences(oldField.getFullName(), oldField, null); |
238 | classDifferences.getFeatureDifferences().add(fieldDifferences); |
239 | } |
240 | |
241 | private void addModifiedFieldDifferences(String name) { |
242 | Field_info oldField = oldClassfile.getField(name); |
243 | Field_info newField = newClassfile.getField(name); |
244 | FieldDifferences fieldDifferences = new FieldDifferences(oldField.getFullName(), oldField, newField); |
245 | fieldDifferences.setConstantValueDifference(true); |
246 | classDifferences.getFeatureDifferences().add(fieldDifferences); |
247 | } |
248 | |
249 | private void addNewFieldDifferences(String name) { |
250 | Field_info newField = newClassfile.getField(name); |
251 | FieldDifferences fieldDifferences = new FieldDifferences(newField.getFullName(), null, newField); |
252 | classDifferences.getFeatureDifferences().add(fieldDifferences); |
253 | } |
254 | |
255 | private void assertAttributeValue(String nodeName, String nameAttribute, String valueAttribute) throws Exception { |
256 | String xmlDocument = classReport.render(); |
257 | |
258 | try { |
259 | reader.parse(new InputSource(new StringReader(xmlDocument))); |
260 | } catch (SAXException ex) { |
261 | fail("Could not parse XML Document: " + ex.getMessage() + "\n" + xmlDocument); |
262 | } catch (IOException ex) { |
263 | fail("Could not read XML Document: " + ex.getMessage() + "\n" + xmlDocument); |
264 | } |
265 | |
266 | XPath xPath = XPathFactory.newInstance().newXPath(); |
267 | InputSource in = new InputSource(new StringReader(xmlDocument)); |
268 | |
269 | String xPathExpression = "*/" + nodeName + "[@name='" + nameAttribute + "']/@value"; |
270 | String result = xPath.evaluate(xPathExpression, in); |
271 | assertEquals("XPath \"" + xPathExpression + "\" in \n" + xmlDocument, valueAttribute, result); |
272 | } |
273 | |
274 | public void error(SAXParseException ex) { |
275 | // Ignore |
276 | } |
277 | |
278 | public void fatalError(SAXParseException ex) { |
279 | // Ignore |
280 | } |
281 | |
282 | public void warning(SAXParseException ex) { |
283 | // Ignore |
284 | } |
285 | } |