Skip to content

Commit f6a63da

Browse files
Copilotedburns
andauthored
Add unit tests for ToolSet, CopilotClientMode, and PermissionRequestResult
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
1 parent 3705d64 commit f6a63da

3 files changed

Lines changed: 236 additions & 0 deletions

File tree

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
*--------------------------------------------------------------------------------------------*/
4+
5+
package com.github.copilot;
6+
7+
import static org.junit.jupiter.api.Assertions.*;
8+
9+
import org.junit.jupiter.api.Test;
10+
11+
import com.github.copilot.rpc.CopilotClientMode;
12+
import com.github.copilot.rpc.CopilotClientOptions;
13+
14+
/**
15+
* Tests for {@link CopilotClientMode} and Empty mode validation.
16+
*/
17+
public class CopilotClientModeTest {
18+
19+
@Test
20+
void testDefaultModeIsCopilotCli() {
21+
var opts = new CopilotClientOptions();
22+
assertEquals(CopilotClientMode.COPILOT_CLI, opts.getMode());
23+
}
24+
25+
@Test
26+
void testSetModeEmpty() {
27+
var opts = new CopilotClientOptions();
28+
opts.setMode(CopilotClientMode.EMPTY);
29+
assertEquals(CopilotClientMode.EMPTY, opts.getMode());
30+
}
31+
32+
@Test
33+
void testEmptyModeRequiresCopilotHome() {
34+
var opts = new CopilotClientOptions().setMode(CopilotClientMode.EMPTY).setAutoStart(false);
35+
// Empty mode without copilotHome should throw
36+
var ex = assertThrows(IllegalArgumentException.class, () -> new CopilotClient(opts));
37+
assertTrue(ex.getMessage().contains("Empty mode"));
38+
}
39+
40+
@Test
41+
void testEmptyModeWithCopilotHome() {
42+
var opts = new CopilotClientOptions().setMode(CopilotClientMode.EMPTY).setCopilotHome("/tmp/copilot-home")
43+
.setAutoStart(false);
44+
// Should not throw - copilotHome is set
45+
var client = new CopilotClient(opts);
46+
assertEquals(ConnectionState.DISCONNECTED, client.getState());
47+
client.close();
48+
}
49+
50+
@Test
51+
void testCopilotClientModeEnumValues() {
52+
assertEquals(2, CopilotClientMode.values().length);
53+
assertEquals(CopilotClientMode.EMPTY, CopilotClientMode.valueOf("EMPTY"));
54+
assertEquals(CopilotClientMode.COPILOT_CLI, CopilotClientMode.valueOf("COPILOT_CLI"));
55+
}
56+
57+
@Test
58+
void testEnumSerializationNames() {
59+
// CopilotClientMode is a plain enum; verify the values exist
60+
assertNotNull(CopilotClientMode.EMPTY);
61+
assertNotNull(CopilotClientMode.COPILOT_CLI);
62+
}
63+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
*--------------------------------------------------------------------------------------------*/
4+
5+
package com.github.copilot;
6+
7+
import static org.junit.jupiter.api.Assertions.*;
8+
9+
import org.junit.jupiter.api.Test;
10+
11+
import com.github.copilot.rpc.PermissionRequestResult;
12+
import com.fasterxml.jackson.databind.ObjectMapper;
13+
import com.fasterxml.jackson.databind.json.JsonMapper;
14+
import com.fasterxml.jackson.annotation.JsonInclude;
15+
16+
/**
17+
* Tests for {@link PermissionRequestResult} factory methods and feedback field.
18+
*/
19+
public class PermissionRequestResultTest {
20+
21+
private static final ObjectMapper MAPPER = JsonMapper.builder().serializationInclusion(JsonInclude.Include.NON_NULL)
22+
.build();
23+
24+
@Test
25+
void testApproveOnce() {
26+
var result = PermissionRequestResult.approveOnce();
27+
assertEquals("approve-once", result.getKind());
28+
assertNull(result.getFeedback());
29+
}
30+
31+
@Test
32+
void testRejectWithFeedback() {
33+
var result = PermissionRequestResult.reject("Not allowed");
34+
assertEquals("reject", result.getKind());
35+
assertEquals("Not allowed", result.getFeedback());
36+
}
37+
38+
@Test
39+
void testRejectWithoutFeedback() {
40+
var result = PermissionRequestResult.reject(null);
41+
assertEquals("reject", result.getKind());
42+
assertNull(result.getFeedback());
43+
}
44+
45+
@Test
46+
void testUserNotAvailable() {
47+
var result = PermissionRequestResult.userNotAvailable();
48+
assertEquals("user-not-available", result.getKind());
49+
assertNull(result.getFeedback());
50+
}
51+
52+
@Test
53+
void testNoResult() {
54+
var result = PermissionRequestResult.noResult();
55+
assertEquals("no-result", result.getKind());
56+
assertNull(result.getFeedback());
57+
}
58+
59+
@Test
60+
void testFeedbackSerialized() throws Exception {
61+
var result = PermissionRequestResult.reject("Unsafe operation");
62+
var json = MAPPER.writeValueAsString(result);
63+
assertTrue(json.contains("\"feedback\":\"Unsafe operation\""));
64+
assertTrue(json.contains("\"kind\":\"reject\""));
65+
}
66+
67+
@Test
68+
void testFeedbackNotSerializedWhenNull() throws Exception {
69+
var result = PermissionRequestResult.approveOnce();
70+
var json = MAPPER.writeValueAsString(result);
71+
assertFalse(json.contains("feedback"));
72+
}
73+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
*--------------------------------------------------------------------------------------------*/
4+
5+
package com.github.copilot;
6+
7+
import static org.junit.jupiter.api.Assertions.*;
8+
9+
import java.util.Collection;
10+
import java.util.List;
11+
12+
import org.junit.jupiter.api.Test;
13+
14+
import com.github.copilot.rpc.BuiltInTools;
15+
import com.github.copilot.rpc.ToolSet;
16+
17+
/**
18+
* Tests for {@link ToolSet} and {@link BuiltInTools}.
19+
*/
20+
public class ToolSetTest {
21+
22+
@Test
23+
void testAddBuiltIn() {
24+
var ts = new ToolSet().addBuiltIn("bash");
25+
assertEquals(1, ts.size());
26+
assertEquals("builtin:bash", ts.get(0));
27+
}
28+
29+
@Test
30+
void testAddBuiltInWildcard() {
31+
var ts = new ToolSet().addBuiltIn("*");
32+
assertEquals("builtin:*", ts.get(0));
33+
}
34+
35+
@Test
36+
void testAddCustom() {
37+
var ts = new ToolSet().addCustom("my_tool");
38+
assertEquals("custom:my_tool", ts.get(0));
39+
}
40+
41+
@Test
42+
void testAddMcp() {
43+
var ts = new ToolSet().addMcp("github-list_issues");
44+
assertEquals("mcp:github-list_issues", ts.get(0));
45+
}
46+
47+
@Test
48+
void testAddMcpWildcard() {
49+
var ts = new ToolSet().addMcp("*");
50+
assertEquals("mcp:*", ts.get(0));
51+
}
52+
53+
@Test
54+
void testChaining() {
55+
var ts = new ToolSet().addBuiltIn("bash").addMcp("*").addCustom("my_tool");
56+
assertEquals(3, ts.size());
57+
assertEquals("builtin:bash", ts.get(0));
58+
assertEquals("mcp:*", ts.get(1));
59+
assertEquals("custom:my_tool", ts.get(2));
60+
}
61+
62+
@Test
63+
void testAddBuiltInCollection() {
64+
var ts = new ToolSet();
65+
ts.addBuiltIn((Collection<String>) BuiltInTools.ISOLATED);
66+
assertEquals(BuiltInTools.ISOLATED.size(), ts.size());
67+
assertTrue(ts.contains("builtin:ask_user"));
68+
assertTrue(ts.contains("builtin:task_complete"));
69+
}
70+
71+
@Test
72+
void testInvalidNameThrows() {
73+
assertThrows(IllegalArgumentException.class, () -> new ToolSet().addBuiltIn(""));
74+
assertThrows(IllegalArgumentException.class, () -> new ToolSet().addBuiltIn((String) null));
75+
assertThrows(IllegalArgumentException.class, () -> new ToolSet().addBuiltIn("bad/name"));
76+
assertThrows(IllegalArgumentException.class, () -> new ToolSet().addBuiltIn("bad name"));
77+
assertThrows(IllegalArgumentException.class, () -> new ToolSet().addMcp("bad.name"));
78+
assertThrows(IllegalArgumentException.class, () -> new ToolSet().addCustom("bad:name"));
79+
}
80+
81+
@Test
82+
void testValidNamePatterns() {
83+
// Names with letters, digits, hyphens, underscores are valid
84+
assertDoesNotThrow(() -> new ToolSet().addBuiltIn("my-tool_123"));
85+
assertDoesNotThrow(() -> new ToolSet().addMcp("github-list_issues"));
86+
}
87+
88+
@Test
89+
void testBuiltInToolsIsolatedIsUnmodifiable() {
90+
assertThrows(UnsupportedOperationException.class, () -> BuiltInTools.ISOLATED.add("new_tool"));
91+
}
92+
93+
@Test
94+
void testToolSetIsListOfStrings() {
95+
var ts = new ToolSet().addBuiltIn("bash").addMcp("*");
96+
// ToolSet extends ArrayList<String>, so it is a List<String>
97+
List<String> list = ts;
98+
assertEquals(2, list.size());
99+
}
100+
}

0 commit comments

Comments
 (0)