View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.scm.provider.svn.svnexe.command.changelog;
20  
21  import java.io.File;
22  import java.io.IOException;
23  import java.text.DateFormat;
24  import java.text.SimpleDateFormat;
25  import java.util.Date;
26  import java.util.LinkedHashMap;
27  import java.util.List;
28  import java.util.Map;
29  import java.util.TimeZone;
30  import java.util.concurrent.atomic.AtomicInteger;
31  
32  import org.apache.maven.scm.ChangeFile;
33  import org.apache.maven.scm.ChangeSet;
34  import org.apache.maven.scm.ScmFileStatus;
35  import org.apache.maven.scm.ScmTestCase;
36  import org.apache.maven.scm.util.ConsumerUtils;
37  import org.junit.Before;
38  import org.junit.Test;
39  import org.slf4j.Logger;
40  import org.slf4j.LoggerFactory;
41  
42  import static org.junit.Assert.assertEquals;
43  import static org.junit.Assert.assertTrue;
44  import static org.junit.Assert.fail;
45  
46  /**
47   * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
48   *
49   */
50  public class SvnChangeLogConsumerTest extends ScmTestCase {
51      Logger logger = LoggerFactory.getLogger(getClass());
52  
53      SvnChangeLogConsumer consumer;
54  
55      @Before
56      @Override
57      public void setUp() throws Exception {
58          super.setUp();
59          consumer = new SvnChangeLogConsumer(null);
60      }
61  
62      /**
63       * Initial modifications should be empty.
64       */
65      @Test
66      public void testGetModifications_Initial() {
67          assertTrue(
68                  "Initial modifications should be empty",
69                  consumer.getModifications().isEmpty());
70      }
71  
72      /**
73       * Valid svn log output should have expected values.
74       *
75       * @throws Exception if any problem occurs.
76       */
77      @Test
78      public void testConsumeLine_ValidOutput() throws Exception {
79          final File svnLog = getTestFile("/src/test/resources/svn/changelog/svnLogValidOutput.txt");
80  
81          consumeLog(svnLog);
82  
83          final ChangeSet entry = consumer.getModifications().get(0);
84  
85          final List<ChangeFile> changedFiles = entry.getFiles();
86          final String revision = changedFiles.get(0).getRevision();
87  
88          assertEquals("Valid revision expected", "15", revision);
89          assertEquals("Valid num changed files expected", 2, changedFiles.size());
90          assertEquals("Valid name expected", "unconventional author output (somedata)", entry.getAuthor());
91          String expectedDate = getLocalizedDate("2002-08-26 14:33:26", TimeZone.getTimeZone("GMT-4"));
92          assertEquals("Valid date expected", expectedDate, entry.getDateFormatted());
93          assertEquals("Valid comment expected", "Minor formatting changes.\n", entry.getComment());
94      }
95  
96      private static String getLocalizedDate(String date, TimeZone timeZone) throws Exception {
97          DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
98          fmt.setTimeZone(timeZone);
99          Date parsed = fmt.parse(date);
100         fmt = new SimpleDateFormat("yyyy-MM-dd");
101         return fmt.format(parsed);
102     }
103 
104     /**
105      * Svn log output with an invalid reason should throw an IllegalOutputException.
106      *
107      * @throws Exception
108      */
109     @Test
110     public void testConsumeLine_InvalidReason() throws Exception {
111         final File svnLog = getTestFile("/src/test/resources/svn/changelog/svnLogInvalidReason.txt");
112 
113         try {
114             consumeLog(svnLog);
115             fail("Svn log output with an invalid reason should throw IllegalOutputException");
116         } catch (final IllegalOutputException e) {
117             assertTrue(true);
118         }
119     }
120 
121     /**
122      * Svn log output with an invalid date should throw an IllegalOutputException.
123      *
124      * @throws Exception
125      */
126     @Test
127     public void testConsumeLine_InvalidDate() throws Exception {
128         final File svnLog = getTestFile("/src/test/resources/svn/changelog/svnLogInvalidDate.txt");
129         try {
130             consumeLog(svnLog);
131             fail("Svn log output with an invalid date should throw IllegalOutputException");
132         } catch (final IllegalOutputException e) {
133             assertTrue(true);
134         }
135     }
136 
137     /**
138      * Consumes change log information stored in a file.
139      *
140      * @param logFile the file.
141      * @throws IOException if a problem occurs.
142      */
143     private void consumeLog(final File logFile) throws IOException {
144         ConsumerUtils.consumeFile(logFile, consumer);
145     }
146 
147     @Test
148     public void testConsumerWithPattern1() throws Exception {
149         StringBuilder out = new StringBuilder();
150 
151         File f = getTestFile("/src/test/resources/svn/changelog/svnlog.txt");
152 
153         ConsumerUtils.consumeFile(f, consumer);
154 
155         List<ChangeSet> modifications = consumer.getModifications();
156 
157         out.append("Text format:");
158 
159         out.append("nb modifications : " + modifications.size());
160 
161         for (ChangeSet entry : modifications) {
162 
163             out.append("Author:" + entry.getAuthor());
164 
165             out.append("Date:" + entry.getDate());
166 
167             out.append("Comment:" + entry.getComment());
168 
169             for (ChangeFile file : entry.getFiles()) {
170 
171                 out.append("File:" + file.getName());
172             }
173 
174             out.append("==============================");
175         }
176 
177         out.append("XML format:");
178 
179         out.append("nb modifications : " + modifications.size());
180 
181         for (ChangeSet entry : modifications) {
182             out.append(entry.toXML());
183 
184             out.append("==============================");
185         }
186 
187         if (logger.isDebugEnabled()) {
188             logger.debug(out.toString());
189         }
190     }
191 
192     @Test
193     public void testConsumerWithPattern2() throws Exception {
194         StringBuilder out = new StringBuilder();
195 
196         File f = getTestFile("/src/test/resources/svn/changelog/svnlog2.txt");
197 
198         ConsumerUtils.consumeFile(f, consumer);
199 
200         List<ChangeSet> modifications = consumer.getModifications();
201 
202         out.append("nb modifications : " + modifications.size());
203 
204         int origFileCounter = 0;
205 
206         // must use *Linked* HashMap to have predictable toString
207         final Map<ScmFileStatus, AtomicInteger> summary = new LinkedHashMap<>();
208 
209         for (ChangeSet entry : consumer.getModifications()) {
210 
211             out.append("Author:" + entry.getAuthor());
212 
213             out.append("Date:" + entry.getDate());
214 
215             out.append("Comment:" + entry.getComment());
216 
217             for (ChangeFile file : entry.getFiles()) {
218                 final ScmFileStatus action = file.getAction();
219                 if (!summary.containsKey(action)) {
220                     summary.put(action, new AtomicInteger());
221                 }
222                 summary.get(action).incrementAndGet();
223 
224                 final String fileName = file.getName();
225                 out.append("File:" + fileName);
226 
227                 // files in this log are known to be from one subtree
228                 assertTrue("Unexpected file name: " + fileName, fileName.startsWith("/maven/scm/trunk"));
229 
230                 // files in this log are known not to contain space
231                 assertEquals("Unexpected space found in filename: " + fileName, -1, fileName.indexOf(" "));
232 
233                 if (file.getOriginalName() != null) {
234                     origFileCounter++;
235                 }
236             }
237 
238             out.append("==============================");
239         }
240 
241         assertEquals("Unexpected number of file copy records", 1, origFileCounter);
242 
243         assertEquals(
244                 "Action summary differs from expectations",
245                 "{modified=626, deleted=56, added=310, copied=1}",
246                 summary.toString());
247 
248         if (logger.isDebugEnabled()) {
249             logger.debug(out.toString());
250         }
251     }
252 }