Skip to content

Commit

Permalink
SLLS-268 refactoring for better coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
sophio-japharidze-sonarsource committed Oct 7, 2024
1 parent c28b19b commit dd5eb5c
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,6 @@ public String matchSonarProjectBranch(String folderUri, String mainBranchName, S

public boolean matchProjectBranch(String folderUri, String branchNameToMatch, SonarLintCancelChecker cancelChecker) {
if (cancelChecker.isCanceled()) return false;
var repo = GitUtils.getRepositoryForDir(Paths.get(URI.create(folderUri)), logOutput);
if (repo == null) {
return false;
}
var currentBranch = GitUtils.getCurrentBranch(repo);
return branchNameToMatch.equals(currentBranch);
return GitUtils.isCurrentBranch(folderUri, branchNameToMatch, logOutput);
}
}
13 changes: 10 additions & 3 deletions src/main/java/org/sonarsource/sonarlint/ls/util/GitUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
package org.sonarsource.sonarlint.ls.util;

import java.io.IOException;
import java.net.URI;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
Expand Down Expand Up @@ -109,11 +111,16 @@ public static String electBestMatchingServerBranchForCurrentHead(Repository repo
}
}

public static String getCurrentBranch(Repository repo) {
public static boolean isCurrentBranch(String folderUri, String expectedBranch, LanguageClientLogger logOutput) {
var repo = GitUtils.getRepositoryForDir(Paths.get(URI.create(folderUri)), logOutput);
if (repo == null) {
return false;
}
try {
return repo.getBranch();
var branch = repo.getBranch();
return branch != null && branch.equals(expectedBranch);
} catch (IOException e) {
return null;
return false;
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* SonarLint Language Server
* Copyright (C) 2009-2024 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonarsource.sonarlint.ls.folders;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.CancellationException;
import org.eclipse.lsp4j.jsonrpc.CancelChecker;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.sonarsource.sonarlint.core.rpc.client.SonarLintCancelChecker;
import org.sonarsource.sonarlint.ls.backend.BackendServiceFacade;
import org.sonarsource.sonarlint.ls.log.LanguageClientLogger;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.mockito.Mockito.mock;
import static testutils.JavaUnzip.javaUnzip;

class WorkspaceFolderBranchManagerTest {
private static WorkspaceFolderBranchManager underTest;

@BeforeAll
static void setUp() {
var fakeClientLogger = mock(LanguageClientLogger.class);
var backendServiceFacade = mock(BackendServiceFacade.class);
underTest = new WorkspaceFolderBranchManager(backendServiceFacade, fakeClientLogger);
}

@Test
void matchProjectBranch_shouldReturnTrueWhenCurrentBranch(@TempDir File projectDir) {
javaUnzip("closest-branch.zip", projectDir);
Path path = Paths.get(projectDir.getPath(), "closest-branch");

var cancelChecker = new SonarLintCancelChecker(DummyCancelChecker::new);

var matchProjectBranch = underTest.matchProjectBranch(path.toUri().toString(), "current_branch", cancelChecker);
assertThat(matchProjectBranch).isTrue();
}

@Test
void matchProjectBranch_shouldReturnFalseWhenCanceled(@TempDir File projectDir) {
javaUnzip("closest-branch.zip", projectDir);
Path path = Paths.get(projectDir.getPath(), "closest-branch");

var cancelChecker = new SonarLintCancelChecker(new CanceledDummyCancelChecker());

var matchProjectBranch = underTest.matchProjectBranch(path.toUri().toString(), "current_branch", cancelChecker);
assertThat(matchProjectBranch).isFalse();
}

static class DummyCancelChecker implements CancelChecker {
private final boolean canceled = false;

@Override
public void checkCanceled() {
if (canceled) {
throw new RuntimeException("Canceled");
}
}

@Override
public boolean isCanceled() {
return canceled;
}
}

static class CanceledDummyCancelChecker implements CancelChecker {
@Override
public void checkCanceled() {
throw new CancellationException("Canceled");
}

@Override
public boolean isCanceled() {
return true;
}
}
}
84 changes: 26 additions & 58 deletions src/test/java/org/sonarsource/sonarlint/ls/util/GitUtilsTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,39 +21,35 @@

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Enumeration;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.eclipse.jgit.lib.RefDatabase;
import org.eclipse.jgit.lib.Repository;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.sonarsource.sonarlint.ls.log.LanguageClientLogger;

import static java.lang.String.format;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static testutils.JavaUnzip.javaUnzip;

class GitUtilsTests {

private final LanguageClientLogger fakeClientLogger = mock(LanguageClientLogger.class);

@Test
void noGitRepoShouldBeNull(@TempDir File projectDir) throws IOException {
void noGitRepoShouldBeNull(@TempDir File projectDir) {
javaUnzip("no-git-repo.zip", projectDir);
Path path = Paths.get(projectDir.getPath(), "no-git-repo");
Repository repo = GitUtils.getRepositoryForDir(path, fakeClientLogger);
assertThat(repo).isNull();
}

@Test
void gitRepoShouldBeNotNull(@TempDir File projectDir) throws IOException {
void gitRepoShouldBeNotNull(@TempDir File projectDir) {
javaUnzip("dummy-git.zip", projectDir);
Path path = Paths.get(projectDir.getPath(), "dummy-git");
try (Repository repo = GitUtils.getRepositoryForDir(path, fakeClientLogger)) {
Expand All @@ -65,7 +61,7 @@ void gitRepoShouldBeNotNull(@TempDir File projectDir) throws IOException {
}

@Test
void shouldElectAnalyzedBranch(@TempDir File projectDir) throws IOException {
void shouldElectAnalyzedBranch(@TempDir File projectDir) {
javaUnzip("analyzed-branch.zip", projectDir);
Path path = Paths.get(projectDir.getPath(), "analyzed-branch");
try (Repository repo = GitUtils.getRepositoryForDir(path, fakeClientLogger)) {
Expand All @@ -77,7 +73,7 @@ void shouldElectAnalyzedBranch(@TempDir File projectDir) throws IOException {
}

@Test
void shouldReturnNullIfNonePresentInLocalGit(@TempDir File projectDir) throws IOException {
void shouldReturnNullIfNonePresentInLocalGit(@TempDir File projectDir) {
javaUnzip("analyzed-branch.zip", projectDir);
Path path = Paths.get(projectDir.getPath(), "analyzed-branch");
try (Repository repo = GitUtils.getRepositoryForDir(path, fakeClientLogger)) {
Expand All @@ -89,7 +85,7 @@ void shouldReturnNullIfNonePresentInLocalGit(@TempDir File projectDir) throws IO
}

@Test
void shouldElectClosestBranch(@TempDir File projectDir) throws IOException {
void shouldElectClosestBranch(@TempDir File projectDir) {
javaUnzip("closest-branch.zip", projectDir);
Path path = Paths.get(projectDir.getPath(), "closest-branch");

Expand All @@ -103,7 +99,7 @@ void shouldElectClosestBranch(@TempDir File projectDir) throws IOException {
}

@Test
void shouldElectClosestBranch_even_if_no_main_branch(@TempDir File projectDir) throws IOException {
void shouldElectClosestBranch_even_if_no_main_branch(@TempDir File projectDir) {
javaUnzip("closest-branch.zip", projectDir);
Path path = Paths.get(projectDir.getPath(), "closest-branch");

Expand All @@ -117,7 +113,7 @@ void shouldElectClosestBranch_even_if_no_main_branch(@TempDir File projectDir) t
}

@Test
void shouldElectMainBranchForNonAnalyzedChildBranch(@TempDir File projectDir) throws IOException {
void shouldElectMainBranchForNonAnalyzedChildBranch(@TempDir File projectDir) {
javaUnzip("child-from-non-analyzed.zip", projectDir);
Path path = Paths.get(projectDir.getPath(), "child-from-non-analyzed");
try (Repository repo = GitUtils.getRepositoryForDir(path, fakeClientLogger)) {
Expand All @@ -142,28 +138,34 @@ void shouldReturnNullOnException() throws IOException {
}

@Test
void getCurrentBranch_shouldReturnNullOnException() throws IOException {
Repository repo = mock(Repository.class);
when(repo.getBranch()).thenThrow(new IOException());

String branch = GitUtils.getCurrentBranch(repo);
void isCurrentBranch_shouldReturnTrueWhenCurrentBranch(@TempDir File projectDir) {
javaUnzip("closest-branch.zip", projectDir);
Path path = Paths.get(projectDir.getPath(), "closest-branch");

assertThat(branch).isNull();
boolean isCurrentBranch = GitUtils.isCurrentBranch(path.toUri().toString(), "current_branch", fakeClientLogger);
assertThat(isCurrentBranch).isTrue();
}

@Test
void shouldReturnCurrentBranch(@TempDir File projectDir) throws IOException {
void isCurrentBranch_shouldReturnFalseWhenNotCurrentBranch(@TempDir File projectDir) {
javaUnzip("closest-branch.zip", projectDir);
Path path = Paths.get(projectDir.getPath(), "closest-branch");

try (Repository repo = GitUtils.getRepositoryForDir(path, fakeClientLogger)) {
String currentBranch = GitUtils.getCurrentBranch(repo);
assertThat(currentBranch).isEqualTo("current_branch");
}
boolean isCurrentBranch = GitUtils.isCurrentBranch(path.toUri().toString(), "not_current_branch", fakeClientLogger);
assertThat(isCurrentBranch).isFalse();
}

@Test
void isCurrentBranch_shouldReturnFalseWhenNoRepo(@TempDir File projectDir) {
javaUnzip("closest-branch.zip", projectDir);
Path path = Paths.get(projectDir.getPath(), "non-existent");

boolean isCurrentBranch = GitUtils.isCurrentBranch(path.toUri().toString(), "not_current_branch", fakeClientLogger);
assertThat(isCurrentBranch).isFalse();
}

@Test
void shouldFavorCurrentBranchIfMultipleCandidates(@TempDir File projectDir) throws IOException {
void shouldFavorCurrentBranchIfMultipleCandidates(@TempDir File projectDir) {
// Both main and same-as-master branches are pointing to HEAD, but same-as-master is the currently checked out branch
javaUnzip("two-branches-for-head.zip", projectDir);
Path path = Paths.get(projectDir.getPath(), "two-branches-for-head");
Expand All @@ -176,38 +178,4 @@ void shouldFavorCurrentBranchIfMultipleCandidates(@TempDir File projectDir) thro
}
}

public void javaUnzip(String zipFileName, File toDir) throws IOException {
File testRepos = new File("src/test/resources/test-repos");
File zipFile = new File(testRepos, zipFileName);
javaUnzip(zipFile, toDir);
}

private static void javaUnzip(File zip, File toDir) {
try {
try (ZipFile zipFile = new ZipFile(zip)) {
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
File to = new File(toDir, entry.getName());
if (entry.isDirectory()) {
forceMkdir(to);
} else {
File parent = to.getParentFile();
forceMkdir(parent);

Files.copy(zipFile.getInputStream(entry), to.toPath());
}
}
}
} catch (Exception e) {
throw new IllegalStateException(format("Fail to unzip %s to %s", zip, toDir), e);
}
}

private static void forceMkdir(final File directory) throws IOException {
if ((directory != null) && (!directory.mkdirs() && !directory.isDirectory())) {
throw new IOException("Cannot create directory '" + directory + "'.");
}
}

}
65 changes: 65 additions & 0 deletions src/test/java/testutils/JavaUnzip.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* SonarLint Language Server
* Copyright (C) 2009-2024 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package testutils;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import static java.lang.String.format;

public class JavaUnzip {
public static void javaUnzip(String zipFileName, File toDir) {
File testRepos = new File("src/test/resources/test-repos");
File zipFile = new File(testRepos, zipFileName);
javaUnzip(zipFile, toDir);
}

private static void javaUnzip(File zip, File toDir) {
try {
try (ZipFile zipFile = new ZipFile(zip)) {
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
File to = new File(toDir, entry.getName());
if (entry.isDirectory()) {
forceMkdir(to);
} else {
File parent = to.getParentFile();
forceMkdir(parent);

Files.copy(zipFile.getInputStream(entry), to.toPath());
}
}
}
} catch (Exception e) {
throw new IllegalStateException(format("Fail to unzip %s to %s", zip, toDir), e);
}
}

private static void forceMkdir(final File directory) throws IOException {
if ((directory != null) && (!directory.mkdirs() && !directory.isDirectory())) {
throw new IOException("Cannot create directory '" + directory + "'.");
}
}
}

0 comments on commit dd5eb5c

Please sign in to comment.