package artifact import ( "reflect" "testing" ) func TestNormalizeTargetsPreservesOrderAndFirstOccurrence(t *testing.T) { targets := []Target{ {OS: "linux", Arch: "amd64"}, {OS: "windows", Arch: "arm64"}, {OS: "linux", Arch: "amd64"}, } want := []Target{{OS: "linux", Arch: "amd64"}, {OS: "windows", Arch: "arm64"}} if got := NormalizeTargets(targets); !reflect.DeepEqual(got, want) { t.Fatalf("NormalizeTargets() = %#v, want %#v", got, want) } } func TestNormalizeSettingsKeepsBuildInputsAndNormalizesTargets(t *testing.T) { settings := NormalizeSettings("./cmd/app", "app", []Target{ {OS: "linux", Arch: "amd64"}, {OS: "windows", Arch: "arm64"}, {OS: "linux", Arch: "amd64"}, }) want := Settings{ MainPackage: "./cmd/app", BinaryName: "app", Targets: []Target{{OS: "linux", Arch: "amd64"}, {OS: "windows", Arch: "arm64"}}, } if !reflect.DeepEqual(settings, want) { t.Fatalf("NormalizeSettings() = %#v, want %#v", settings, want) } } func TestExpectedBuildUsesSharedNamesInTargetOrder(t *testing.T) { targets := []Target{{OS: "windows", Arch: "arm64"}, {OS: "linux", Arch: "amd64"}} want := []Declaration{ {Target: targets[0], Filename: "app-v1.2.3-windows-arm64.exe"}, {Target: targets[1], Filename: "app-v1.2.3-linux-amd64"}, } if got := ExpectedBuild("app", "v1.2.3", targets); !reflect.DeepEqual(got, want) { t.Fatalf("ExpectedBuild() = %#v, want %#v", got, want) } } func TestValidComponentPreservesBuildAndReceiptRules(t *testing.T) { for _, value := range []string{"", "path/name", `path\name`, "line\nbreak", "line\rbreak"} { if ValidComponent(value) { t.Errorf("ValidComponent(%q) = true, want false", value) } } for _, value := range []string{"app", "..", "nul\x00byte"} { if !ValidComponent(value) { t.Errorf("ValidComponent(%q) = false, want true", value) } } } func TestValidateDeclarationsMatchesTargetsAndNames(t *testing.T) { linux := Target{OS: "linux", Arch: "amd64"} windows := Target{OS: "windows", Arch: "arm64"} first := Declaration{Target: linux, Filename: "app-v1.2.3-linux-amd64"} second := Declaration{Target: windows, Filename: "app-v1.2.3-windows-arm64.exe"} for _, test := range []struct { name string targets []Target recorded []Declaration valid bool }{ {"reordered", []Target{linux, windows}, []Declaration{second, first}, true}, {"count", []Target{linux, windows}, []Declaration{first}, false}, {"duplicate target", []Target{linux, linux}, []Declaration{first, first}, false}, {"duplicate artifact", []Target{linux, windows}, []Declaration{first, first}, false}, {"incorrect name", []Target{linux}, []Declaration{{Target: linux, Filename: "other"}}, false}, {"unknown target", []Target{linux}, []Declaration{second}, false}, {"unsafe target", []Target{{OS: "linux/other", Arch: "amd64"}}, []Declaration{{Target: linux, Filename: first.Filename}}, false}, } { t.Run(test.name, func(t *testing.T) { err := ValidateDeclarations("app", "v1.2.3", test.targets, test.recorded) if (err == nil) != test.valid { t.Fatalf("ValidateDeclarations() error = %v, valid = %t", err, test.valid) } }) } }