1
0
Fork 0
mirror of https://github.com/imjasonh/terraform-playground synced 2026-07-07 23:35:16 +00:00
terraform-playground/pymage/internal/lock/lock_test.go
Cursor Agent 9a7dc02643
lock: accept name[extras]==version; error on dependency-bearing options (-e/-r/-c)
Co-authored-by: Jason Hall <imjasonh@users.noreply.github.com>
2026-06-10 14:35:36 +00:00

106 lines
3.2 KiB
Go

package lock
import (
"strings"
"testing"
)
const sample = `
# This file is autogenerated by pip-compile
--index-url https://pypi.org/simple
flask==2.3.3 \
--hash=sha256:09c347a92aa7ff4a8e7f3206795f30d826654baf38b873d0744cd571ca609efc \
--hash=sha256:f69fcd559dc907ed196ab9df0e48471709175e696d6e698dd4dbe940f96ce66b
# via -r requirements.in
Werkzeug==2.3.7 \
--hash=sha256:2b8c0e447b4b9dbcc85dd97b6eeb4dcbaf6c8b6c3be0bd654e25553e0a2157d8
click == 8.1.7 ; python_version >= "3.8" \
--hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28
`
func TestParse(t *testing.T) {
reqs, err := Parse(strings.NewReader(sample))
if err != nil {
t.Fatal(err)
}
if len(reqs) != 3 {
t.Fatalf("got %d reqs, want 3: %+v", len(reqs), reqs)
}
if reqs[0].Name != "flask" || reqs[0].Version != "2.3.3" {
t.Errorf("req0 = %+v", reqs[0])
}
if len(reqs[0].Hashes) != 2 {
t.Errorf("flask hashes = %v, want 2", reqs[0].Hashes)
}
if reqs[2].Name != "click" || reqs[2].Version != "8.1.7" {
t.Errorf("req2 = %+v (markers should be stripped)", reqs[2])
}
if len(reqs[2].Hashes) != 1 {
t.Errorf("click hashes = %v, want 1", reqs[2].Hashes)
}
}
func TestValidate(t *testing.T) {
ok := []Requirement{{Name: "a", Version: "1", Hashes: []string{"abc"}}}
if err := Validate(ok, true); err != nil {
t.Errorf("unexpected error: %v", err)
}
noHash := []Requirement{{Name: "a", Version: "1"}}
if err := Validate(noHash, true); err == nil {
t.Error("expected error for missing hash")
}
if err := Validate(noHash, false); err != nil {
t.Errorf("unexpected error when hashes not required: %v", err)
}
noPin := []Requirement{{Name: "a"}}
if err := Validate(noPin, false); err == nil {
t.Error("expected error for unpinned requirement")
}
}
func TestParseRejectsUnsupportedLines(t *testing.T) {
for _, in := range []string{
"requests>=2.0", // not pinned with ==
"mypkg @ https://example.com/x.whl", // direct URL reference
"justaname", // bare name
"-e ./local", // editable reference
"--editable=./local", // editable reference
"-r other.txt", // nested requirements
"-c constraints.txt", // nested constraints
} {
if _, err := Parse(strings.NewReader(in)); err == nil {
t.Errorf("expected error for unsupported line %q", in)
}
}
}
func TestParseAllowsExtrasAndBenignOptions(t *testing.T) {
in := `--index-url https://pypi.org/simple
requests[socks,security]==2.31.0 --hash=sha256:` + strings.Repeat("a", 64) + `
`
reqs, err := Parse(strings.NewReader(in))
if err != nil {
t.Fatal(err)
}
if len(reqs) != 1 || reqs[0].Name != "requests" || reqs[0].Version != "2.31.0" {
t.Fatalf("got %+v", reqs)
}
if len(reqs[0].Hashes) != 1 {
t.Errorf("expected the hash to be parsed, got %v", reqs[0].Hashes)
}
}
func TestNormalizeName(t *testing.T) {
for _, tc := range []struct{ in, want string }{
{"Flask", "flask"},
{"typing_extensions", "typing-extensions"},
{"ruamel.yaml", "ruamel-yaml"},
{"a--b__c", "a-b-c"},
} {
if got := NormalizeName(tc.in); got != tc.want {
t.Errorf("NormalizeName(%q) = %q, want %q", tc.in, got, tc.want)
}
}
}