diff --git a/sonar-scm-mercurial-plugin/src/main/java/org/sonar/plugins/scm/mercurial/MercurialBlameCommand.java b/sonar-scm-mercurial-plugin/src/main/java/org/sonar/plugins/scm/mercurial/MercurialBlameCommand.java index e2d051d..921fce6 100644 --- a/sonar-scm-mercurial-plugin/src/main/java/org/sonar/plugins/scm/mercurial/MercurialBlameCommand.java +++ b/sonar-scm-mercurial-plugin/src/main/java/org/sonar/plugins/scm/mercurial/MercurialBlameCommand.java @@ -99,7 +99,7 @@ private void blame(FileSystem fs, InputFile inputFile, BlameOutput output) { LOG.debug("The mercurial blame command [" + cl.toString() + "] failed: " + stderr.getOutput()); } List lines = consumer.getLines(); - if (lines.size() == inputFile.lines() - 1) { + if (!lines.isEmpty() && lines.size() == inputFile.lines() - 1) { // SONARPLUGINS-3097 Mercurial do not report blame on last empty line lines.add(lines.get(lines.size() - 1)); } diff --git a/sonar-scm-mercurial-plugin/src/test/java/org/sonar/plugins/scm/mercurial/MercurialBlameCommandTest.java b/sonar-scm-mercurial-plugin/src/test/java/org/sonar/plugins/scm/mercurial/MercurialBlameCommandTest.java index ba69e43..6c124b0 100644 --- a/sonar-scm-mercurial-plugin/src/test/java/org/sonar/plugins/scm/mercurial/MercurialBlameCommandTest.java +++ b/sonar-scm-mercurial-plugin/src/test/java/org/sonar/plugins/scm/mercurial/MercurialBlameCommandTest.java @@ -22,7 +22,6 @@ import java.io.File; import java.io.IOException; import java.util.Arrays; -import org.apache.commons.io.FileUtils; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -40,6 +39,7 @@ import org.sonar.api.utils.command.CommandExecutor; import org.sonar.api.utils.command.StreamConsumer; +import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyLong; @@ -68,9 +68,7 @@ public void prepare() throws IOException { } @Test - public void testParsingOfOutput() throws IOException { - File source = new File(baseDir, "src/foo.xoo"); - FileUtils.write(source, "sample content"); + public void testParsingOfOutput() { InputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo") .setLines(3) .setModuleBaseDir(baseDir.toPath()) @@ -103,9 +101,7 @@ public void testParsingOfOutput() throws IOException { } @Test - public void testAddMissingLastLine() throws IOException { - File source = new File(baseDir, "src/foo.xoo"); - FileUtils.write(source, "sample content"); + public void testAddMissingLastLine() { InputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo") .setLines(4) .setModuleBaseDir(baseDir.toPath()) @@ -127,16 +123,36 @@ public void testAddMissingLastLine() throws IOException { when(input.filesToBlame()).thenReturn(singletonList(inputFile)); new MercurialBlameCommand(commandExecutor, new MapSettings()).blame(input, result); verify(result).blameResult(inputFile, - Arrays.asList(new BlameLine().date(DateUtils.parseDateTime("2014-11-04T11:01:10+0100")).revision("d45dafac0d9a").author("julien.henry@sonarsource.com"), + Arrays.asList( + new BlameLine().date(DateUtils.parseDateTime("2014-11-04T11:01:10+0100")).revision("d45dafac0d9a").author("julien.henry@sonarsource.com"), new BlameLine().date(DateUtils.parseDateTime("2014-11-04T11:01:10+0100")).revision("d45dafac0d9a").author("julien.henry@sonarsource.com"), new BlameLine().date(DateUtils.parseDateTime("2014-11-04T11:01:10+0100")).revision("d45dafac0d9a").author("julien.henry@sonarsource.com"), new BlameLine().date(DateUtils.parseDateTime("2014-11-04T11:01:10+0100")).revision("d45dafac0d9a").author("julien.henry@sonarsource.com"))); } @Test - public void shouldNotFailOnFileUncommitted() throws IOException { - File source = new File(baseDir, "src/foo.xoo"); - FileUtils.write(source, "sample content"); + public void empty_file_has_always_an_empty_last_line() { + InputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo") + .setLines(1) + .setModuleBaseDir(baseDir.toPath()) + .build(); + fs.add(inputFile); + + BlameOutput result = mock(BlameOutput.class); + CommandExecutor commandExecutor = mock(CommandExecutor.class); + + when(commandExecutor.execute(any(), any(), any(), anyLong())).thenAnswer((Answer) invocation -> { + // Hg doesn't blame last empty line + return 0; + }); + + when(input.filesToBlame()).thenReturn(singletonList(inputFile)); + new MercurialBlameCommand(commandExecutor, new MapSettings()).blame(input, result); + verify(result).blameResult(inputFile, emptyList()); + } + + @Test + public void shouldNotFailOnFileUncommitted() { InputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo") .setModuleBaseDir(baseDir.toPath()) .build();