Skip to content

Commit e28cd46

Browse files
[Autoloop: python-to-go-migration] Iteration 120: Add extra test files for 7 packages (listcmd, pluginparser, urlnormalize, gitauthenv, installedpkg, unpacker, opencode)
Run: https://github.com/githubnext/apm/actions/runs/26009157875 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 0eebf83 commit e28cd46

8 files changed

Lines changed: 930 additions & 2 deletions

File tree

benchmarks/migration-status.json

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"original_python_lines": 87626,
3-
"migrated_python_lines": 873506,
3+
"migrated_python_lines": 874399,
44
"migrated_modules": [
55
{
66
"module": "deps/apm_resolver",
@@ -16852,6 +16852,41 @@
1685216852
"module": "outputwriter-extra-tests",
1685316853
"status": "test-migrated",
1685416854
"python_lines": 78
16855+
},
16856+
{
16857+
"module": "test-migration/listcmd-extra",
16858+
"python_lines": 126,
16859+
"status": "test-migrated"
16860+
},
16861+
{
16862+
"module": "test-migration/pluginparser-extra",
16863+
"python_lines": 132,
16864+
"status": "test-migrated"
16865+
},
16866+
{
16867+
"module": "test-migration/urlnormalize-extra",
16868+
"python_lines": 110,
16869+
"status": "test-migrated"
16870+
},
16871+
{
16872+
"module": "test-migration/gitauthenv-extra",
16873+
"python_lines": 115,
16874+
"status": "test-migrated"
16875+
},
16876+
{
16877+
"module": "test-migration/installedpkg-extra",
16878+
"python_lines": 115,
16879+
"status": "test-migrated"
16880+
},
16881+
{
16882+
"module": "test-migration/unpacker-extra",
16883+
"python_lines": 157,
16884+
"status": "test-migrated"
16885+
},
16886+
{
16887+
"module": "test-migration/opencode-extra",
16888+
"python_lines": 138,
16889+
"status": "test-migrated"
1685516890
}
1685616891
]
16857-
}
16892+
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
package opencode_test
2+
3+
import (
4+
"encoding/json"
5+
"os"
6+
"path/filepath"
7+
"testing"
8+
9+
"github.com/githubnext/apm/internal/adapters/opencode"
10+
)
11+
12+
func TestToOpenCodeFormat_NoCommand(t *testing.T) {
13+
entry := opencode.CopilotEntry{}
14+
got := opencode.ToOpenCodeFormat(entry, true)
15+
if got.Type != "local" {
16+
t.Errorf("expected local type, got %q", got.Type)
17+
}
18+
if len(got.Command) != 0 {
19+
t.Errorf("expected no command, got %v", got.Command)
20+
}
21+
}
22+
23+
func TestToOpenCodeFormat_ArgsPreserved(t *testing.T) {
24+
entry := opencode.CopilotEntry{
25+
Command: "node",
26+
Args: []string{"server.js", "--port", "3000"},
27+
}
28+
got := opencode.ToOpenCodeFormat(entry, true)
29+
if len(got.Command) != 4 {
30+
t.Fatalf("expected 4 command parts, got %d: %v", len(got.Command), got.Command)
31+
}
32+
if got.Command[0] != "node" {
33+
t.Errorf("Command[0] = %q, want node", got.Command[0])
34+
}
35+
if got.Command[3] != "3000" {
36+
t.Errorf("Command[3] = %q, want 3000", got.Command[3])
37+
}
38+
}
39+
40+
func TestToOpenCodeFormat_URLWithNoHeaders(t *testing.T) {
41+
entry := opencode.CopilotEntry{URL: "https://example.com/mcp"}
42+
got := opencode.ToOpenCodeFormat(entry, true)
43+
if got.Type != "remote" {
44+
t.Errorf("expected remote type, got %q", got.Type)
45+
}
46+
if got.URL != "https://example.com/mcp" {
47+
t.Errorf("URL mismatch: %q", got.URL)
48+
}
49+
if len(got.Headers) != 0 {
50+
t.Errorf("expected no headers, got %v", got.Headers)
51+
}
52+
}
53+
54+
func TestToOpenCodeFormat_EmptyEnv(t *testing.T) {
55+
entry := opencode.CopilotEntry{Command: "cmd"}
56+
got := opencode.ToOpenCodeFormat(entry, true)
57+
if len(got.Environment) != 0 {
58+
t.Errorf("expected no environment, got %v", got.Environment)
59+
}
60+
}
61+
62+
func TestServerEntry_Fields(t *testing.T) {
63+
e := opencode.ServerEntry{
64+
Type: "local",
65+
Command: []string{"npx", "-y", "pkg"},
66+
Enabled: true,
67+
Environment: map[string]string{"API_KEY": "secret"},
68+
}
69+
if e.Type != "local" {
70+
t.Errorf("Type mismatch: %q", e.Type)
71+
}
72+
if len(e.Command) != 3 {
73+
t.Errorf("Command length: %d", len(e.Command))
74+
}
75+
if !e.Enabled {
76+
t.Error("Enabled should be true")
77+
}
78+
if e.Environment["API_KEY"] != "secret" {
79+
t.Errorf("Environment mismatch")
80+
}
81+
}
82+
83+
func TestCopilotEntry_Fields(t *testing.T) {
84+
e := opencode.CopilotEntry{
85+
Command: "npx",
86+
Args: []string{"-y", "pkg"},
87+
Env: map[string]string{"KEY": "val"},
88+
URL: "",
89+
}
90+
if e.Command != "npx" {
91+
t.Errorf("Command mismatch: %q", e.Command)
92+
}
93+
if len(e.Args) != 2 {
94+
t.Errorf("Args length: %d", len(e.Args))
95+
}
96+
}
97+
98+
func TestGetCurrentConfig_WithFile(t *testing.T) {
99+
dir := t.TempDir()
100+
openDir := filepath.Join(dir, ".opencode")
101+
if err := os.Mkdir(openDir, 0o755); err != nil {
102+
t.Fatal(err)
103+
}
104+
cfgFile := filepath.Join(dir, "opencode.json")
105+
cfg := map[string]interface{}{
106+
"mcp": map[string]interface{}{
107+
"my-server": map[string]interface{}{
108+
"type": "local",
109+
"command": []string{"node", "s.js"},
110+
"enabled": true,
111+
},
112+
},
113+
}
114+
b, _ := json.Marshal(cfg)
115+
if err := os.WriteFile(cfgFile, b, 0o644); err != nil {
116+
t.Fatal(err)
117+
}
118+
adapter := opencode.New(dir)
119+
got := adapter.GetCurrentConfig()
120+
if got == nil {
121+
t.Fatal("expected non-nil config")
122+
}
123+
if _, ok := got["mcp"]; !ok {
124+
t.Error("expected 'mcp' key in config")
125+
}
126+
}
127+
128+
func TestIsOptedIn_WithFile(t *testing.T) {
129+
dir := t.TempDir()
130+
openDir := filepath.Join(dir, ".opencode")
131+
if err := os.Mkdir(openDir, 0o755); err != nil {
132+
t.Fatal(err)
133+
}
134+
adapter := opencode.New(dir)
135+
if !adapter.IsOptedIn() {
136+
t.Error("IsOptedIn should return true when .opencode/ exists")
137+
}
138+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package urlnormalize_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/githubnext/apm/internal/cache/urlnormalize"
7+
)
8+
9+
func TestNormalizeRepoURL_GitLabLowercase(t *testing.T) {
10+
got := urlnormalize.NormalizeRepoURL("https://gitlab.com/Owner/Repo")
11+
want := "https://gitlab.com/owner/repo"
12+
if got != want {
13+
t.Errorf("got %q, want %q", got, want)
14+
}
15+
}
16+
17+
func TestNormalizeRepoURL_BitbucketLowercase(t *testing.T) {
18+
got := urlnormalize.NormalizeRepoURL("https://bitbucket.org/Owner/Repo.git")
19+
want := "https://bitbucket.org/owner/repo"
20+
if got != want {
21+
t.Errorf("got %q, want %q", got, want)
22+
}
23+
}
24+
25+
func TestNormalizeRepoURL_SSHDefaultPort(t *testing.T) {
26+
got := urlnormalize.NormalizeRepoURL("ssh://git@github.com:22/owner/repo")
27+
want := "ssh://git@github.com/owner/repo"
28+
if got != want {
29+
t.Errorf("got %q, want %q", got, want)
30+
}
31+
}
32+
33+
func TestNormalizeRepoURL_GitDefaultPort(t *testing.T) {
34+
got := urlnormalize.NormalizeRepoURL("git://github.com:9418/owner/repo")
35+
want := "git://github.com/owner/repo"
36+
if got != want {
37+
t.Errorf("got %q, want %q", got, want)
38+
}
39+
}
40+
41+
func TestNormalizeRepoURL_NoScheme(t *testing.T) {
42+
got := urlnormalize.NormalizeRepoURL("github.com/owner/repo")
43+
// without scheme, host is treated as-is
44+
if got == "" {
45+
t.Error("expected non-empty result")
46+
}
47+
}
48+
49+
func TestNormalizeRepoURL_EmptyString(t *testing.T) {
50+
got := urlnormalize.NormalizeRepoURL("")
51+
if got != "" {
52+
t.Errorf("expected empty, got %q", got)
53+
}
54+
}
55+
56+
func TestNormalizeRepoURL_SCPWithDotGit(t *testing.T) {
57+
got := urlnormalize.NormalizeRepoURL("git@gitlab.com:owner/repo.git")
58+
if got != "ssh://git@gitlab.com/owner/repo" {
59+
t.Errorf("got %q", got)
60+
}
61+
}
62+
63+
func TestNormalizeRepoURL_HTTPDefaultPort(t *testing.T) {
64+
got := urlnormalize.NormalizeRepoURL("http://github.com:80/owner/repo")
65+
want := "http://github.com/owner/repo"
66+
if got != want {
67+
t.Errorf("got %q, want %q", got, want)
68+
}
69+
}
70+
71+
func TestNormalizeRepoURL_StripTrailingWhitespace(t *testing.T) {
72+
got := urlnormalize.NormalizeRepoURL(" https://github.com/owner/repo ")
73+
want := "https://github.com/owner/repo"
74+
if got != want {
75+
t.Errorf("got %q, want %q", got, want)
76+
}
77+
}
78+
79+
func TestCacheKey_DifferentURLs(t *testing.T) {
80+
k1 := urlnormalize.CacheKey("https://github.com/owner/repo1")
81+
k2 := urlnormalize.CacheKey("https://github.com/owner/repo2")
82+
if k1 == k2 {
83+
t.Error("different URLs must produce different cache keys")
84+
}
85+
}
86+
87+
func TestCacheKey_IsHex(t *testing.T) {
88+
key := urlnormalize.CacheKey("https://github.com/owner/repo")
89+
for _, c := range key {
90+
if !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f')) {
91+
t.Errorf("cache key contains non-hex char %q: %s", c, key)
92+
}
93+
}
94+
}
95+
96+
func TestNormalizeRepoURL_PreservesCustomHostPath(t *testing.T) {
97+
got := urlnormalize.NormalizeRepoURL("https://ghe.example.com/Org/Repo")
98+
// non-known host: path is preserved as-is (not lowercased)
99+
if got == "" {
100+
t.Error("expected non-empty result")
101+
}
102+
}
103+
104+
func TestNormalizeRepoURL_UserWithoutPassword(t *testing.T) {
105+
got := urlnormalize.NormalizeRepoURL("https://user@example.com/org/repo")
106+
want := "https://user@example.com/org/repo"
107+
if got != want {
108+
t.Errorf("got %q, want %q", got, want)
109+
}
110+
}

0 commit comments

Comments
 (0)