Skip to content

Commit 1d5cbef

Browse files
committed
test: add generated tests
1 parent 8764839 commit 1d5cbef

2 files changed

Lines changed: 292 additions & 0 deletions

File tree

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
package packagist
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"net/http"
7+
"net/http/httptest"
8+
"testing"
9+
"time"
10+
)
11+
12+
func TestNewClient(t *testing.T) {
13+
c, err := NewClient(time.Hour)
14+
if err != nil {
15+
t.Fatalf("NewClient failed: %v", err)
16+
}
17+
if c.baseURL != "https://repo.packagist.org" {
18+
t.Errorf("expected base URL %s, got %s", "https://repo.packagist.org", c.baseURL)
19+
}
20+
}
21+
22+
func TestFetchPackage_Success(t *testing.T) {
23+
// Build a fake Packagist p2 response
24+
vStable := p2Version{
25+
Name: "vendor/package",
26+
Version: "1.2.3",
27+
Description: "A great package",
28+
Homepage: "https://example.com",
29+
License: []string{"MIT"},
30+
Require: map[string]string{
31+
"php": ">=8.0",
32+
"ext-json": "*",
33+
"lib-icu": "*",
34+
"composer-plugin-api": "^2.0",
35+
"composer-runtime-api": "^2.2",
36+
"vendor/dep": "^0.9.0",
37+
"noslash": "1.0.0",
38+
},
39+
Source: struct{ URL string `json:"url"` }{URL: "git+https://github.com/user/repo.git"},
40+
Authors: []struct{ Name string `json:"name"` }{{Name: " Jane Doe "}},
41+
}
42+
vDev := p2Version{Name: "vendor/package", Version: "1.3.0-dev"}
43+
payload := p2Response{Packages: map[string][]p2Version{
44+
"vendor/package": {vDev, vStable}, // chooseLatestStable should skip dev and pick vStable
45+
}}
46+
47+
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
48+
if r.URL.Path == "/p2/vendor/package.json" {
49+
_ = json.NewEncoder(w).Encode(payload)
50+
return
51+
}
52+
w.WriteHeader(http.StatusNotFound)
53+
}))
54+
defer server.Close()
55+
56+
c, err := NewClient(time.Hour)
57+
if err != nil {
58+
t.Fatalf("NewClient error: %v", err)
59+
}
60+
// Point client to our test server
61+
c.baseURL = server.URL
62+
63+
info, err := c.FetchPackage(context.Background(), "Vendor/Package", true)
64+
if err != nil {
65+
t.Fatalf("FetchPackage error: %v", err)
66+
}
67+
68+
if info.Name != "vendor/package" {
69+
t.Errorf("want name vendor/package, got %s", info.Name)
70+
}
71+
if info.Version != "1.2.3" {
72+
t.Errorf("want version 1.2.3, got %s", info.Version)
73+
}
74+
if info.Description != "A great package" {
75+
t.Errorf("unexpected description: %s", info.Description)
76+
}
77+
if info.Author != "Jane Doe" {
78+
t.Errorf("want author 'Jane Doe', got %q", info.Author)
79+
}
80+
if info.Repository != "https://github.com/user/repo" {
81+
t.Errorf("unexpected repository url: %s", info.Repository)
82+
}
83+
if info.HomePage != "https://example.com" {
84+
t.Errorf("unexpected homepage: %s", info.HomePage)
85+
}
86+
// Only vendor/dep should survive filtering
87+
if len(info.Dependencies) != 1 || info.Dependencies[0] != "vendor/dep" {
88+
t.Errorf("unexpected dependencies: %#v", info.Dependencies)
89+
}
90+
}
91+
92+
func TestFetchPackage_NotFound(t *testing.T) {
93+
server := httptest.NewServer(http.NotFoundHandler())
94+
defer server.Close()
95+
96+
c, err := NewClient(time.Minute)
97+
if err != nil {
98+
t.Fatalf("NewClient error: %v", err)
99+
}
100+
c.baseURL = server.URL
101+
102+
if _, err := c.FetchPackage(context.Background(), "missing/pkg", true); err == nil {
103+
t.Fatalf("expected error for 404, got nil")
104+
}
105+
}
106+
107+
func TestNormalizeName(t *testing.T) {
108+
if got := normalizeName(" VenDor/PackAge "); got != "vendor/package" {
109+
t.Errorf("normalizeName unexpected: %q", got)
110+
}
111+
}
112+
113+
func TestNormalizeRepoURL(t *testing.T) {
114+
cases := []struct{ in, want string }{
115+
{"git+https://github.com/user/repo.git", "https://github.com/user/repo"},
116+
{"git://github.com/user/repo.git", "https://github.com/user/repo"},
117+
{"git@github.com:user/repo.git", "https://github.com/user/repo"},
118+
{"https://github.com/user/repo", "https://github.com/user/repo"},
119+
{"", ""},
120+
}
121+
for _, c := range cases {
122+
if got := normalizeRepoURL(c.in); got != c.want {
123+
t.Errorf("normalizeRepoURL(%q) = %q, want %q", c.in, got, c.want)
124+
}
125+
}
126+
}
127+
128+
func TestFilterComposerDeps(t *testing.T) {
129+
in := map[string]string{
130+
"php": ">=8.1",
131+
"ext-json": "*",
132+
"lib-icu": "*",
133+
"composer-plugin-api": "^2",
134+
"composer-runtime-api": "^2",
135+
"vendor/dep1": "^1.0",
136+
"Vendor/Dep2": "*",
137+
"no/slash?": "1.0", // still has slash, should be included once normalized by caller (function just checks contains "/")
138+
"noslash": "*", // ignored
139+
}
140+
got := filterComposerDeps(in)
141+
// Expect entries with a slash and not platform/composer special ones
142+
if _, ok := got["vendor/dep1"]; !ok {
143+
t.Errorf("missing vendor/dep1 in %v", got)
144+
}
145+
if _, ok := got["vendor/dep2"]; !ok {
146+
t.Errorf("missing vendor/dep2 in %v", got)
147+
}
148+
if _, ok := got["php"]; ok {
149+
t.Errorf("php should be filtered out")
150+
}
151+
if _, ok := got["ext-json"]; ok {
152+
t.Errorf("ext-json should be filtered out")
153+
}
154+
if _, ok := got["lib-icu"]; ok {
155+
t.Errorf("lib-icu should be filtered out")
156+
}
157+
if _, ok := got["composer-plugin-api"]; ok {
158+
t.Errorf("composer-plugin-api should be filtered out")
159+
}
160+
if _, ok := got["composer-runtime-api"]; ok {
161+
t.Errorf("composer-runtime-api should be filtered out")
162+
}
163+
}
164+
165+
func TestChooseLatestStable(t *testing.T) {
166+
versions := []p2Version{
167+
{Version: "2-dev"},
168+
{Version: "v3"}, // no dot, not chosen by stable rule
169+
{Version: "1.5.0"}, // has dot, should be chosen
170+
}
171+
got := chooseLatestStable(versions)
172+
if got.Version != "1.5.0" {
173+
t.Errorf("chooseLatestStable = %s", got.Version)
174+
}
175+
176+
// If none match, fall back to first
177+
versions = []p2Version{{Version: "dev-main"}, {Version: "v2"}}
178+
got = chooseLatestStable(versions)
179+
if got.Version != "dev-main" {
180+
t.Errorf("chooseLatestStable fallback = %s", got.Version)
181+
}
182+
}
183+
184+
func TestP2Version_UnmarshalJSON(t *testing.T) {
185+
// license as string, require as object with non-string values
186+
raw := `{
187+
"name": "vendor/pkg",
188+
"version": "1.0.0",
189+
"description": "d",
190+
"homepage": "h",
191+
"license": "BSD-3-Clause",
192+
"require": {"vendor/dep": "^1", "php": ">=8.0", "weird": 5},
193+
"source": {"url": "https://example.com/repo.git"},
194+
"authors": [{"name": "Ann"}]
195+
}`
196+
var v p2Version
197+
if err := json.Unmarshal([]byte(raw), &v); err != nil {
198+
t.Fatalf("unmarshal: %v", err)
199+
}
200+
if len(v.License) != 1 || v.License[0] != "BSD-3-Clause" {
201+
t.Errorf("unexpected license: %#v", v.License)
202+
}
203+
if v.Require["vendor/dep"] != "^1" || v.Require["php"] != ">=8.0" {
204+
t.Errorf("unexpected require: %#v", v.Require)
205+
}
206+
}

