Add JaCoCo coverage and improve tests to 98.7%
Add JaCoCo plugin for coverage reporting. Add additional tests for null/edge cases in TelnetSession, TelnetServer, and WebgitApplication.main to maximize coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
plugins {
|
||||
java
|
||||
jacoco
|
||||
id("org.springframework.boot") version "4.0.3"
|
||||
id("io.spring.dependency-management") version "1.1.7"
|
||||
}
|
||||
@@ -41,4 +42,12 @@ dependencies {
|
||||
|
||||
tasks.withType<Test> {
|
||||
useJUnitPlatform()
|
||||
finalizedBy(tasks.jacocoTestReport)
|
||||
}
|
||||
|
||||
tasks.jacocoTestReport {
|
||||
dependsOn(tasks.test)
|
||||
reports {
|
||||
csv.required = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,4 +10,9 @@ class WebgitApplicationTests {
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void mainMethodRuns() {
|
||||
WebgitApplication.main(new String[]{});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,17 +22,15 @@ class TelnetServerTest
|
||||
WebgitProperties props = new WebgitProperties();
|
||||
props.setWorktreePath(tempDir.resolve("worktrees"));
|
||||
props.setGitDirPath(tempDir.resolve("gitdirs"));
|
||||
props.setTelnetPort(0); // use any free port
|
||||
|
||||
GitService gitService = new GitService(props);
|
||||
|
||||
// We'll test with a real server socket but use port 0 for a random free port
|
||||
// Since the TelnetServer uses PostConstruct, we'll test the component manually
|
||||
var serverSocket = new java.net.ServerSocket(0);
|
||||
int port = serverSocket.getLocalPort();
|
||||
serverSocket.close();
|
||||
// First find a free port
|
||||
var tmpSocket = new java.net.ServerSocket(0);
|
||||
int port = tmpSocket.getLocalPort();
|
||||
tmpSocket.close();
|
||||
|
||||
props.setTelnetPort(port);
|
||||
GitService gitService = new GitService(props);
|
||||
|
||||
TelnetServer server = new TelnetServer(gitService, props);
|
||||
server.start();
|
||||
|
||||
@@ -40,14 +38,11 @@ class TelnetServerTest
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
|
||||
PrintWriter out = new PrintWriter(socket.getOutputStream(), true))
|
||||
{
|
||||
// Read the welcome message
|
||||
String line = in.readLine();
|
||||
assertTrue(line.contains("Welcome to WebGit"));
|
||||
|
||||
// Send quit
|
||||
out.println("q");
|
||||
|
||||
// Read until we see Goodbye
|
||||
String response = "";
|
||||
String l;
|
||||
while ((l = in.readLine()) != null)
|
||||
@@ -61,4 +56,49 @@ class TelnetServerTest
|
||||
server.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void serverUsesDefaultPortWhenNull() throws Exception
|
||||
{
|
||||
WebgitProperties props = new WebgitProperties();
|
||||
props.setWorktreePath(tempDir.resolve("worktrees"));
|
||||
props.setGitDirPath(tempDir.resolve("gitdirs"));
|
||||
props.setTelnetPort(null);
|
||||
|
||||
GitService gitService = new GitService(props);
|
||||
TelnetServer server = new TelnetServer(gitService, props);
|
||||
|
||||
// The default port is 2323; this tests the null branch
|
||||
// We can't easily test this without port conflicts, so just verify
|
||||
// it starts and stops without error (port 2323 may be in use)
|
||||
try
|
||||
{
|
||||
server.start();
|
||||
server.stop();
|
||||
}
|
||||
catch (java.net.BindException e)
|
||||
{
|
||||
// Port 2323 already in use is acceptable for this test
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void serverStopIsIdempotent() throws Exception
|
||||
{
|
||||
WebgitProperties props = new WebgitProperties();
|
||||
props.setWorktreePath(tempDir.resolve("worktrees"));
|
||||
props.setGitDirPath(tempDir.resolve("gitdirs"));
|
||||
|
||||
var tmpSocket = new java.net.ServerSocket(0);
|
||||
int port = tmpSocket.getLocalPort();
|
||||
tmpSocket.close();
|
||||
props.setTelnetPort(port);
|
||||
|
||||
GitService gitService = new GitService(props);
|
||||
TelnetServer server = new TelnetServer(gitService, props);
|
||||
server.start();
|
||||
server.stop();
|
||||
// Second stop should not throw
|
||||
server.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,4 +349,90 @@ class TelnetSessionTest
|
||||
String output = runSession("3\n1\n6\nabc\nb\nq\n");
|
||||
verify(gitService, never()).stageFiles(anyString(), anyList());
|
||||
}
|
||||
|
||||
@Test
|
||||
void stageOutOfRangeNumbers() throws IOException, GitAPIException
|
||||
{
|
||||
when(gitService.listRepositories()).thenReturn(List.of("myrepo"));
|
||||
when(gitService.getCurrentBranch("myrepo")).thenReturn("main");
|
||||
when(gitService.getModifiedFiles("myrepo")).thenReturn(List.of("a.txt"));
|
||||
// Index 99 is out of range
|
||||
String output = runSession("3\n1\n6\n99\nb\nq\n");
|
||||
verify(gitService, never()).stageFiles(anyString(), anyList());
|
||||
}
|
||||
|
||||
@Test
|
||||
void stageNegativeIndex() throws IOException, GitAPIException
|
||||
{
|
||||
when(gitService.listRepositories()).thenReturn(List.of("myrepo"));
|
||||
when(gitService.getCurrentBranch("myrepo")).thenReturn("main");
|
||||
when(gitService.getModifiedFiles("myrepo")).thenReturn(List.of("a.txt"));
|
||||
// Index 0 maps to -1 which is < 0
|
||||
String output = runSession("3\n1\n6\n0\nb\nq\n");
|
||||
verify(gitService, never()).stageFiles(anyString(), anyList());
|
||||
}
|
||||
|
||||
@Test
|
||||
void cloneNullUrl()
|
||||
{
|
||||
// Input ends after "2\n" prompt for URL — readLine returns null
|
||||
String output = runSession("2\n");
|
||||
assertTrue(output.contains("Goodbye!"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void checkoutBranchNull() throws IOException, GitAPIException
|
||||
{
|
||||
when(gitService.listRepositories()).thenReturn(List.of("myrepo"));
|
||||
when(gitService.getCurrentBranch("myrepo")).thenReturn("main");
|
||||
// Enter repo menu, choose checkout(2), then input stream ends
|
||||
String output = runSession("3\n1\n2\n");
|
||||
verify(gitService, never()).checkoutBranch(anyString(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void createBranchNull() throws IOException, GitAPIException
|
||||
{
|
||||
when(gitService.listRepositories()).thenReturn(List.of("myrepo"));
|
||||
when(gitService.getCurrentBranch("myrepo")).thenReturn("main");
|
||||
String output = runSession("3\n1\n3\n");
|
||||
verify(gitService, never()).createAndCheckoutBranch(anyString(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void commitNull() throws IOException, GitAPIException
|
||||
{
|
||||
when(gitService.listRepositories()).thenReturn(List.of("myrepo"));
|
||||
when(gitService.getCurrentBranch("myrepo")).thenReturn("main");
|
||||
String output = runSession("3\n1\n7\n");
|
||||
verify(gitService, never()).commit(anyString(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void stageFilesNull() throws IOException, GitAPIException
|
||||
{
|
||||
when(gitService.listRepositories()).thenReturn(List.of("myrepo"));
|
||||
when(gitService.getCurrentBranch("myrepo")).thenReturn("main");
|
||||
when(gitService.getModifiedFiles("myrepo")).thenReturn(List.of("a.txt"));
|
||||
// Input ends at the "enter numbers" prompt
|
||||
String output = runSession("3\n1\n6\n");
|
||||
verify(gitService, never()).stageFiles(anyString(), anyList());
|
||||
}
|
||||
|
||||
@Test
|
||||
void openRepositoryNull() throws IOException
|
||||
{
|
||||
when(gitService.listRepositories()).thenReturn(List.of("myrepo"));
|
||||
// Input ends at the "enter number" prompt
|
||||
String output = runSession("3\n");
|
||||
assertTrue(output.contains("Goodbye!"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void cloneNullName()
|
||||
{
|
||||
// URL is provided but name input stream ends
|
||||
String output = runSession("2\nhttps://example.com/repo.git\n");
|
||||
assertTrue(output.contains("Goodbye!"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user