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.git.gitexe.command.blame;
20  
21  import java.io.BufferedReader;
22  import java.io.File;
23  import java.io.FileReader;
24  import java.io.IOException;
25  import java.text.SimpleDateFormat;
26  import java.util.Iterator;
27  import java.util.List;
28  import java.util.TimeZone;
29  
30  import org.apache.maven.scm.ScmTestCase;
31  import org.apache.maven.scm.command.blame.BlameLine;
32  import org.apache.maven.scm.util.ConsumerUtils;
33  import org.junit.Assert;
34  import org.junit.Test;
35  
36  import static org.junit.Assert.fail;
37  
38  /**
39   * Test the {@link GitBlameConsumer} in various different situations.
40   * Depending on the underlying operating system we might get
41   * slightly different output from a <pre>git blame</pre> commandline invocation.
42   */
43  public class GitBlameConsumerTest extends ScmTestCase {
44      @Test
45      public void testConsumerEasy() throws Exception {
46          GitBlameConsumer consumer = consumeFile("/src/test/resources/git/blame/git-blame-3.out");
47  
48          Assert.assertEquals(36, consumer.getLines().size());
49  
50          BlameLine blameLine = consumer.getLines().get(11);
51          Assert.assertEquals("e670863b2b03e158c59f34af1fee20f91b2bd852", blameLine.getRevision());
52          Assert.assertEquals("Mark Struberg", blameLine.getAuthor());
53          Assert.assertNotNull(blameLine.getDate());
54      }
55  
56      @Test
57      public void testConsumer() throws Exception {
58          GitBlameConsumer consumer = consumeFile("/src/test/resources/git/blame/git-blame.out");
59  
60          Assert.assertEquals(187, consumer.getLines().size());
61  
62          BlameLine blameLine = consumer.getLines().get(11);
63          Assert.assertEquals("e670863b2b03e158c59f34af1fee20f91b2bd852", blameLine.getRevision());
64          Assert.assertEquals("Mark Struberg", blameLine.getAuthor());
65          Assert.assertNotNull(blameLine.getDate());
66      }
67  
68      /**
69       * Test what happens if a git-blame command got invoked on a
70       * file which has no content.
71       */
72      @Test
73      public void testConsumerEmptyFile() throws Exception {
74          GitBlameConsumer consumer = consumeFile("/src/test/resources/git/blame/git-blame-empty.out");
75  
76          Assert.assertEquals(0, consumer.getLines().size());
77      }
78  
79      /**
80       * Test what happens if a git-blame command got invoked on a
81       * file which didn't got added to the git repo yet.
82       */
83      @Test
84      public void testConsumerOnNewFile() throws Exception {
85          GitBlameConsumer consumer = consumeFile("/src/test/resources/git/blame/git-blame-new-file.out");
86  
87          Assert.assertEquals(3, consumer.getLines().size());
88          BlameLine blameLine = consumer.getLines().get(0);
89          Assert.assertNotNull(blameLine);
90          Assert.assertEquals("0000000000000000000000000000000000000000", blameLine.getRevision());
91          Assert.assertEquals("Not Committed Yet", blameLine.getAuthor());
92      }
93  
94      /**
95       * Test a case where the committer and author are different persons
96       */
97      @Test
98      public void testConsumerWithDifferentAuthor() throws Exception {
99          GitBlameConsumer consumer = consumeFile("/src/test/resources/git/blame/git-blame-different-author.out");
100 
101         Assert.assertEquals(93, consumer.getLines().size());
102         BlameLine blameLine = consumer.getLines().get(0);
103         Assert.assertNotNull(blameLine);
104         Assert.assertEquals("39574726d20f62023d39311e6032c7ab0a9d3cdb", blameLine.getRevision());
105         Assert.assertEquals("Mark Struberg", blameLine.getAuthor());
106         Assert.assertEquals("Mark Struberg", blameLine.getCommitter());
107 
108         blameLine = consumer.getLines().get(12);
109         Assert.assertNotNull(blameLine);
110         Assert.assertEquals("41e5bc05953781a5702f597a1a36c55371b517d3", blameLine.getRevision());
111         Assert.assertEquals("Another User", blameLine.getAuthor());
112         Assert.assertEquals("Mark Struberg", blameLine.getCommitter());
113     }
114 
115     /**
116      * This unit test compares the output of our new parsing with a
117      * simplified git blame output.
118      */
119     @Test
120     public void testConsumerCompareWithOriginal() throws Exception {
121         GitBlameConsumer consumer = consumeFile("/src/test/resources/git/blame/git-blame-2.out");
122         Assert.assertNotNull(consumer);
123 
124         List<BlameLine> consumerLines = consumer.getLines();
125         Iterator<BlameLine> consumerLineIt = consumerLines.iterator();
126 
127         File compareWithFile = getTestFile("/src/test/resources/git/blame/git-blame-2.orig");
128         Assert.assertNotNull(compareWithFile);
129 
130         try (BufferedReader r = new BufferedReader(new FileReader(compareWithFile))) {
131             String line;
132             SimpleDateFormat blameDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
133             blameDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
134 
135             int lineNr = 0;
136 
137             while ((line = r.readLine()) != null && line.trim().length() > 0) {
138                 if (!consumerLineIt.hasNext()) {
139                     fail("GitBlameConsumer lines do not match the original output!");
140                 }
141                 BlameLine blameLine = consumerLineIt.next();
142                 Assert.assertNotNull(blameLine);
143 
144                 String[] parts = line.split("\t");
145                 Assert.assertEquals(3, parts.length);
146 
147                 Assert.assertEquals("error in line " + lineNr, parts[0], blameLine.getRevision());
148                 Assert.assertEquals("error in line " + lineNr, parts[1], blameLine.getAuthor());
149                 Assert.assertEquals("error in line " + lineNr, parts[2], blameDateFormat.format(blameLine.getDate()));
150 
151                 lineNr++;
152             }
153         }
154 
155         if (consumerLineIt.hasNext()) {
156             fail("GitBlameConsumer found more lines than in the original output!");
157         }
158     }
159 
160     /**
161      * Consume all lines in the given file with a fresh {@link GitBlameConsumer}.
162      *
163      * @param fileName
164      * @return the resulting {@link GitBlameConsumer}
165      * @throws IOException
166      */
167     private GitBlameConsumer consumeFile(String fileName) throws IOException {
168         GitBlameConsumer consumer = new GitBlameConsumer();
169 
170         File f = getTestFile(fileName);
171 
172         ConsumerUtils.consumeFile(f, consumer);
173 
174         return consumer;
175     }
176 }