Files
snack/apt/helpers_linux_test.go
Tai Groot c34b7a467c test: exhaustive unit tests for all provider-specific interfaces
Add 740 total tests (up from ~200) covering:
- Compile-time interface compliance for all providers
- GetCapabilities assertions for every provider
- Parse function edge cases: empty, malformed, single-entry, multi-entry
- apt: extract inline parse logic into testable functions (parsePolicyCandidate,
  parseUpgradeSimulation, parseHoldList, parseOwner, parseSourcesLine)
- dnf/rpm: edge cases for both dnf4 and dnf5 parsers, normalize/parseArch
- pacman/aur: parseUpgrades, parseGroupPkgSet, capabilities
- apk: parseUpgradeSimulation, parseListLine, SupportsDryRun
- flatpak/snap: semverCmp, stripNonNumeric edge cases
- pkg/ports: all parse functions with thorough edge cases

Every provider now has:
- Interface compliance checks (what it implements AND what it doesn't)
- Capabilities test via snack.GetCapabilities()
- Parse function unit tests with table-driven edge cases
2026-03-06 01:07:35 +00:00

153 lines
3.8 KiB
Go

//go:build linux
package apt
import (
"testing"
"github.com/gogrlx/snack"
)
func TestFormatTargets(t *testing.T) {
tests := []struct {
name string
targets []snack.Target
want []string
}{
{
name: "empty",
targets: nil,
want: []string{},
},
{
name: "name_only",
targets: []snack.Target{{Name: "curl"}},
want: []string{"curl"},
},
{
name: "with_version",
targets: []snack.Target{{Name: "curl", Version: "7.88"}},
want: []string{"curl=7.88"},
},
{
name: "mixed",
targets: []snack.Target{
{Name: "curl"},
{Name: "bash", Version: "5.2-1"},
{Name: "vim"},
},
want: []string{"curl", "bash=5.2-1", "vim"},
},
{
name: "version_with_epoch",
targets: []snack.Target{{Name: "systemd", Version: "1:252-2"}},
want: []string{"systemd=1:252-2"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := formatTargets(tt.targets)
if len(got) != len(tt.want) {
t.Fatalf("formatTargets() returned %d args, want %d", len(got), len(tt.want))
}
for i, g := range got {
if g != tt.want[i] {
t.Errorf("formatTargets()[%d] = %q, want %q", i, g, tt.want[i])
}
}
})
}
}
func TestBuildArgs(t *testing.T) {
tests := []struct {
name string
cmd string
pkgs []snack.Target
opts []snack.Option
want []string
}{
{
name: "basic_install",
cmd: "install",
pkgs: []snack.Target{{Name: "curl"}},
want: []string{"apt-get", "install", "curl"},
},
{
name: "install_with_yes",
cmd: "install",
pkgs: []snack.Target{{Name: "curl"}},
opts: []snack.Option{snack.WithAssumeYes()},
want: []string{"apt-get", "install", "-y", "curl"},
},
{
name: "install_with_dry_run",
cmd: "install",
pkgs: []snack.Target{{Name: "curl"}},
opts: []snack.Option{snack.WithDryRun()},
want: []string{"apt-get", "install", "--dry-run", "curl"},
},
{
name: "install_with_sudo",
cmd: "install",
pkgs: []snack.Target{{Name: "curl"}},
opts: []snack.Option{snack.WithSudo()},
want: []string{"sudo", "apt-get", "install", "curl"},
},
{
name: "install_with_reinstall",
cmd: "install",
pkgs: []snack.Target{{Name: "curl"}},
opts: []snack.Option{snack.WithReinstall()},
want: []string{"apt-get", "install", "--reinstall", "curl"},
},
{
name: "remove_no_reinstall_flag",
cmd: "remove",
pkgs: []snack.Target{{Name: "curl"}},
opts: []snack.Option{snack.WithReinstall()},
want: []string{"apt-get", "remove", "curl"}, // --reinstall only on install
},
{
name: "install_from_repo",
cmd: "install",
pkgs: []snack.Target{{Name: "curl"}},
opts: []snack.Option{snack.WithFromRepo("stable")},
want: []string{"apt-get", "install", "-t", "stable", "curl"},
},
{
name: "all_options",
cmd: "install",
pkgs: []snack.Target{{Name: "curl", Version: "7.88"}},
opts: []snack.Option{snack.WithSudo(), snack.WithAssumeYes(), snack.WithDryRun(), snack.WithFromRepo("sid"), snack.WithReinstall()},
want: []string{"sudo", "apt-get", "install", "-y", "--dry-run", "-t", "sid", "--reinstall", "curl=7.88"},
},
{
name: "multiple_packages",
cmd: "install",
pkgs: []snack.Target{{Name: "curl"}, {Name: "wget"}, {Name: "bash", Version: "5.2"}},
want: []string{"apt-get", "install", "curl", "wget", "bash=5.2"},
},
{
name: "upgrade_no_packages",
cmd: "upgrade",
pkgs: nil,
opts: []snack.Option{snack.WithAssumeYes()},
want: []string{"apt-get", "upgrade", "-y"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := buildArgs(tt.cmd, tt.pkgs, tt.opts...)
if len(got) != len(tt.want) {
t.Fatalf("buildArgs() = %v (len %d), want %v (len %d)", got, len(got), tt.want, len(tt.want))
}
for i, g := range got {
if g != tt.want[i] {
t.Errorf("buildArgs()[%d] = %q, want %q", i, g, tt.want[i])
}
}
})
}
}