001: /*
002: * Copyright (c) 2001-2007, Jean Tessier
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions
007: * are met:
008: *
009: * * Redistributions of source code must retain the above copyright
010: * notice, this list of conditions and the following disclaimer.
011: *
012: * * Redistributions in binary form must reproduce the above copyright
013: * notice, this list of conditions and the following disclaimer in the
014: * documentation and/or other materials provided with the distribution.
015: *
016: * * Neither the name of Jean Tessier nor the names of his contributors
017: * may be used to endorse or promote products derived from this software
018: * without specific prior written permission.
019: *
020: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
021: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
022: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
023: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
024: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
027: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
028: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
029: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
030: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031: */
032:
033: package com.jeantessier.diff;
034:
035: import java.io.*;
036: import java.util.*;
037: import javax.xml.parsers.*;
038: import javax.xml.transform.*;
039:
040: import com.sun.org.apache.xpath.internal.*;
041: import junit.framework.*;
042: import org.apache.oro.text.perl.*;
043: import org.w3c.dom.*;
044: import org.xml.sax.*;
045:
046: import com.jeantessier.classreader.*;
047:
048: public class TestReport extends TestCase implements ErrorHandler {
049: private static final String SPECIFIC_ENCODING = "iso-latin-1";
050: private static final String SPECIFIC_DTD_PREFIX = "./etc";
051:
052: private static final String OLD_CLASSPATH = "tests"
053: + File.separator + "JarJarDiff" + File.separator + "old";
054: private static final String NEW_CLASSPATH = "tests"
055: + File.separator + "JarJarDiff" + File.separator + "new";
056:
057: private static final String OLD_PUBLISHED_CLASSPATH = "tests"
058: + File.separator + "JarJarDiff" + File.separator
059: + "oldpublished";
060: private static final String NEW_PUBLISHED_CLASSPATH = "tests"
061: + File.separator + "JarJarDiff" + File.separator
062: + "newpublished";
063:
064: private XMLReader reader;
065: private Perl5Util perl;
066:
067: protected void setUp() throws Exception {
068: reader = SAXParserFactory.newInstance().newSAXParser()
069: .getXMLReader();
070: reader.setFeature("http://xml.org/sax/features/validation",
071: true);
072: reader
073: .setFeature(
074: "http://apache.org/xml/features/nonvalidating/load-external-dtd",
075: true);
076: reader.setErrorHandler(this );
077:
078: perl = new Perl5Util();
079: }
080:
081: public void testDefaultDTDPrefix() {
082: Visitor printer = new Report();
083:
084: String xmlDocument = printer.toString();
085: assertTrue(xmlDocument + "Missing DTD", perl.match(
086: "/DOCTYPE \\S+ SYSTEM \"(.*)\"/", xmlDocument));
087: assertTrue("DTD \"" + perl.group(1)
088: + "\" does not have prefix \""
089: + Report.DEFAULT_DTD_PREFIX + "\"", perl.group(1)
090: .startsWith(Report.DEFAULT_DTD_PREFIX));
091:
092: try {
093: reader
094: .parse(new InputSource(
095: new StringReader(xmlDocument)));
096: } catch (SAXException ex) {
097: fail("Could not parse XML Document: " + ex.getMessage()
098: + "\n" + xmlDocument);
099: } catch (IOException ex) {
100: fail("Could not read XML Document: " + ex.getMessage()
101: + "\n" + xmlDocument);
102: }
103: }
104:
105: public void testSpecificDTDPrefix() {
106: Visitor printer = new Report(Report.DEFAULT_ENCODING,
107: SPECIFIC_DTD_PREFIX);
108:
109: String xmlDocument = printer.toString();
110: assertTrue(xmlDocument + "Missing DTD", perl.match(
111: "/DOCTYPE \\S+ SYSTEM \"(.*)\"/", xmlDocument));
112: assertTrue("DTD \"" + perl.group(1)
113: + "\" does not have prefix \"./etc\"", perl.group(1)
114: .startsWith(SPECIFIC_DTD_PREFIX));
115:
116: try {
117: reader
118: .parse(new InputSource(
119: new StringReader(xmlDocument)));
120: } catch (SAXException ex) {
121: fail("Could not parse XML Document: " + ex.getMessage()
122: + "\n" + xmlDocument);
123: } catch (IOException ex) {
124: fail("Could not read XML Document: " + ex.getMessage()
125: + "\n" + xmlDocument);
126: }
127: }
128:
129: public void testDefaultEncoding() {
130: Visitor printer = new Report();
131:
132: String xmlDocument = printer.toString();
133: assertTrue(xmlDocument + "Missing encoding", perl.match(
134: "/encoding=\"([^\"]*)\"/", xmlDocument));
135: assertEquals("Encoding", Report.DEFAULT_ENCODING, perl.group(1));
136:
137: try {
138: reader
139: .parse(new InputSource(
140: new StringReader(xmlDocument)));
141: } catch (SAXException ex) {
142: fail("Could not parse XML Document: " + ex.getMessage()
143: + "\n" + xmlDocument);
144: } catch (IOException ex) {
145: fail("Could not read XML Document: " + ex.getMessage()
146: + "\n" + xmlDocument);
147: }
148: }
149:
150: public void testSpecificEncoding() {
151: Visitor printer = new Report(SPECIFIC_ENCODING,
152: Report.DEFAULT_DTD_PREFIX);
153:
154: String xmlDocument = printer.toString();
155: assertTrue(xmlDocument + "Missing encoding", perl.match(
156: "/encoding=\"([^\"]*)\"/", xmlDocument));
157: assertEquals("Encoding", SPECIFIC_ENCODING, perl.group(1));
158:
159: try {
160: reader
161: .parse(new InputSource(
162: new StringReader(xmlDocument)));
163: } catch (SAXException ex) {
164: fail("Could not parse XML Document: " + ex.getMessage()
165: + "\n" + xmlDocument);
166: } catch (IOException ex) {
167: fail("Could not read XML Document: " + ex.getMessage()
168: + "\n" + xmlDocument);
169: }
170: }
171:
172: public void testContent() throws IOException,
173: ParserConfigurationException, SAXException,
174: TransformerException {
175: PackageMapper oldPackages = new PackageMapper();
176: ClassfileLoader oldJar = new AggregatingClassfileLoader();
177: oldJar.addLoadListener(oldPackages);
178: oldJar.load(Collections.singleton(OLD_CLASSPATH));
179:
180: PackageMapper newPackages = new PackageMapper();
181: ClassfileLoader newJar = new AggregatingClassfileLoader();
182: newJar.addLoadListener(newPackages);
183: newJar.load(Collections.singleton(NEW_CLASSPATH));
184:
185: DifferencesFactory factory = new DifferencesFactory();
186: ProjectDifferences projectDifferences = (ProjectDifferences) factory
187: .createProjectDifferences("test", "old", oldPackages,
188: "new", newPackages);
189:
190: Visitor printer = new Report(Report.DEFAULT_ENCODING,
191: SPECIFIC_DTD_PREFIX);
192: projectDifferences.accept(printer);
193:
194: String xmlDocument = printer.toString();
195:
196: try {
197: reader
198: .parse(new InputSource(
199: new StringReader(xmlDocument)));
200: } catch (SAXException ex) {
201: fail("Could not parse XML Document: " + ex.getMessage()
202: + "\n" + xmlDocument);
203: } catch (IOException ex) {
204: fail("Could not read XML Document: " + ex.getMessage()
205: + "\n" + xmlDocument);
206: }
207:
208: InputSource in = new InputSource(new StringReader(xmlDocument));
209: Document doc = DocumentBuilderFactory.newInstance()
210: .newDocumentBuilder().parse(in);
211:
212: assertNotNull("//differences", XPathAPI.selectSingleNode(doc,
213: "//differences"));
214: assertNotNull("*/old[text()='old']", XPathAPI.selectSingleNode(
215: doc, "*/old[text()='old']"));
216: assertEquals("*/modified-classes/class", 3, XPathAPI
217: .selectNodeList(doc, "*/modified-classes/class")
218: .getLength());
219: }
220:
221: public void testIncompatibleContent() throws IOException,
222: ParserConfigurationException, SAXException,
223: TransformerException {
224: PackageMapper oldPackages = new PackageMapper();
225: ClassfileLoader oldJar = new AggregatingClassfileLoader();
226: oldJar.addLoadListener(oldPackages);
227: oldJar.load(Collections.singleton(OLD_PUBLISHED_CLASSPATH
228: + File.separator + "ModifiedPackage" + File.separator
229: + "CompatibleClass.class"));
230:
231: PackageMapper newPackages = new PackageMapper();
232: ClassfileLoader newJar = new AggregatingClassfileLoader();
233: newJar.addLoadListener(newPackages);
234: newJar.load(Collections.singleton(NEW_PUBLISHED_CLASSPATH
235: + File.separator + "ModifiedPackage" + File.separator
236: + "CompatibleClass.class"));
237:
238: DifferencesFactory factory = new DifferencesFactory(
239: new IncompatibleDifferenceStrategy(
240: new NoDifferenceStrategy()));
241: ProjectDifferences projectDifferences = (ProjectDifferences) factory
242: .createProjectDifferences("test", "old", oldPackages,
243: "new", newPackages);
244:
245: Visitor printer = new Report(Report.DEFAULT_ENCODING,
246: SPECIFIC_DTD_PREFIX);
247: projectDifferences.accept(printer);
248:
249: String xmlDocument = printer.toString();
250:
251: try {
252: reader
253: .parse(new InputSource(
254: new StringReader(xmlDocument)));
255: } catch (SAXException ex) {
256: fail("Could not parse XML Document: " + ex.getMessage()
257: + "\n" + xmlDocument);
258: } catch (IOException ex) {
259: fail("Could not read XML Document: " + ex.getMessage()
260: + "\n" + xmlDocument);
261: }
262:
263: InputSource in = new InputSource(new StringReader(xmlDocument));
264: Document doc = DocumentBuilderFactory.newInstance()
265: .newDocumentBuilder().parse(in);
266:
267: assertNotNull("//differences", XPathAPI.selectSingleNode(doc,
268: "//differences"));
269: assertNotNull("*/old[text()='old']", XPathAPI.selectSingleNode(
270: doc, "*/old[text()='old']"));
271: assertEquals("*/modified-classes/class", 1, XPathAPI
272: .selectNodeList(doc, "*/modified-classes/class")
273: .getLength());
274: assertNull(
275: "*/modified-classes/class/modified-declaration",
276: XPathAPI
277: .selectSingleNode(doc,
278: "*/modified-classes/class/modified-declaration"));
279: assertEquals(
280: "*/modified-classes/class/modified-methods/feature",
281: 1,
282: XPathAPI
283: .selectNodeList(doc,
284: "*/modified-classes/class/modified-methods/feature")
285: .getLength());
286: assertNotNull(
287: "*/modified-classes/class/modified-methods/feature/modified-declaration",
288: XPathAPI
289: .selectSingleNode(doc,
290: "*/modified-classes/class/modified-methods/feature/modified-declaration"));
291: }
292:
293: public void error(SAXParseException ex) {
294: // Ignore
295: }
296:
297: public void fatalError(SAXParseException ex) {
298: // Ignore
299: }
300:
301: public void warning(SAXParseException ex) {
302: // Ignore
303: }
304: }
|