pkg/source/php/php_test.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package php
2+
3+
import (
4+
"testing"
5+
"time"
6+
7+
"github.com/matzehuels/stacktower/pkg/integrations/packagist"
8+
)
9+
10+
func TestNewParser(t *testing.T) {
11+
p, err := NewParser(time.Minute)
12+
if err != nil {
13+
t.Fatalf("NewParser error: %v", err)
14+
}
15+
if p == nil || p.client == nil {
16+
t.Fatalf("parser or client is nil")
17+
}
18+
}
19+
20+
func TestPackageInfo_Getters(t *testing.T) {
21+
pi := &packageInfo{&packagist.PackageInfo{
22+
Name: "vendor/pkg",
23+
Version: "1.0.0",
24+
Dependencies: []string{"vendor/dep"},
25+
}}
26+
27+
if pi.GetName() != "vendor/pkg" {
28+
t.Errorf("GetName = %s", pi.GetName())
29+
}
30+
if pi.GetVersion() != "1.0.0" {
31+
t.Errorf("GetVersion = %s", pi.GetVersion())
32+
}
33+
deps := pi.GetDependencies()
34+
if len(deps) != 1 || deps[0] != "vendor/dep" {
35+
t.Errorf("GetDependencies = %#v", deps)
36+
}
37+
}
38+
39+
func TestPackageInfo_ToMetadata(t *testing.T) {
40+
pi := &packageInfo{&packagist.PackageInfo{
41+
Version: "2.3.4",
42+
Description: "desc",
43+
License: "MIT",
44+
Author: "Jane",
45+
}}
46+
47+
m := pi.ToMetadata()
48+
if m["version"].(string) != "2.3.4" {
49+
t.Errorf("version missing or wrong: %#v", m)
50+
}
51+
if m["description"].(string) != "desc" {
52+
t.Errorf("description wrong: %#v", m)
53+
}
54+
if m["license"].(string) != "MIT" {
55+
t.Errorf("license wrong: %#v", m)
56+
}
57+
if m["author"].(string) != "Jane" {
58+
t.Errorf("author wrong: %#v", m)
59+
}
60+
}
61+
62+
func TestPackageInfo_ToRepoInfo(t *testing.T) {
63+
pi := &packageInfo{&packagist.PackageInfo{
64+
Name: "vendor/pkg",
65+
Version: "0.1.0",
66+
Repository: "https://github.com/user/repo",
67+
HomePage: "https://example.com",
68+
}}
69+
70+
ri := pi.ToRepoInfo()
71+
if ri.Name != "vendor/pkg" || ri.Version != "0.1.0" {
72+
t.Errorf("unexpected name/version: %#v", ri)
73+
}
74+
if ri.ManifestFile != "composer.json" {
75+
t.Errorf("unexpected manifest: %s", ri.ManifestFile)
76+
}
77+
if ri.ProjectURLs["repository"] != "https://github.com/user/repo" {
78+
t.Errorf("repo url missing: %#v", ri.ProjectURLs)
79+
}
80+
if ri.ProjectURLs["homepage"] != "https://example.com" {
81+
t.Errorf("homepage url missing: %#v", ri.ProjectURLs)
82+
}
83+
if ri.HomePage != "https://example.com" {
84+
t.Errorf("homepage field wrong: %s", ri.HomePage)
85+
}
86+
}

0 commit comments

Comments
 (0)