001: /********************************************************************************
002: * CruiseControl, a Continuous Integration Toolkit
003: * Copyright (c) 2007, ThoughtWorks, Inc.
004: * 200 E. Randolph, 25th Floor
005: * Chicago, IL 60601 USA
006: * All rights reserved.
007: *
008: * Redistribution and use in source and binary forms, with or without
009: * modification, are permitted provided that the following conditions
010: * are met:
011: *
012: * + Redistributions of source code must retain the above copyright
013: * notice, this list of conditions and the following disclaimer.
014: *
015: * + Redistributions in binary form must reproduce the above
016: * copyright notice, this list of conditions and the following
017: * disclaimer in the documentation and/or other materials provided
018: * with the distribution.
019: *
020: * + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the
021: * names of its contributors may be used to endorse or promote
022: * products derived from this software without specific prior
023: * written permission.
024: *
025: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
026: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
027: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
028: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
029: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
030: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
031: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
032: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
033: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
034: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
035: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
036: ********************************************************************************/package net.sourceforge.cruisecontrol.sourcecontrols;
037:
038: import junit.framework.TestCase;
039: import net.sourceforge.cruisecontrol.CruiseControlException;
040: import net.sourceforge.cruisecontrol.Modification;
041: import net.sourceforge.cruisecontrol.testutil.TestUtil;
042: import org.jdom.JDOMException;
043:
044: import java.io.BufferedInputStream;
045: import java.io.File;
046: import java.io.InputStream;
047: import java.io.IOException;
048: import java.text.ParseException;
049: import java.text.SimpleDateFormat;
050: import java.util.ArrayList;
051: import java.util.Date;
052: import java.util.List;
053: import java.util.Map;
054: import java.util.TimeZone;
055:
056: /**
057: * @author <a href="jerome@coffeebreaks.org">Jerome Lacoste</a>
058: * @see <a href="http://www.selenic.com/mercurial">Mercurial web site</a>
059: */
060: public class MercurialTest extends TestCase {
061: private Mercurial mercurial;
062: private TimeZone originalTimeZone;
063: private File tempFile;
064:
065: protected void setUp() throws Exception {
066: mercurial = new Mercurial();
067: originalTimeZone = TimeZone.getDefault();
068: tempFile = File.createTempFile("temp", "txt");
069: tempFile.deleteOnExit();
070: }
071:
072: protected void tearDown() throws Exception {
073: TimeZone.setDefault(originalTimeZone);
074: }
075:
076: public void testValidateNoAttributesSet() throws IOException {
077: try {
078: mercurial.validate();
079: } catch (CruiseControlException e) {
080: fail("should not throw an exception when no attributes are set "
081: + e.getMessage());
082: }
083: }
084:
085: public void testValidatInvalidLocalWorkingCopy() throws IOException {
086: mercurial.setLocalWorkingCopy("invalid directory");
087: try {
088: mercurial.validate();
089: fail("should throw an exception when an invalid 'localWorkingCopy' attribute is set");
090: } catch (CruiseControlException e) {
091: // expected
092: }
093: }
094:
095: public void testValidateValidLocalWorkingCopy() throws IOException {
096:
097: mercurial = new Mercurial();
098: mercurial.setLocalWorkingCopy(tempFile.getParent());
099: try {
100: mercurial.validate();
101: } catch (CruiseControlException e) {
102: fail("should not throw an exception when at least a valid 'localWorkingCopy' "
103: + "attribute is set");
104: }
105: }
106:
107: public void testValidateFailWhenLocalWorkingCopyIsAFile()
108: throws IOException {
109: mercurial = new Mercurial();
110: mercurial.setLocalWorkingCopy(tempFile.getAbsolutePath());
111: try {
112: mercurial.validate();
113: fail("should throw an exception when 'localWorkingCopy' is file instead of directory.");
114: } catch (CruiseControlException e) {
115: // expected
116: }
117: }
118:
119: public void testBuildHistoryCommand() throws CruiseControlException {
120: mercurial.setLocalWorkingCopy(".");
121:
122: String[] expectedCmd = new String[] { "hg", "incoming",
123: "--debug", "--template",
124: Mercurial.INCOMING_XML_TEMPLATE };
125: String[] actualCmd = mercurial.buildHistoryCommand()
126: .getCommandline();
127: TestUtil.assertArray("", expectedCmd, actualCmd);
128: }
129:
130: public void testParseModifications() throws JDOMException,
131: ParseException, IOException {
132: BufferedInputStream input = new BufferedInputStream(
133: loadTestLog("mercurial_incoming_xml_debug.txt"));
134: List modifications = Mercurial.parseStream(input);
135: input.close();
136:
137: assertEquals("Should have returned 7 modifications.", 7,
138: modifications.size());
139:
140: Modification modification = createModification(
141: parseIso8601Format("2007-08-27 16:11:19 +0200"),
142: "ET4642@localhost", "Test of a fourth commit",
143: "3:bb0a5f00315f4f6dddb7362a69bc0910b07c4faa", "",
144: "file1.txt", "modified");
145: assertEquals(modification, modifications.get(0));
146:
147: modification = createModification(
148: parseIso8601Format("2007-08-29 21:38:18 +0200"),
149: "ET4642@edbwp000856.edb.local", "Changed 2 files",
150: "4:1da89ee88532fddb21235b2d21e4a46424adbe39", "",
151: "file1.txt", "modified");
152: assertEquals(modification, modifications.get(1));
153:
154: modification = createModification(
155: parseIso8601Format("2007-08-29 21:38:18 +0200"),
156: "ET4642@edbwp000856.edb.local", "Changed 2 files",
157: "4:1da89ee88532fddb21235b2d21e4a46424adbe39", "",
158: "file2.txt", "modified");
159: assertEquals(modification, modifications.get(2));
160:
161: modification = createModification(
162: parseIso8601Format("2007-08-29 21:44:37 +0200"),
163: "ET4642@edbwp000856.edb.local",
164: "new change, with one directory depth",
165: "5:93981bd125719a98d7c11028560b2b736b3f12ec", "",
166: "file2.txt", "modified");
167: assertEquals(modification, modifications.get(3));
168:
169: modification = createModification(
170: parseIso8601Format("2007-08-29 21:44:37 +0200"),
171: "ET4642@edbwp000856.edb.local",
172: "new change, with one directory depth",
173: "5:93981bd125719a98d7c11028560b2b736b3f12ec", "",
174: "mydir/newfile.txt", "added");
175: assertEquals(modification, modifications.get(4));
176:
177: modification = createModification(
178: parseIso8601Format("2007-08-30 09:09:08 +0200"),
179: "ET4642@localhost", "removed one file, changed one",
180: "6:e3cefb520ddc6c7de8bad83f17df4b3d4194fe08", "",
181: "file2.txt", "removed");
182: assertEquals(modification, modifications.get(5));
183:
184: modification = createModification(
185: parseIso8601Format("2007-08-30 09:09:08 +0200"),
186: "ET4642@localhost", "removed one file, changed one",
187: "6:e3cefb520ddc6c7de8bad83f17df4b3d4194fe08", "",
188: "file1.txt", "modified");
189: assertEquals(modification, modifications.get(6));
190:
191: }
192:
193: private Date parseIso8601Format(String iso8601Date)
194: throws ParseException {
195: return Iso8601DateParser.parse(iso8601Date);
196: }
197:
198: // 2007-08-29 21:44:19 +0200
199: private static final class Iso8601DateParser {
200: private Iso8601DateParser() {
201: }
202:
203: public static final SimpleDateFormat ISO8601_DATE_PARSER = new SimpleDateFormat(
204: "yyyy-MM-d HH:mm:ss Z");
205:
206: private static Date parse(String date) throws ParseException {
207: return ISO8601_DATE_PARSER.parse(date);
208: }
209: }
210:
211: private InputStream loadTestLog(String name) {
212: InputStream testStream = getClass().getResourceAsStream(name);
213: assertNotNull("failed to load resource " + name + " in class "
214: + getClass().getName(), testStream);
215: return testStream;
216: }
217:
218: public void testSetPropertyNoChanges() throws ParseException {
219: mercurial.setProperty("hasChanges?");
220:
221: List noModifications = new ArrayList();
222: mercurial.fillPropertiesIfNeeded(noModifications);
223:
224: assertFalse(mercurial.getProperties()
225: .containsKey("hasChanges?"));
226: assertEquals(null, mercurial.getProperties().get("hgrevision"));
227: }
228:
229: public void testSetPropertyHasChanges() throws ParseException {
230: mercurial.setProperty("hasChanges?");
231:
232: List hasModifications = new ArrayList();
233: hasModifications.add(createModification(
234: parseIso8601Format("2007-08-27 16:11:19 +0200"),
235: "ET4642@localhost", "Test of a fourth commit",
236: "3:bb0a5f00315f4f6dddb7362a69bc0910b07c4faa", "",
237: "file1.txt", "modified"));
238:
239: hasModifications.add(createModification(
240: parseIso8601Format("2007-08-29 21:38:18 +0200"),
241: "ET4642@edbwp000856.edb.local", "Changed 2 files",
242: "4:1da89ee88532fddb21235b2d21e4a46424adbe39", "",
243: "file1.txt", "modified"));
244:
245: mercurial.fillPropertiesIfNeeded(hasModifications);
246: Map properties = mercurial.getProperties();
247: assertEquals("true", properties.get("hasChanges?"));
248: assertEquals("4:1da89ee88532fddb21235b2d21e4a46424adbe39",
249: properties.get("hgrevision"));
250: }
251:
252: public void testSetPropertyIgnoresPriorState()
253: throws ParseException {
254: testSetPropertyHasChanges();
255: mercurial.fillPropertiesIfNeeded(new ArrayList());
256:
257: assertFalse(mercurial.getProperties()
258: .containsKey("hasChanges?"));
259: }
260:
261: public void testSetPropertyOnDeleteEmptyModifications()
262: throws ParseException {
263: mercurial.setPropertyOnDelete("hasDeletions?");
264:
265: List noModifications = new ArrayList();
266: mercurial.fillPropertiesIfNeeded(noModifications);
267:
268: assertEquals(null, mercurial.getProperties().get(
269: "hasDeletions?"));
270: }
271:
272: public void testSetPropertyOnDeleteNoDeletion()
273: throws ParseException {
274: mercurial.setPropertyOnDelete("hasDeletions?");
275:
276: List noDeletions = new ArrayList();
277: noDeletions.add(createModification(
278: parseIso8601Format("2007-08-27 16:11:19 +0200"),
279: "ET4642@localhost", "Test of a fourth commit",
280: "3:bb0a5f00315f4f6dddb7362a69bc0910b07c4faa", "",
281: "file1.txt", "modified"));
282:
283: mercurial.fillPropertiesIfNeeded(noDeletions);
284:
285: assertEquals(null, mercurial.getProperties().get(
286: "hasDeletions?"));
287: }
288:
289: public void testSetPropertyOnDeleteHasDeletion()
290: throws ParseException {
291: mercurial.setPropertyOnDelete("hasDeletions?");
292:
293: List hasDeletions = new ArrayList();
294: hasDeletions.add(createModification(
295: parseIso8601Format("2007-08-27 16:11:19 +0200"),
296: "ET4642@localhost", "Test of a fourth commit",
297: "3:bb0a5f00315f4f6dddb7362a69bc0910b07c4faa", "",
298: "file1.txt", "modified"));
299:
300: hasDeletions.add(createModification(
301: parseIso8601Format("2007-08-29 21:38:18 +0200"),
302: "ET4642@edbwp000856.edb.local", "Changed 2 files",
303: "4:1da89ee88532fddb21235b2d21e4a46424adbe39", "",
304: "file1.txt", "deleted"));
305: mercurial.fillPropertiesIfNeeded(hasDeletions);
306: assertEquals("true", mercurial.getProperties().get(
307: "hasDeletions?"));
308: }
309:
310: private static Modification createModification(Date date,
311: String user, String comment, String revision,
312: String folder, String file, String type) {
313: Modification modification = new Modification("mercurial");
314: Modification.ModifiedFile modifiedFile = modification
315: .createModifiedFile(file, folder);
316: modifiedFile.action = type;
317: modifiedFile.revision = revision;
318:
319: modification.modifiedTime = date;
320: modification.userName = user;
321: modification.comment = comment;
322: modification.revision = revision;
323: return modification;
324: }
325:
326: public void testParseVersion() throws JDOMException, IOException,
327: ParseException {
328: BufferedInputStream input = new BufferedInputStream(
329: loadTestLog("mercurial_version.txt"));
330: String version = Mercurial.parseVersionStream(input);
331: input.close();
332:
333: assertEquals("version 0.9.4", version);
334: }
335:
336: public void testBuildVersionCommand() throws CruiseControlException {
337: mercurial.setLocalWorkingCopy(".");
338: String[] expectedCmd = { "hg", "version" };
339: String[] actualCmd = mercurial.buildVersionCommand()
340: .getCommandline();
341: TestUtil.assertArray("", expectedCmd, actualCmd);
342: }
343: }
|