test: harden coverage and make tests parallel-safe (#2797)
* Test coverage hardening and parallel-safe refactors Add focused test coverage for under-tested operational paths, edge branches, and make key table-driven suites parallel-safe. Also fixed flaky installer test execution under repeated/parallel runs. * chore: fix goimports ordering for golangci-lint * Test(download): expand integration coverage for download paths Add integration scenarios for force/pull repo updates, repo-only and skip semantics, and direct AUR download/scanner coverage used by getpkgbuild and package preparation. * Test(exe): relax systemd-run path assertion Fix flaky TestBuildGitCmd by accepting an absolute systemd-run path while still asserting the expected binary is used. * Test(text): avoid race in color tests Remove parallel execution from TestColorHash so global UseColor writes do not overlap with color consumers in parallel tests and trigger race detector failures. * fix potential race conditions
This commit is contained in:
22 files changed
+1713
-78
No files matched your search
@@ -0,0 +1,77 @@
|
||||
//go:build !integration
|
||||
// +build !integration
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/Jguer/aur"
|
||||
"github.com/stretchr/testify/require"
|
||||
gock "gopkg.in/h2non/gock.v1"
|
||||
|
||||
"github.com/Jguer/yay/v12/pkg/db"
|
||||
mockaur "github.com/Jguer/yay/v12/pkg/dep/mock"
|
||||
"github.com/Jguer/yay/v12/pkg/settings/parser"
|
||||
"github.com/Jguer/yay/v12/pkg/text"
|
||||
)
|
||||
|
||||
func TestPrintPkgbuilds(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
targets []string
|
||||
results []aur.Pkg
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "prints pkgbuild when package exists",
|
||||
targets: []string{"aur/pkg"},
|
||||
results: []aur.Pkg{{Name: "pkg", PackageBase: "pkg"}},
|
||||
},
|
||||
{
|
||||
name: "returns error when package does not exist",
|
||||
targets: []string{"aur/found", "aur/missing"},
|
||||
results: nil,
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
defer gock.Off()
|
||||
gock.New("https://aur.archlinux.org").
|
||||
Get("/cgit/aur.git/plain/PKGBUILD").
|
||||
Reply(200).
|
||||
BodyString("pkgbuild")
|
||||
|
||||
err := printPkgbuilds(&mockDBSearcher{}, &mockaur.MockAUR{
|
||||
GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
|
||||
return tc.results, nil
|
||||
},
|
||||
}, &http.Client{}, text.NewLogger(io.Discard, io.Discard, strings.NewReader(""), true, "test"),
|
||||
tc.targets, parser.ModeAny, "https://aur.archlinux.org")
|
||||
if tc.wantErr {
|
||||
require.Error(t, err)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type mockDBSearcher struct{}
|
||||
|
||||
func (m *mockDBSearcher) SyncPackage(string) db.IPackage {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockDBSearcher) SyncPackageFromDB(string, string) db.IPackage {
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
//go:build !integration
|
||||
// +build !integration
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/Jguer/aur"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/Jguer/yay/v12/pkg/db"
|
||||
"github.com/Jguer/yay/v12/pkg/db/mock"
|
||||
"github.com/Jguer/yay/v12/pkg/dep"
|
||||
mockaur "github.com/Jguer/yay/v12/pkg/dep/mock"
|
||||
"github.com/Jguer/yay/v12/pkg/text"
|
||||
)
|
||||
|
||||
func TestGraphPackageRequiresSingleTarget(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
logger := text.NewLogger(io.Discard, io.Discard, strings.NewReader(""), true, "test")
|
||||
grapher := dep.NewGrapher(&mock.DBExecutor{}, &mockaur.MockAUR{}, false, false, false, false, false, logger)
|
||||
err := graphPackage(context.Background(), grapher, []string{"one", "two"})
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestGraphPackage(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
logger := text.NewLogger(io.Discard, io.Discard, strings.NewReader(""), true, "test")
|
||||
grapher := dep.NewGrapher(&mock.DBExecutor{
|
||||
LocalPackageFn: func(string) db.IPackage { return nil },
|
||||
}, &mockaur.MockAUR{
|
||||
GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
|
||||
return []aur.Pkg{
|
||||
{
|
||||
Name: "target",
|
||||
PackageBase: "target",
|
||||
Version: "1.2.3",
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
}, false, false, false, false, false, logger)
|
||||
|
||||
output := captureStdout(t, func() {
|
||||
err := graphPackage(context.Background(), grapher, []string{"target"})
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
require.Contains(t, output, "digraph {")
|
||||
require.Contains(t, output, "layers map")
|
||||
}
|
||||
|
||||
func captureStdout(t *testing.T, fn func()) string {
|
||||
orig := os.Stdout
|
||||
r, w, err := os.Pipe()
|
||||
require.NoError(t, err)
|
||||
|
||||
os.Stdout = w
|
||||
defer func() {
|
||||
os.Stdout = orig
|
||||
}()
|
||||
|
||||
buffer := &bytes.Buffer{}
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
_, _ = io.Copy(buffer, r)
|
||||
close(done)
|
||||
}()
|
||||
|
||||
fn()
|
||||
|
||||
require.NoError(t, w.Close())
|
||||
<-done
|
||||
|
||||
return buffer.String()
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
//go:build !integration
|
||||
// +build !integration
|
||||
|
||||
package dep
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/Jguer/aur"
|
||||
"github.com/Jguer/dyalpm"
|
||||
gosrc "github.com/Morganamilo/go-srcinfo"
|
||||
mapset "github.com/deckarep/golang-set/v2"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/Jguer/yay/v12/pkg/db/mock"
|
||||
mockaur "github.com/Jguer/yay/v12/pkg/dep/mock"
|
||||
"github.com/Jguer/yay/v12/pkg/query"
|
||||
"github.com/Jguer/yay/v12/pkg/text"
|
||||
)
|
||||
|
||||
func TestGrapher_GraphFromTargetsBranches(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
logger := text.NewLogger(io.Discard, io.Discard, strings.NewReader(""), true, "test")
|
||||
dbExecutor := &mock.DBExecutor{
|
||||
LocalPackageFn: func(string) mock.IPackage { return nil },
|
||||
SatisfierFromDBFn: func(_, db string) (mock.IPackage, error) {
|
||||
return &mock.Package{
|
||||
PName: "repo-pkg",
|
||||
PVersion: "1",
|
||||
PDB: mock.NewDB(db),
|
||||
}, nil
|
||||
},
|
||||
PackagesFromGroupAndDBFn: func(name, dbName string) ([]mock.IPackage, error) {
|
||||
return nil, nil
|
||||
},
|
||||
}
|
||||
|
||||
grapher := NewGrapher(dbExecutor, &mockaur.MockAUR{}, false, false, false, false, false, logger)
|
||||
graph, err := grapher.GraphFromTargets(context.Background(), nil, []string{"core/repo-pkg"})
|
||||
require.NoError(t, err)
|
||||
require.True(t, graph.Exists("repo-pkg"))
|
||||
}
|
||||
|
||||
func TestGrapher_GraphFromTargetsFallbackToGroup(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
logger := text.NewLogger(io.Discard, io.Discard, strings.NewReader(""), true, "test")
|
||||
dbExecutor := &mock.DBExecutor{
|
||||
SyncSatisfierFn: func(string) mock.IPackage {
|
||||
return nil
|
||||
},
|
||||
PackagesFromGroupFn: func(name string) []mock.IPackage {
|
||||
return []mock.IPackage{
|
||||
&mock.Package{
|
||||
PName: "grouped",
|
||||
PDB: mock.NewDB("extra"),
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
grapher := NewGrapher(dbExecutor, &mockaur.MockAUR{}, false, false, false, false, false, logger)
|
||||
graph, err := grapher.GraphFromTargets(context.Background(), nil, []string{"grouped"})
|
||||
require.NoError(t, err)
|
||||
require.True(t, graph.Exists("grouped"))
|
||||
require.True(t, graph.GetNodeInfo("grouped").Value.IsGroup)
|
||||
}
|
||||
|
||||
func TestGrapher_GraphFromTargetsFallbackToAur(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
logger := text.NewLogger(io.Discard, io.Discard, strings.NewReader(""), true, "test")
|
||||
dbExecutor := &mock.DBExecutor{
|
||||
SyncSatisfierFn: func(string) mock.IPackage { return nil },
|
||||
PackagesFromGroupFn: func(string) []mock.IPackage { return nil },
|
||||
LocalPackageFn: func(string) mock.IPackage { return nil },
|
||||
}
|
||||
|
||||
grapher := NewGrapher(dbExecutor, &mockaur.MockAUR{
|
||||
GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
|
||||
return []aur.Pkg{{Name: "aur-target", Version: "1"}}, nil
|
||||
},
|
||||
}, false, false, false, false, false, logger)
|
||||
|
||||
graph, err := grapher.GraphFromTargets(context.Background(), nil, []string{"aur-target"})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, AUR, graph.GetNodeInfo("aur-target").Value.Source)
|
||||
}
|
||||
|
||||
func TestGrapher_GraphFromAURNeededSkipsUpToDate(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
logger := text.NewLogger(io.Discard, io.Discard, strings.NewReader(""), true, "test")
|
||||
dbExecutor := &mock.DBExecutor{
|
||||
LocalPackageFn: func(name string) mock.IPackage {
|
||||
return &mock.Package{
|
||||
PName: name,
|
||||
PVersion: "2",
|
||||
PReason: dyalpm.PkgReasonExplicit,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
grapher := NewGrapher(dbExecutor, &mockaur.MockAUR{
|
||||
GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
|
||||
return []aur.Pkg{{
|
||||
Name: "needless",
|
||||
Version: "1",
|
||||
}}, nil
|
||||
},
|
||||
}, false, false, false, false, true, logger)
|
||||
|
||||
graph, err := grapher.GraphFromAUR(context.Background(), nil, []string{"needless"})
|
||||
require.NoError(t, err)
|
||||
require.False(t, graph.Exists("needless"))
|
||||
}
|
||||
|
||||
func TestGrapher_GraphFromAURNotFoundReturnsErr(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
logger := text.NewLogger(io.Discard, io.Discard, strings.NewReader(""), true, "test")
|
||||
grapher := NewGrapher(&mock.DBExecutor{}, &mockaur.MockAUR{
|
||||
GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
|
||||
return nil, nil
|
||||
},
|
||||
}, false, false, false, false, false, logger)
|
||||
|
||||
graph, err := grapher.GraphFromAUR(context.Background(), nil, []string{"ghost"})
|
||||
var targetNotFound *query.ErrTargetNotFound
|
||||
require.ErrorAs(t, err, &targetNotFound)
|
||||
require.NotNil(t, graph)
|
||||
require.False(t, graph.Exists("ghost"))
|
||||
}
|
||||
|
||||
func TestGrapher_GraphFromSrcInfosSinglePkg(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
logger := text.NewLogger(io.Discard, io.Discard, strings.NewReader(""), true, "test")
|
||||
dbExecutor := &mock.DBExecutor{
|
||||
LocalPackageFn: func(string) mock.IPackage { return nil },
|
||||
AlpmArchitecturesFn: func() ([]string, error) {
|
||||
return []string{"x86_64"}, nil
|
||||
},
|
||||
}
|
||||
|
||||
grapher := NewGrapher(dbExecutor, &mockaur.MockAUR{}, false, false, false, false, false, logger)
|
||||
graph, err := grapher.GraphFromSrcInfos(context.Background(), nil, map[string]*gosrc.Srcinfo{
|
||||
"foo": {
|
||||
PackageBase: gosrc.PackageBase{
|
||||
Pkgbase: "foo",
|
||||
Pkgver: "1",
|
||||
},
|
||||
Packages: []gosrc.Package{
|
||||
{
|
||||
Pkgname: "foo",
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
info := graph.GetNodeInfo("foo")
|
||||
require.NotNil(t, info)
|
||||
require.Equal(t, SrcInfo, info.Value.Source)
|
||||
}
|
||||
|
||||
func TestGrapher_FindDepsFromAURSatisfiesMissingAndErrorPaths(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
logger := text.NewLogger(io.Discard, io.Discard, strings.NewReader(""), true, "test")
|
||||
dbExecutor := &mock.DBExecutor{
|
||||
LocalSatisfierExistsFn: func(string) bool { return false },
|
||||
SyncSatisfierFn: func(string) mock.IPackage { return nil },
|
||||
}
|
||||
|
||||
grapher := NewGrapher(dbExecutor, &mockaur.MockAUR{
|
||||
GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
|
||||
return []aur.Pkg{
|
||||
{
|
||||
Name: "dep-provider",
|
||||
Version: "2.0",
|
||||
Provides: []string{
|
||||
"dep-lib",
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
}, false, false, false, false, false, logger)
|
||||
|
||||
graph := NewGraph()
|
||||
graph.AddNode("root")
|
||||
graph.AddProvides("dep-lib", &dyalpm.Depend{Name: "dep-lib", Version: "2.0"}, "dep-provider")
|
||||
deps := mapset.NewThreadUnsafeSet("dep-lib")
|
||||
found := grapher.findDepsFromAUR(context.Background(), graph, "root", deps)
|
||||
require.Len(t, found, 1)
|
||||
}
|
||||
@@ -29,6 +29,8 @@ import (
|
||||
// This validates that the RPC metadata is correctly parsed and dependencies
|
||||
// are properly resolved without needing PKGBUILD parsing.
|
||||
func TestGrapher_ReliableParser_AWSCliGit(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockDB := &mock.DBExecutor{
|
||||
SyncPackageFn: func(string) mock.IPackage { return nil },
|
||||
PackagesFromGroupFn: func(string) []mock.IPackage { return []mock.IPackage{} },
|
||||
@@ -93,36 +95,42 @@ func TestGrapher_ReliableParser_AWSCliGit(t *testing.T) {
|
||||
return []aur.Pkg{}, nil
|
||||
}}
|
||||
|
||||
t.Run("parses aws-cli-git with all its dependencies", func(t *testing.T) {
|
||||
t.Run("parses aws-cli-git with all its dependencies", func(td *testing.T) {
|
||||
td.Parallel()
|
||||
|
||||
g := NewGrapher(mockDB, mockAUR, false, true, false, false, false,
|
||||
text.NewLogger(io.Discard, io.Discard, &os.File{}, true, "test"))
|
||||
got, err := g.GraphFromTargets(context.Background(), nil, []string{"aws-cli-git"})
|
||||
require.NoError(t, err)
|
||||
require.NoError(td, err)
|
||||
layers := got.TopoSortedLayers(nil)
|
||||
|
||||
require.NotEmpty(t, layers)
|
||||
require.Contains(t, layers[0], "aws-cli-git")
|
||||
require.Equal(t, "1.27.145.r11217.g5885ee4dc-1", layers[0]["aws-cli-git"].Version)
|
||||
require.Equal(t, "aws-cli-git", *layers[0]["aws-cli-git"].AURBase)
|
||||
require.Equal(t, Explicit, layers[0]["aws-cli-git"].Reason)
|
||||
require.Equal(t, AUR, layers[0]["aws-cli-git"].Source)
|
||||
require.NotEmpty(td, layers)
|
||||
require.Contains(td, layers[0], "aws-cli-git")
|
||||
require.Equal(td, "1.27.145.r11217.g5885ee4dc-1", layers[0]["aws-cli-git"].Version)
|
||||
require.Equal(td, "aws-cli-git", *layers[0]["aws-cli-git"].AURBase)
|
||||
require.Equal(td, Explicit, layers[0]["aws-cli-git"].Reason)
|
||||
require.Equal(td, AUR, layers[0]["aws-cli-git"].Source)
|
||||
})
|
||||
|
||||
t.Run("validates provides field for aws-cli", func(t *testing.T) {
|
||||
t.Run("validates provides field for aws-cli", func(td *testing.T) {
|
||||
td.Parallel()
|
||||
|
||||
g := NewGrapher(mockDB, mockAUR, false, true, false, false, false,
|
||||
text.NewLogger(io.Discard, io.Discard, &os.File{}, true, "test"))
|
||||
got, err := g.GraphFromTargets(context.Background(), nil, []string{"aws-cli-git"})
|
||||
require.NoError(t, err)
|
||||
require.NoError(td, err)
|
||||
layers := got.TopoSortedLayers(nil)
|
||||
|
||||
require.NotEmpty(t, layers)
|
||||
require.Contains(t, layers[0], "aws-cli-git")
|
||||
require.NotEmpty(td, layers)
|
||||
require.Contains(td, layers[0], "aws-cli-git")
|
||||
})
|
||||
}
|
||||
|
||||
// TestGrapher_ReliableSolver_LiriDesktopGit tests the dependency solver
|
||||
// with complex dependency chains like liri-desktop-git metapackage.
|
||||
func TestGrapher_ReliableSolver_LiriDesktopGit(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockDB := &mock.DBExecutor{
|
||||
SyncPackageFn: func(string) mock.IPackage { return nil },
|
||||
PackagesFromGroupFn: func(string) []mock.IPackage { return []mock.IPackage{} },
|
||||
@@ -181,11 +189,13 @@ func TestGrapher_ReliableSolver_LiriDesktopGit(t *testing.T) {
|
||||
return []aur.Pkg{}, nil
|
||||
}}
|
||||
|
||||
t.Run("liri-desktop-git pulls all dependencies", func(t *testing.T) {
|
||||
t.Run("liri-desktop-git pulls all dependencies", func(td *testing.T) {
|
||||
td.Parallel()
|
||||
|
||||
g := NewGrapher(mockDB, mockAUR, false, true, false, false, false,
|
||||
text.NewLogger(io.Discard, io.Discard, &os.File{}, true, "test"))
|
||||
got, err := g.GraphFromTargets(context.Background(), nil, []string{"liri-desktop-git"})
|
||||
require.NoError(t, err)
|
||||
require.NoError(td, err)
|
||||
layers := got.TopoSortedLayers(nil)
|
||||
|
||||
totalPkgs := 0
|
||||
@@ -193,19 +203,21 @@ func TestGrapher_ReliableSolver_LiriDesktopGit(t *testing.T) {
|
||||
totalPkgs += len(layer)
|
||||
}
|
||||
// 6 packages: liri-desktop-git + 4 deps + liri-cmake-shared-git (makedep)
|
||||
require.Equal(t, 6, totalPkgs)
|
||||
require.Contains(t, layers[0], "liri-desktop-git")
|
||||
require.Equal(t, Explicit, layers[0]["liri-desktop-git"].Reason)
|
||||
require.Equal(td, 6, totalPkgs)
|
||||
require.Contains(td, layers[0], "liri-desktop-git")
|
||||
require.Equal(td, Explicit, layers[0]["liri-desktop-git"].Reason)
|
||||
})
|
||||
|
||||
t.Run("complex dependency chain resolves in correct order", func(t *testing.T) {
|
||||
t.Run("complex dependency chain resolves in correct order", func(td *testing.T) {
|
||||
td.Parallel()
|
||||
|
||||
g := NewGrapher(mockDB, mockAUR, false, true, false, false, false,
|
||||
text.NewLogger(io.Discard, io.Discard, &os.File{}, true, "test"))
|
||||
got, err := g.GraphFromTargets(context.Background(), nil, []string{"liri-desktop-git"})
|
||||
require.NoError(t, err)
|
||||
require.NoError(td, err)
|
||||
layers := got.TopoSortedLayers(nil)
|
||||
|
||||
require.Contains(t, layers[0], "liri-desktop-git")
|
||||
require.Contains(td, layers[0], "liri-desktop-git")
|
||||
|
||||
allPkgs := make(map[string]bool)
|
||||
for _, layer := range layers {
|
||||
@@ -213,18 +225,20 @@ func TestGrapher_ReliableSolver_LiriDesktopGit(t *testing.T) {
|
||||
allPkgs[pkg] = true
|
||||
}
|
||||
}
|
||||
require.True(t, allPkgs["liri-desktop-git"])
|
||||
require.True(t, allPkgs["liri-shell-git"])
|
||||
require.True(t, allPkgs["liri-settings-git"])
|
||||
require.True(t, allPkgs["fluid-git"])
|
||||
require.True(t, allPkgs["libliri-git"])
|
||||
require.True(t, allPkgs["liri-cmake-shared-git"]) // makedepend
|
||||
require.True(td, allPkgs["liri-desktop-git"])
|
||||
require.True(td, allPkgs["liri-shell-git"])
|
||||
require.True(td, allPkgs["liri-settings-git"])
|
||||
require.True(td, allPkgs["fluid-git"])
|
||||
require.True(td, allPkgs["libliri-git"])
|
||||
require.True(td, allPkgs["liri-cmake-shared-git"]) // makedepend
|
||||
})
|
||||
}
|
||||
|
||||
// TestGrapher_SplitPackages_Clion tests split packages where multiple packages
|
||||
// come from the same package base, ensuring no rebuilding or reinstalling multiple times.
|
||||
func TestGrapher_SplitPackages_Clion(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockDB := &mock.DBExecutor{
|
||||
SyncPackageFn: func(string) mock.IPackage { return nil },
|
||||
PackagesFromGroupFn: func(string) []mock.IPackage { return []mock.IPackage{} },
|
||||
@@ -340,6 +354,8 @@ func TestGrapher_SplitPackages_Clion(t *testing.T) {
|
||||
// TestGrapher_SplitPackages_SamsungUnifiedDriver tests split packages where
|
||||
// packages depend on another package from the same package base.
|
||||
func TestGrapher_SplitPackages_SamsungUnifiedDriver(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockDB := &mock.DBExecutor{
|
||||
SyncPackageFn: func(string) mock.IPackage { return nil },
|
||||
PackagesFromGroupFn: func(string) []mock.IPackage { return []mock.IPackage{} },
|
||||
@@ -473,6 +489,8 @@ func TestGrapher_SplitPackages_SamsungUnifiedDriver(t *testing.T) {
|
||||
|
||||
// TestGrapher_SplitPackages_NX tests independent split packages like nxproxy and nxagent.
|
||||
func TestGrapher_SplitPackages_NX(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockDB := &mock.DBExecutor{
|
||||
SyncPackageFn: func(string) mock.IPackage { return nil },
|
||||
PackagesFromGroupFn: func(string) []mock.IPackage { return []mock.IPackage{} },
|
||||
@@ -637,6 +655,8 @@ func TestGrapher_SplitPackages_NX(t *testing.T) {
|
||||
// TestGrapher_SplitPackages_ReversedOrder tests that split packages resolve
|
||||
// correctly regardless of the order they are specified in.
|
||||
func TestGrapher_SplitPackages_ReversedOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockDB := &mock.DBExecutor{
|
||||
SyncPackageFn: func(string) mock.IPackage { return nil },
|
||||
PackagesFromGroupFn: func(string) []mock.IPackage { return []mock.IPackage{} },
|
||||
@@ -696,6 +716,8 @@ func TestGrapher_SplitPackages_ReversedOrder(t *testing.T) {
|
||||
// TestGrapher_MultipleInstallInfo ensures that when the same package appears as
|
||||
// both explicit target and dependency, the explicit reason takes precedence.
|
||||
func TestGrapher_MultipleInstallInfo(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockDB := &mock.DBExecutor{
|
||||
SyncPackageFn: func(string) mock.IPackage { return nil },
|
||||
PackagesFromGroupFn: func(string) []mock.IPackage { return []mock.IPackage{} },
|
||||
@@ -755,6 +777,8 @@ func TestGrapher_MultipleInstallInfo(t *testing.T) {
|
||||
|
||||
// TestGrapher_VersionedDependencies tests proper handling of versioned dependencies.
|
||||
func TestGrapher_VersionedDependencies(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockDB := &mock.DBExecutor{
|
||||
SyncPackageFn: func(string) mock.IPackage { return nil },
|
||||
PackagesFromGroupFn: func(string) []mock.IPackage { return []mock.IPackage{} },
|
||||
|
||||
@@ -47,6 +47,8 @@ func getFromFile(t testing.TB, filePath string) mockaur.GetFunc {
|
||||
}
|
||||
|
||||
func TestGrapher_findDepsFromAUR_logsRequiredByForMissingDep(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockDB := &mock.DBExecutor{}
|
||||
mockAUR := &mockaur.MockAUR{GetFn: func(ctx context.Context, query *aurc.Query) ([]aur.Pkg, error) {
|
||||
return []aur.Pkg{}, nil
|
||||
@@ -73,6 +75,8 @@ func TestGrapher_findDepsFromAUR_logsRequiredByForMissingDep(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGrapher_GraphFromTargets_jellyfin(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockDB := &mock.DBExecutor{
|
||||
SyncPackageFn: func(string) mock.IPackage { return nil },
|
||||
SyncSatisfierFn: func(s string) mock.IPackage {
|
||||
@@ -242,6 +246,8 @@ func TestGrapher_GraphFromTargets_jellyfin(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGrapher_GraphProvides_androidsdk(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockDB := &mock.DBExecutor{
|
||||
SyncPackageFn: func(string) mock.IPackage { return nil },
|
||||
SyncSatisfierFn: func(s string) mock.IPackage {
|
||||
@@ -356,6 +362,8 @@ func TestGrapher_GraphProvides_androidsdk(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGrapher_GraphFromAUR_Deps_ceph_bin(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockDB := &mock.DBExecutor{
|
||||
SyncPackageFn: func(string) mock.IPackage { return nil },
|
||||
PackagesFromGroupFn: func(string) []mock.IPackage { return []mock.IPackage{} },
|
||||
@@ -558,6 +566,8 @@ func TestGrapher_GraphFromAUR_Deps_ceph_bin(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGrapher_GraphFromAUR_Deps_gourou(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockDB := &mock.DBExecutor{
|
||||
SyncPackageFn: func(string) mock.IPackage { return nil },
|
||||
PackagesFromGroupFn: func(string) []mock.IPackage { return []mock.IPackage{} },
|
||||
@@ -703,6 +713,8 @@ func TestGrapher_GraphFromAUR_Deps_gourou(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGrapher_GraphFromTargets_ReinstalledDeps(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockDB := &mock.DBExecutor{
|
||||
SyncPackageFn: func(string) mock.IPackage { return nil },
|
||||
PackagesFromGroupFn: func(string) []mock.IPackage { return []mock.IPackage{} },
|
||||
@@ -841,6 +853,8 @@ func TestGrapher_GraphFromTargets_ReinstalledDeps(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGrapher_GraphFromTargets_TargetNotFound(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockDB := &mock.DBExecutor{
|
||||
SyncSatisfierFn: func(string) mock.IPackage { return nil },
|
||||
PackagesFromGroupFn: func(string) []mock.IPackage { return nil },
|
||||
@@ -909,6 +923,8 @@ func TestGrapher_GraphFromTargets_TargetNotFound(t *testing.T) {
|
||||
// TestGrapher_GraphFromAUR_SplitPkgInternalDeps tests split packages where
|
||||
// packages from the same base depend on each other (like gstreamer-git).
|
||||
func TestGrapher_GraphFromAUR_SplitPkgInternalDeps(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockDB := &mock.DBExecutor{
|
||||
SyncPackageFn: func(string) mock.IPackage { return nil },
|
||||
PackagesFromGroupFn: func(string) []mock.IPackage { return []mock.IPackage{} },
|
||||
@@ -1089,6 +1105,8 @@ func TestGrapher_GraphFromAUR_SplitPkgInternalDeps(t *testing.T) {
|
||||
|
||||
// TestGrapher_GraphFromAUR_CheckDeps tests packages with CheckDepends.
|
||||
func TestGrapher_GraphFromAUR_CheckDeps(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockDB := &mock.DBExecutor{
|
||||
SyncPackageFn: func(string) mock.IPackage { return nil },
|
||||
PackagesFromGroupFn: func(string) []mock.IPackage { return []mock.IPackage{} },
|
||||
@@ -1193,6 +1211,8 @@ func TestGrapher_GraphFromAUR_CheckDeps(t *testing.T) {
|
||||
// TestGrapher_GraphFromAUR_VirtualProvides tests packages that provide virtual packages
|
||||
// (like mesa-git providing vulkan-driver, opengl-driver).
|
||||
func TestGrapher_GraphFromAUR_VirtualProvides(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockDB := &mock.DBExecutor{
|
||||
SyncPackageFn: func(string) mock.IPackage { return nil },
|
||||
PackagesFromGroupFn: func(string) []mock.IPackage { return []mock.IPackage{} },
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
//go:build !integration
|
||||
// +build !integration
|
||||
|
||||
package dep
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/Jguer/aur"
|
||||
alpm "github.com/Jguer/dyalpm"
|
||||
gosrc "github.com/Morganamilo/go-srcinfo"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/Jguer/yay/v12/pkg/db"
|
||||
"github.com/Jguer/yay/v12/pkg/db/mock"
|
||||
mockaur "github.com/Jguer/yay/v12/pkg/dep/mock"
|
||||
"github.com/Jguer/yay/v12/pkg/dep/topo"
|
||||
"github.com/Jguer/yay/v12/pkg/text"
|
||||
)
|
||||
|
||||
func TestDepSplitDep(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
wantName string
|
||||
wantMod string
|
||||
wantDepVer string
|
||||
}{
|
||||
{name: "plain", input: "base", wantName: "base"},
|
||||
{name: "greater", input: "base>=1.0", wantName: "base", wantMod: ">=", wantDepVer: "1.0"},
|
||||
{name: "less", input: "base<2.0", wantName: "base", wantMod: "<", wantDepVer: "2.0"},
|
||||
{name: "equal", input: "base=1", wantName: "base", wantMod: "=", wantDepVer: "1"},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
name, mod, depVer := splitDep(tc.input)
|
||||
require.Equal(t, tc.wantName, name)
|
||||
require.Equal(t, tc.wantMod, mod)
|
||||
require.Equal(t, tc.wantDepVer, depVer)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDepSatisfies(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require.True(t, pkgSatisfies("linux", "1.0", "linux"))
|
||||
require.False(t, pkgSatisfies("linux", "1.0", "linux>=1.5"))
|
||||
require.True(t, pkgSatisfies("linux", "1.7", "linux>=1.5"))
|
||||
require.True(t, verSatisfies("1.5", "<=", "1.5"))
|
||||
require.False(t, verSatisfies("1.4", ">=", "1.5"))
|
||||
}
|
||||
|
||||
func TestProvideSatisfies(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require.True(t, provideSatisfies("dep=2.0", "dep>=1.0", "1.0"))
|
||||
require.True(t, provideSatisfies("dep", "dep>=1.0", "2.0"))
|
||||
require.False(t, provideSatisfies("dep", "dep>=3.0", "2.0"))
|
||||
require.False(t, provideSatisfies("other=2.0", "dep>=1.0", "2.0"))
|
||||
}
|
||||
|
||||
func TestSatisfiesAurProvides(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
pkg := &aur.Pkg{
|
||||
Name: "pkgbase",
|
||||
Version: "10",
|
||||
Provides: []string{
|
||||
"pkgbase",
|
||||
"oldpkg=1.2",
|
||||
},
|
||||
}
|
||||
|
||||
require.True(t, satisfiesAur("pkgbase>=10", pkg))
|
||||
require.True(t, satisfiesAur("oldpkg=1.2", pkg))
|
||||
require.False(t, satisfiesAur("oldpkg>=2", pkg))
|
||||
}
|
||||
|
||||
func TestTargetParsing(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
target := ToTarget("core/libpng>=1.6")
|
||||
require.Equal(t, "core", target.DB)
|
||||
require.Equal(t, "libpng", target.Name)
|
||||
require.Equal(t, ">=", target.Mod)
|
||||
require.Equal(t, "1.6", target.Version)
|
||||
|
||||
target = ToTarget("yay")
|
||||
require.Equal(t, "", target.DB)
|
||||
require.Equal(t, "yay", target.Name)
|
||||
require.Equal(t, "", target.Mod)
|
||||
require.Equal(t, "", target.Version)
|
||||
}
|
||||
|
||||
func TestGrapher_GraphSyncPkgAndUpgrade(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
logger := text.NewLogger(io.Discard, io.Discard, strings.NewReader(""), true, "test")
|
||||
|
||||
mockDb := &mock.DBExecutor{
|
||||
LocalPackageFn: func(s string) mock.IPackage {
|
||||
return &mock.Package{
|
||||
PName: "yay",
|
||||
PVersion: "1.0.0-1",
|
||||
PReason: alpm.PkgReasonDepend,
|
||||
PDB: mock.NewDB("core"),
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
grapher := NewGrapher(mockDb, &mockaur.MockAUR{}, false, false, false, false, false, logger)
|
||||
graph := grapher.GraphSyncPkg(context.TODO(), nil, &mock.Package{
|
||||
PName: "yay",
|
||||
PVersion: "1.2.0",
|
||||
PDB: mock.NewDB("core"),
|
||||
}, nil)
|
||||
|
||||
info := graph.GetNodeInfo("yay").Value
|
||||
require.NotNil(t, info)
|
||||
require.Equal(t, Dep, info.Reason)
|
||||
require.False(t, info.Upgrade)
|
||||
|
||||
upgraded := grapher.GraphSyncPkg(context.TODO(), nil, &mock.Package{
|
||||
PName: "yaysrc",
|
||||
PVersion: "2.0.0",
|
||||
PDB: mock.NewDB("core"),
|
||||
}, &db.SyncUpgrade{
|
||||
Package: &mock.Package{
|
||||
PName: "yaysrc",
|
||||
PDB: mock.NewDB("core"),
|
||||
},
|
||||
LocalVersion: "1.0.0",
|
||||
Reason: alpm.PkgReasonExplicit,
|
||||
})
|
||||
|
||||
upgradeInfo := upgraded.GetNodeInfo("yaysrc").Value
|
||||
require.NotNil(t, upgradeInfo)
|
||||
require.True(t, upgradeInfo.Upgrade)
|
||||
require.Equal(t, "1.0.0", upgradeInfo.LocalVersion)
|
||||
}
|
||||
|
||||
func TestGrapher_GraphSyncGroupAndValidateNodeInfo(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
grapher := NewGrapher(&mock.DBExecutor{}, &mockaur.MockAUR{}, false, false, false, false, false, text.NewLogger(io.Discard, io.Discard, strings.NewReader(""), true, "test"))
|
||||
|
||||
graph := grapher.GraphSyncGroup(context.TODO(), nil, "editors", "community")
|
||||
groupInfo := graph.GetNodeInfo("editors").Value
|
||||
require.NotNil(t, groupInfo)
|
||||
require.True(t, groupInfo.IsGroup)
|
||||
require.Equal(t, "community", *groupInfo.SyncDBName)
|
||||
|
||||
target := "grouped"
|
||||
graph.SetNodeInfo(target, &topo.NodeInfo[*InstallInfo]{Value: &InstallInfo{Reason: Explicit}})
|
||||
grapher.ValidateAndSetNodeInfo(graph, target, &topo.NodeInfo[*InstallInfo]{Value: &InstallInfo{Reason: MakeDep}})
|
||||
require.Equal(t, Explicit, graph.GetNodeInfo(target).Value.Reason)
|
||||
|
||||
graph.SetNodeInfo(target, &topo.NodeInfo[*InstallInfo]{Value: &InstallInfo{Reason: Explicit, Upgrade: true}})
|
||||
grapher.ValidateAndSetNodeInfo(graph, target, &topo.NodeInfo[*InstallInfo]{Value: &InstallInfo{Reason: Explicit, Upgrade: false}})
|
||||
require.True(t, graph.GetNodeInfo(target).Value.Upgrade)
|
||||
}
|
||||
|
||||
func TestProvideMenuAndMakeAURPKGFromSrcinfo(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
grapher := NewGrapher(&mock.DBExecutor{}, &mockaur.MockAUR{}, false, true, false, false, false, text.NewLogger(io.Discard, io.Discard, strings.NewReader(""), true, "test"))
|
||||
opts := []aur.Pkg{
|
||||
{Name: "aur-pkg-one", Version: "1"},
|
||||
{Name: "aur-pkg-two", Version: "2"},
|
||||
}
|
||||
|
||||
require.Equal(t, "aur-pkg-one", grapher.provideMenu("dep", opts).Name)
|
||||
|
||||
grapherNoConfirm := NewGrapher(&mock.DBExecutor{}, &mockaur.MockAUR{}, false, false, false, false, false,
|
||||
text.NewLogger(io.Discard, io.Discard, strings.NewReader("2\n"), false, "test"))
|
||||
require.Equal(t, "aur-pkg-two", grapherNoConfirm.provideMenu("dep", opts).Name)
|
||||
}
|
||||
|
||||
func TestMakeAURPKGFromSrcinfo(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assertErr := errors.New("arch error")
|
||||
|
||||
dbExecutor := &mock.DBExecutor{
|
||||
AlpmArchitecturesFn: func() ([]string, error) {
|
||||
return []string{"x86_64"}, nil
|
||||
},
|
||||
}
|
||||
|
||||
srcinfo := &gosrc.Srcinfo{
|
||||
PackageBase: gosrc.PackageBase{
|
||||
Pkgbase: "yay",
|
||||
},
|
||||
Package: gosrc.Package{
|
||||
Depends: []gosrc.ArchString{
|
||||
{Arch: "x86_64", Value: "xdep"},
|
||||
{Arch: "arm", Value: "ignored"},
|
||||
},
|
||||
},
|
||||
Packages: []gosrc.Package{
|
||||
{
|
||||
Pkgname: "yay",
|
||||
Depends: []gosrc.ArchString{
|
||||
{Value: "pkgdep"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
pkgs, err := makeAURPKGFromSrcinfo(dbExecutor, srcinfo)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, pkgs, 1)
|
||||
require.Equal(t, []string{"pkgdep", "xdep"}, pkgs[0].Depends)
|
||||
|
||||
dbFail := &mock.DBExecutor{
|
||||
AlpmArchitecturesFn: func() ([]string, error) {
|
||||
return nil, assertErr
|
||||
},
|
||||
}
|
||||
|
||||
_, err = makeAURPKGFromSrcinfo(dbFail, srcinfo)
|
||||
require.Error(t, err)
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
//go:build !integration
|
||||
// +build !integration
|
||||
|
||||
package topo
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestGraph_AddNodeAndLenAndExists(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
graph := New[string, struct{}]()
|
||||
graph.AddNode("core")
|
||||
graph.AddNode("extra")
|
||||
graph.AddNode("core")
|
||||
|
||||
require.Equal(t, 2, graph.Len())
|
||||
require.True(t, graph.Exists("core"))
|
||||
require.False(t, graph.Exists("missing"))
|
||||
}
|
||||
|
||||
func TestGraph_DependOnRejectsInvalidEdges(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
graph := New[string, struct{}]()
|
||||
require.EqualError(t, ErrSelfReferential, graph.DependOn("a", "a").Error())
|
||||
|
||||
require.NoError(t, graph.DependOn("a", "b"))
|
||||
require.EqualError(t, ErrCircular, graph.DependOn("b", "a").Error())
|
||||
require.NoError(t, graph.DependOn("c", "b"))
|
||||
}
|
||||
|
||||
func TestGraph_ForEachAndForEachError(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
graph := New[string, int]()
|
||||
graph.AddNode("one")
|
||||
graph.SetNodeInfo("one", &NodeInfo[int]{Value: 1})
|
||||
graph.AddNode("two")
|
||||
graph.SetNodeInfo("two", &NodeInfo[int]{Value: 2})
|
||||
|
||||
var seen []string
|
||||
err := graph.ForEach(func(node string, value int) error {
|
||||
seen = append(seen, node)
|
||||
return nil
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, seen, 2)
|
||||
|
||||
err = graph.ForEach(func(node string, value int) error {
|
||||
if node == "one" {
|
||||
return errors.New("stop")
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
require.EqualError(t, err, "stop")
|
||||
}
|
||||
|
||||
func TestGraph_TopoSortedLayers_WithCheckFn(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
graph := New[string, int]()
|
||||
graph.AddNode("root")
|
||||
graph.AddNode("leaf")
|
||||
require.NoError(t, graph.DependOn("leaf", "root"))
|
||||
|
||||
called := 0
|
||||
layers := graph.TopoSortedLayers(func(node string, value int) error {
|
||||
called++
|
||||
return nil
|
||||
})
|
||||
require.Equal(t, 2, called)
|
||||
require.Len(t, layers, 2)
|
||||
require.Equal(t, map[string]int{"root": 0}, layers[0])
|
||||
|
||||
called = 0
|
||||
layers = graph.TopoSortedLayers(func(node string, value int) error {
|
||||
called++
|
||||
|
||||
if strings.Contains(node, "leaf") {
|
||||
return errors.New("halt")
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
require.Nil(t, layers)
|
||||
require.Equal(t, 2, called)
|
||||
}
|
||||
|
||||
func TestGraph_PrunedNodes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
graph := New[string, int]()
|
||||
require.NoError(t, graph.DependOn("a", "b"))
|
||||
require.NoError(t, graph.DependOn("c", "a"))
|
||||
|
||||
pruned := graph.Prune("a")
|
||||
require.Len(t, pruned, 3)
|
||||
require.Equal(t, 0, graph.Len())
|
||||
require.False(t, graph.Exists("a"))
|
||||
require.False(t, graph.Exists("b"))
|
||||
require.False(t, graph.Exists("c"))
|
||||
|
||||
set := make(map[string]struct{}, len(pruned))
|
||||
for _, node := range pruned {
|
||||
set[node] = struct{}{}
|
||||
}
|
||||
require.Contains(t, set, "a")
|
||||
require.Contains(t, set, "b")
|
||||
require.Contains(t, set, "c")
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
//go:build integration
|
||||
// +build integration
|
||||
|
||||
package download
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/Jguer/yay/v12/pkg/settings/exe"
|
||||
"github.com/Jguer/yay/v12/pkg/text"
|
||||
)
|
||||
|
||||
// WHEN some AUR bases exist and others are fresh
|
||||
// THEN AURPKGBUILDRepos returns mixed newClone flags
|
||||
func TestIntegrationAURPKGBUILDReposMixedCloneAndPull(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
testLogger := text.NewLogger(os.Stdout, os.Stderr, strings.NewReader(""), true, "test")
|
||||
cmdRunner := &exe.OSRunner{Log: testLogger}
|
||||
cmdBuilder := &exe.CmdBuilder{
|
||||
Runner: cmdRunner,
|
||||
GitBin: "git",
|
||||
GitFlags: []string{},
|
||||
Log: testLogger,
|
||||
}
|
||||
targets := []string{"yay-bin", "yay-git"}
|
||||
|
||||
cloned1, err1 := AURPKGBUILDRepos(context.Background(), cmdBuilder, testLogger.Child("dl"),
|
||||
targets, "https://aur.archlinux.org", dir, false)
|
||||
require.NoError(t, err1)
|
||||
assert.EqualValues(t, map[string]bool{"yay-bin": true, "yay-git": true}, cloned1)
|
||||
|
||||
cloned2, err2 := AURPKGBUILDRepos(context.Background(), cmdBuilder, testLogger.Child("dl2"),
|
||||
targets, "https://aur.archlinux.org", dir, false)
|
||||
require.NoError(t, err2)
|
||||
assert.EqualValues(t, map[string]bool{"yay-bin": false, "yay-git": false}, cloned2)
|
||||
}
|
||||
|
||||
func TestIntegrationGetPackageScannerGzip(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
gw := gzip.NewWriter(&buf)
|
||||
_, err := gw.Write([]byte("line1\nline2\n"))
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, gw.Close())
|
||||
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path != "/packages.gz" {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = w.Write(buf.Bytes())
|
||||
}))
|
||||
t.Cleanup(srv.Close)
|
||||
|
||||
testLogger := text.NewLogger(io.Discard, io.Discard, strings.NewReader(""), true, "test")
|
||||
sc, err := GetPackageScanner(context.Background(), srv.Client(), srv.URL, testLogger)
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() { assert.NoError(t, sc.Close()) })
|
||||
|
||||
var lines []string
|
||||
for sc.Scan() {
|
||||
lines = append(lines, sc.Text())
|
||||
}
|
||||
require.NoError(t, sc.Err())
|
||||
assert.Equal(t, []string{"line1", "line2"}, lines)
|
||||
}
|
||||
|
||||
func TestIntegrationGetPackageScannerRawFallback(t *testing.T) {
|
||||
body := []byte("alpha\nbeta\n")
|
||||
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path != "/packages.gz" {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = w.Write(body)
|
||||
}))
|
||||
t.Cleanup(srv.Close)
|
||||
|
||||
testLogger := text.NewLogger(io.Discard, io.Discard, strings.NewReader(""), true, "test")
|
||||
sc, err := GetPackageScanner(context.Background(), srv.Client(), srv.URL, testLogger)
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() { assert.NoError(t, sc.Close()) })
|
||||
|
||||
var lines []string
|
||||
for sc.Scan() {
|
||||
lines = append(lines, sc.Text())
|
||||
}
|
||||
require.NoError(t, sc.Err())
|
||||
assert.Equal(t, []string{"alpha", "beta"}, lines)
|
||||
}
|
||||
|
||||
func TestIntegrationGetPackageScannerHTTPError(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "gone", http.StatusNotFound)
|
||||
}))
|
||||
t.Cleanup(srv.Close)
|
||||
|
||||
testLogger := text.NewLogger(io.Discard, io.Discard, strings.NewReader(""), true, "test")
|
||||
sc, err := GetPackageScanner(context.Background(), srv.Client(), srv.URL, testLogger)
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, sc)
|
||||
}
|
||||
@@ -5,6 +5,7 @@ package download
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
@@ -20,6 +21,19 @@ import (
|
||||
"github.com/Jguer/yay/v12/pkg/text"
|
||||
)
|
||||
|
||||
func integrationCmdBuilder(t *testing.T) (*text.Logger, *exe.CmdBuilder) {
|
||||
t.Helper()
|
||||
testLogger := text.NewLogger(os.Stdout, os.Stderr, strings.NewReader(""), true, "test")
|
||||
cmdRunner := &exe.OSRunner{Log: testLogger}
|
||||
cmdBuilder := &exe.CmdBuilder{
|
||||
Runner: cmdRunner,
|
||||
GitBin: "git",
|
||||
GitFlags: []string{},
|
||||
Log: testLogger,
|
||||
}
|
||||
return testLogger, cmdBuilder
|
||||
}
|
||||
|
||||
func TestIntegrationPKGBUILDReposDefinedDBClone(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
|
||||
@@ -104,3 +118,160 @@ func TestIntegrationPKGBUILDFull(t *testing.T) {
|
||||
assert.NotEmpty(t, fetched[target])
|
||||
}
|
||||
}
|
||||
|
||||
// WHEN checkouts already exist and force is false
|
||||
// THEN git pull runs and newClone is false for each target
|
||||
func TestIntegrationPKGBUILDReposPullWhenExists(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
mockClient := &mockaur.MockAUR{
|
||||
GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
|
||||
return []aur.Pkg{{}}, nil
|
||||
},
|
||||
}
|
||||
targets := []string{"core/linux", "yay-bin"}
|
||||
testLogger, cmdBuilder := integrationCmdBuilder(t)
|
||||
searcher := &testDBSearcher{absPackagesDB: map[string]string{"linux": "core"}}
|
||||
|
||||
cloned1, err1 := PKGBUILDRepos(context.Background(), searcher, mockClient,
|
||||
cmdBuilder, testLogger.Child("test"),
|
||||
targets, parser.ModeAny, "https://aur.archlinux.org", dir, false)
|
||||
assert.NoError(t, err1)
|
||||
assert.EqualValues(t, map[string]bool{"core/linux": true, "yay-bin": true}, cloned1)
|
||||
|
||||
cloned2, err2 := PKGBUILDRepos(context.Background(), searcher, mockClient,
|
||||
cmdBuilder, testLogger.Child("test2"),
|
||||
targets, parser.ModeAny, "https://aur.archlinux.org", dir, false)
|
||||
assert.NoError(t, err2)
|
||||
assert.EqualValues(t, map[string]bool{"core/linux": false, "yay-bin": false}, cloned2)
|
||||
}
|
||||
|
||||
// WHEN checkouts already exist and force is true
|
||||
// THEN directories are removed and fresh clones return newClone true
|
||||
func TestIntegrationPKGBUILDReposForceRecloneAfterClone(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
mockClient := &mockaur.MockAUR{
|
||||
GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
|
||||
return []aur.Pkg{{}}, nil
|
||||
},
|
||||
}
|
||||
targets := []string{"core/linux", "yay-bin"}
|
||||
testLogger, cmdBuilder := integrationCmdBuilder(t)
|
||||
searcher := &testDBSearcher{absPackagesDB: map[string]string{"linux": "core"}}
|
||||
|
||||
cloned1, err1 := PKGBUILDRepos(context.Background(), searcher, mockClient,
|
||||
cmdBuilder, testLogger.Child("test"),
|
||||
targets, parser.ModeAny, "https://aur.archlinux.org", dir, false)
|
||||
assert.NoError(t, err1)
|
||||
assert.EqualValues(t, map[string]bool{"core/linux": true, "yay-bin": true}, cloned1)
|
||||
|
||||
cloned2, err2 := PKGBUILDRepos(context.Background(), searcher, mockClient,
|
||||
cmdBuilder, testLogger.Child("test2"),
|
||||
targets, parser.ModeAny, "https://aur.archlinux.org", dir, true)
|
||||
assert.NoError(t, err2)
|
||||
assert.EqualValues(t, map[string]bool{"core/linux": true, "yay-bin": true}, cloned2)
|
||||
}
|
||||
|
||||
// WHEN mode is repo-only
|
||||
// THEN only sync db targets are cloned; bare AUR names are skipped
|
||||
func TestIntegrationPKGBUILDReposModeRepoOnlyRepo(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
mockClient := &mockaur.MockAUR{
|
||||
GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
|
||||
return []aur.Pkg{}, nil
|
||||
},
|
||||
}
|
||||
targets := []string{"linux", "yay-bin", "yay-git"}
|
||||
testLogger, cmdBuilder := integrationCmdBuilder(t)
|
||||
searcher := &testDBSearcher{absPackagesDB: map[string]string{"linux": "core"}}
|
||||
|
||||
cloned, err := PKGBUILDRepos(context.Background(), searcher, mockClient,
|
||||
cmdBuilder, testLogger.Child("test"),
|
||||
targets, parser.ModeRepo, "https://aur.archlinux.org", dir, false)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, map[string]bool{"linux": true}, cloned)
|
||||
}
|
||||
|
||||
// WHEN a repo/db-qualified target is wrong for the package
|
||||
// THEN that target is skipped and AUR targets still clone
|
||||
func TestIntegrationPKGBUILDReposWrongDBSkipsTarget(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
mockClient := &mockaur.MockAUR{
|
||||
GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
|
||||
return []aur.Pkg{{}}, nil
|
||||
},
|
||||
}
|
||||
targets := []string{"extra/yay", "yay-bin"}
|
||||
testLogger, cmdBuilder := integrationCmdBuilder(t)
|
||||
searcher := &testDBSearcher{absPackagesDB: map[string]string{"yay": "core"}}
|
||||
|
||||
cloned, err := PKGBUILDRepos(context.Background(), searcher, mockClient,
|
||||
cmdBuilder, testLogger.Child("test"),
|
||||
targets, parser.ModeAny, "https://aur.archlinux.org", dir, false)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, map[string]bool{"yay-bin": true}, cloned)
|
||||
}
|
||||
|
||||
// WHEN mode is repo-only
|
||||
// THEN PKGBUILD bytes are only fetched for repo targets
|
||||
func TestIntegrationPKGBUILDsModeRepoOnlyRepo(t *testing.T) {
|
||||
mockClient := &mockaur.MockAUR{
|
||||
GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
|
||||
return []aur.Pkg{}, nil
|
||||
},
|
||||
}
|
||||
targets := []string{"core/linux", "yay-bin"}
|
||||
testLogger, _ := integrationCmdBuilder(t)
|
||||
searcher := &testDBSearcher{absPackagesDB: map[string]string{"linux": "core"}}
|
||||
|
||||
fetched, err := PKGBUILDs(searcher, mockClient, &http.Client{}, testLogger.Child("test"),
|
||||
targets, "https://aur.archlinux.org", parser.ModeRepo)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, fetched, 1)
|
||||
assert.Contains(t, fetched, "core/linux")
|
||||
assert.NotEmpty(t, fetched["core/linux"])
|
||||
}
|
||||
|
||||
// WHEN AUR RPC fails for an AUR target
|
||||
// THEN repo PKGBUILD still downloads and error aggregates only failed fetches
|
||||
func TestIntegrationPKGBUILDsAURRPCErrorStillFetchesRepo(t *testing.T) {
|
||||
mockClient := &mockaur.MockAUR{
|
||||
GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
|
||||
return nil, errors.New("aur rpc unavailable")
|
||||
},
|
||||
}
|
||||
targets := []string{"core/linux", "yay-git"}
|
||||
testLogger, _ := integrationCmdBuilder(t)
|
||||
searcher := &testDBSearcher{absPackagesDB: map[string]string{"linux": "core"}}
|
||||
|
||||
fetched, err := PKGBUILDs(searcher, mockClient, &http.Client{}, testLogger.Child("test"),
|
||||
targets, "https://aur.archlinux.org", parser.ModeAny)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, fetched, "core/linux")
|
||||
assert.NotEmpty(t, fetched["core/linux"])
|
||||
assert.NotContains(t, fetched, "yay-git")
|
||||
}
|
||||
|
||||
// WHEN AUR returns no packages for an AUR needle
|
||||
// THEN that target is skipped and repo fetch still succeeds
|
||||
func TestIntegrationPKGBUILDsAUREmptySkipsAUR(t *testing.T) {
|
||||
mockClient := &mockaur.MockAUR{
|
||||
GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
|
||||
return []aur.Pkg{}, nil
|
||||
},
|
||||
}
|
||||
targets := []string{"core/linux", "yay-git"}
|
||||
testLogger, _ := integrationCmdBuilder(t)
|
||||
searcher := &testDBSearcher{absPackagesDB: map[string]string{"linux": "core"}}
|
||||
|
||||
fetched, err := PKGBUILDs(searcher, mockClient, &http.Client{}, testLogger.Child("test"),
|
||||
targets, "https://aur.archlinux.org", parser.ModeAny)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, fetched, "core/linux")
|
||||
assert.NotEmpty(t, fetched["core/linux"])
|
||||
assert.NotContains(t, fetched, "yay-git")
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
//go:build !integration
|
||||
// +build !integration
|
||||
|
||||
package menus
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
mapset "github.com/deckarep/golang-set/v2"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/Jguer/yay/v12/pkg/runtime"
|
||||
"github.com/Jguer/yay/v12/pkg/settings"
|
||||
"github.com/Jguer/yay/v12/pkg/settings/parser"
|
||||
"github.com/Jguer/yay/v12/pkg/text"
|
||||
)
|
||||
|
||||
func TestEditor(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
logger := text.NewLogger(io.Discard, io.Discard, strings.NewReader(""), false, "test")
|
||||
editorPath, args := editor(logger, "echo", "--help", false)
|
||||
require.NotEmpty(t, editorPath)
|
||||
require.Contains(t, args, "--help")
|
||||
}
|
||||
|
||||
func TestEditPkgbuilds(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
logger := text.NewLogger(io.Discard, io.Discard, strings.NewReader(""), false, "test")
|
||||
pkgb := t.TempDir()
|
||||
require.NoError(t, os.WriteFile(filepath.Join(pkgb, "PKGBUILD"), []byte("test"), 0o644))
|
||||
require.NoError(t, os.WriteFile(filepath.Join(pkgb, "subpackage"), []byte("pkg"), 0o644))
|
||||
err := editPkgbuilds(logger, map[string]string{"pkg": pkgb}, []string{"pkg"}, "echo", "", nil, false)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestCleanFnNoDirs(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
run := &runtime.Runtime{
|
||||
Logger: text.NewLogger(io.Discard, io.Discard, strings.NewReader(""), false, "test"),
|
||||
Cfg: &settings.Configuration{},
|
||||
}
|
||||
require.NoError(t, CleanFn(context.Background(), run, io.Discard, map[string]string{}, mapset.NewThreadUnsafeSet[string]()))
|
||||
}
|
||||
|
||||
func TestCleanFnWithDirs(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
execCmd := &fakeCmdBuilder{}
|
||||
run := &runtime.Runtime{
|
||||
Logger: text.NewLogger(io.Discard, io.Discard, strings.NewReader("a\n"), false, "test"),
|
||||
CmdBuilder: execCmd,
|
||||
Cfg: &settings.Configuration{},
|
||||
}
|
||||
|
||||
dirs := map[string]string{
|
||||
"pkg": t.TempDir(),
|
||||
}
|
||||
installed := mapset.NewThreadUnsafeSet[string]()
|
||||
err := CleanFn(context.Background(), run, io.Discard, dirs, installed)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, execCmd.showCalls, 2)
|
||||
require.Contains(t, strings.Join(execCmd.showCalls, " "), "reset")
|
||||
}
|
||||
|
||||
type fakeCmdBuilder struct {
|
||||
showCalls []string
|
||||
}
|
||||
|
||||
func (f *fakeCmdBuilder) BuildGitCmd(ctx context.Context, dir string, extraArgs ...string) *exec.Cmd {
|
||||
return exec.CommandContext(ctx, "git", extraArgs...)
|
||||
}
|
||||
|
||||
func (f *fakeCmdBuilder) BuildPacmanCmd(ctx context.Context, args *parser.Arguments, mode parser.TargetMode, noConfirm bool) *exec.Cmd {
|
||||
return exec.CommandContext(ctx, "pacman", args.FormatGlobals()...)
|
||||
}
|
||||
|
||||
func (f *fakeCmdBuilder) BuildMakepkgCmd(ctx context.Context, dir string, extraArgs ...string) *exec.Cmd {
|
||||
return exec.CommandContext(ctx, "makepkg", extraArgs...)
|
||||
}
|
||||
|
||||
func (f *fakeCmdBuilder) BuildGPGCmd(ctx context.Context, extraArgs ...string) *exec.Cmd {
|
||||
return exec.CommandContext(ctx, "gpg", extraArgs...)
|
||||
}
|
||||
|
||||
func (f *fakeCmdBuilder) AddMakepkgFlag(flag string) {}
|
||||
func (f *fakeCmdBuilder) GetKeepSrc() bool { return false }
|
||||
func (f *fakeCmdBuilder) SudoLoop() {}
|
||||
|
||||
func (f *fakeCmdBuilder) Capture(cmd *exec.Cmd) (string, string, error) {
|
||||
return "", "", nil
|
||||
}
|
||||
|
||||
func (f *fakeCmdBuilder) Show(cmd *exec.Cmd) error {
|
||||
f.showCalls = append(f.showCalls, cmd.String())
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
//go:build !integration
|
||||
// +build !integration
|
||||
|
||||
package menus
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"io"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
mapset "github.com/deckarep/golang-set/v2"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/Jguer/yay/v12/pkg/settings/parser"
|
||||
"github.com/Jguer/yay/v12/pkg/text"
|
||||
)
|
||||
|
||||
func TestSelectionMenu(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
installed := mapset.NewThreadUnsafeSet[string]()
|
||||
installed.Add("alpha")
|
||||
|
||||
basenames := []string{"alpha", "beta"}
|
||||
dirs := map[string]string{
|
||||
"alpha": "existing-alpha",
|
||||
"beta": "missing-beta",
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
expected int
|
||||
}{
|
||||
{name: "all", input: "a\n", expected: 2},
|
||||
{name: "none", input: "n\n", expected: 0},
|
||||
{name: "installed only", input: "i\n", expected: 1},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
logger := text.NewLogger(&bytes.Buffer{}, &bytes.Buffer{},
|
||||
strings.NewReader(tc.input), false, "test")
|
||||
selected, err := selectionMenu(logger, dirs, basenames, installed, "choose", false, "", nil)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, selected, tc.expected)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPkgbuildNumberMenu(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var out bytes.Buffer
|
||||
logger := text.NewLogger(&out, io.Discard, strings.NewReader(""), false, "test")
|
||||
dirs := map[string]string{
|
||||
"alpha": t.TempDir(),
|
||||
"beta": t.TempDir(),
|
||||
}
|
||||
installed := mapset.NewThreadUnsafeSet[string]()
|
||||
installed.Add("alpha")
|
||||
|
||||
basenames := []string{"alpha", "beta"}
|
||||
pkgbuildNumberMenu(logger, dirs, basenames, installed)
|
||||
|
||||
require.Contains(t, out.String(), "alpha")
|
||||
require.Contains(t, out.String(), "beta")
|
||||
}
|
||||
|
||||
func TestShowPkgbuildDiffHelpers(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
builder := &fakeMenusCmdBuilder{
|
||||
captureFn: func(cmd *exec.Cmd) (string, string, error) {
|
||||
if strings.Contains(cmd.String(), "--quiet --verify AUR_SEEN") {
|
||||
return "", "", nil
|
||||
}
|
||||
|
||||
return "deadbeef\n", "", nil
|
||||
},
|
||||
}
|
||||
|
||||
require.True(t, gitHasLastSeenRef(context.Background(), builder, "/tmp"))
|
||||
ref, err := getLastSeenHash(context.Background(), builder, "/tmp")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "deadbeef", ref)
|
||||
}
|
||||
|
||||
type fakeMenusCmdBuilder struct {
|
||||
captureFn func(*exec.Cmd) (string, string, error)
|
||||
captureCnt int
|
||||
}
|
||||
|
||||
func (f *fakeMenusCmdBuilder) BuildGitCmd(ctx context.Context, dir string, extraArgs ...string) *exec.Cmd {
|
||||
return exec.CommandContext(ctx, "git", extraArgs...)
|
||||
}
|
||||
|
||||
func (f *fakeMenusCmdBuilder) BuildMakepkgCmd(ctx context.Context, dir string, extraArgs ...string) *exec.Cmd {
|
||||
return exec.CommandContext(ctx, "makepkg", extraArgs...)
|
||||
}
|
||||
|
||||
func (f *fakeMenusCmdBuilder) BuildGPGCmd(ctx context.Context, extraArgs ...string) *exec.Cmd {
|
||||
return exec.CommandContext(ctx, "gpg", extraArgs...)
|
||||
}
|
||||
|
||||
func (f *fakeMenusCmdBuilder) BuildPacmanCmd(ctx context.Context, args *parser.Arguments, mode parser.TargetMode, noConfirm bool) *exec.Cmd {
|
||||
return exec.CommandContext(ctx, "pacman")
|
||||
}
|
||||
|
||||
func (f *fakeMenusCmdBuilder) AddMakepkgFlag(flag string) {}
|
||||
|
||||
func (f *fakeMenusCmdBuilder) GetKeepSrc() bool { return false }
|
||||
|
||||
func (f *fakeMenusCmdBuilder) SudoLoop() {}
|
||||
|
||||
func (f *fakeMenusCmdBuilder) Capture(cmd *exec.Cmd) (string, string, error) {
|
||||
f.captureCnt++
|
||||
if f.captureFn != nil {
|
||||
return f.captureFn(cmd)
|
||||
}
|
||||
|
||||
return "", "", nil
|
||||
}
|
||||
|
||||
func (f *fakeMenusCmdBuilder) Show(cmd *exec.Cmd) error {
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
//go:build !integration
|
||||
// +build !integration
|
||||
|
||||
package multierror
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestMultiError(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
merr := &MultiError{}
|
||||
require.NoError(t, merr.Return())
|
||||
|
||||
merr.Add(errors.New("first"))
|
||||
require.Equal(t, "first", merr.Error())
|
||||
require.EqualError(t, merr.Return(), "first")
|
||||
|
||||
merr.Add(nil)
|
||||
merr.Add(errors.New("second"))
|
||||
require.Equal(t, "first\nsecond", merr.Error())
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
//go:build !integration
|
||||
// +build !integration
|
||||
|
||||
package exe
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/Jguer/yay/v12/pkg/settings/parser"
|
||||
"github.com/Jguer/yay/v12/pkg/text"
|
||||
)
|
||||
|
||||
func TestBuildGitCmd(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
logger := text.NewLogger(io.Discard, io.Discard, strings.NewReader(""), false, "test")
|
||||
runner := &MockRunner{}
|
||||
builder := &CmdBuilder{
|
||||
GitBin: "git",
|
||||
Runner: runner,
|
||||
SudoBin: "su",
|
||||
Log: logger,
|
||||
}
|
||||
|
||||
cmd := builder.BuildGitCmd(context.Background(), "repo", "status")
|
||||
if filepath.Base(cmd.Path) == "git" {
|
||||
require.Equal(t, []string{"git", "-C", "repo", "status"}, cmd.Args)
|
||||
require.NotContains(t, strings.Join(cmd.Env, "|"), "GIT_WORK_TREE=")
|
||||
require.NotContains(t, strings.Join(cmd.Env, "|"), "GIT_DIR=")
|
||||
} else {
|
||||
require.Equal(t, "systemd-run", filepath.Base(cmd.Path))
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildPacmanCmd(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
logger := text.NewLogger(io.Discard, io.Discard, strings.NewReader(""), false, "test")
|
||||
builder := &CmdBuilder{
|
||||
PacmanBin: "pacman",
|
||||
PacmanConfigPath: "/etc/pacman.conf",
|
||||
PacmanDBPath: t.TempDir(),
|
||||
Runner: &MockRunner{},
|
||||
Log: logger,
|
||||
}
|
||||
|
||||
args := parser.MakeArguments()
|
||||
args.AddArg("Q")
|
||||
cmd := builder.BuildPacmanCmd(context.Background(), args, parser.ModeAny, true)
|
||||
require.Equal(t, "pacman", filepath.Base(cmd.Path))
|
||||
require.Contains(t, strings.Join(cmd.Args, " "), "--noconfirm")
|
||||
require.Contains(t, strings.Join(cmd.Args, " "), "--config /etc/pacman.conf")
|
||||
require.Contains(t, strings.Join(cmd.Args, " "), "--")
|
||||
}
|
||||
|
||||
func TestBuildPrivilegeElevatorCommand(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
logger := text.NewLogger(io.Discard, io.Discard, strings.NewReader(""), false, "test")
|
||||
builder := &CmdBuilder{
|
||||
SudoBin: "su",
|
||||
Runner: &MockRunner{},
|
||||
Log: logger,
|
||||
}
|
||||
cmd := builder.buildPrivilegeElevatorCommand(context.Background(), []string{"echo", "hello"})
|
||||
require.Equal(t, "su", filepath.Base(cmd.Path))
|
||||
require.Equal(t, []string{"su", "-c", "echo hello"}, cmd.Args)
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
//go:build !integration
|
||||
// +build !integration
|
||||
|
||||
package exe
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/Jguer/yay/v12/pkg/text"
|
||||
)
|
||||
|
||||
func TestOSRunnerCapture(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
runner := NewOSRunner(text.NewLogger(io.Discard, io.Discard, strings.NewReader(""), false, "test"))
|
||||
cmd := exec.CommandContext(context.Background(), "sh", "-c", "printf 'ok'; printf 'err' >&2")
|
||||
out, errOut, err := runner.Capture(cmd)
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "ok", out)
|
||||
require.Empty(t, errOut)
|
||||
|
||||
cmdFail := exec.CommandContext(context.Background(), "sh", "-c", "exit 1")
|
||||
_, stderr, err := runner.Capture(cmdFail)
|
||||
require.Error(t, err)
|
||||
require.Empty(t, stderr)
|
||||
}
|
||||
@@ -88,7 +88,9 @@ func TestInstaller_InstallNeeded(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
t.Run(tc.desc, func(td *testing.T) {
|
||||
td.Parallel()
|
||||
tmpDir := td.TempDir()
|
||||
pkgTar := tmpDir + "/yay-91.0.0-1-x86_64.pkg.tar.zst"
|
||||
|
||||
@@ -451,6 +453,7 @@ func TestInstaller_InstallMixedSourcesAndLayers(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
t.Run(tc.desc, func(td *testing.T) {
|
||||
pkgTar := tmpDir + "/yay-91.0.0-1-x86_64.pkg.tar.zst"
|
||||
jfinPkgTar := tmpDirJfin + "/jellyfin-server-10.8.8-1-x86_64.pkg.tar.zst"
|
||||
@@ -655,7 +658,9 @@ func TestInstaller_CompileFailed(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
t.Run(tc.desc, func(td *testing.T) {
|
||||
td.Parallel()
|
||||
pkgTar := tmpDir + "/yay-91.0.0-1-x86_64.pkg.tar.zst"
|
||||
|
||||
captureOverride := func(cmd *exec.Cmd) (stdout string, stderr string, err error) {
|
||||
@@ -811,7 +816,9 @@ func TestInstaller_InstallSplitPackage(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
t.Run(tc.desc, func(td *testing.T) {
|
||||
td.Parallel()
|
||||
pkgTars := []string{
|
||||
tmpDir + "/jellyfin-10.8.4-1-x86_64.pkg.tar.zst",
|
||||
tmpDir + "/jellyfin-web-10.8.4-1-x86_64.pkg.tar.zst",
|
||||
@@ -946,7 +953,9 @@ func TestInstaller_InstallDownloadOnly(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
t.Run(tc.desc, func(td *testing.T) {
|
||||
td.Parallel()
|
||||
tmpDir := td.TempDir()
|
||||
pkgTar := tmpDir + "/yay-91.0.0-1-x86_64.pkg.tar.zst"
|
||||
|
||||
@@ -1070,7 +1079,9 @@ func TestInstaller_InstallGroup(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
t.Run(tc.desc, func(td *testing.T) {
|
||||
td.Parallel()
|
||||
tmpDir := td.TempDir()
|
||||
|
||||
captureOverride := func(cmd *exec.Cmd) (stdout string, stderr string, err error) {
|
||||
@@ -1266,7 +1277,9 @@ func TestInstaller_InstallRebuild(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
t.Run(tc.desc, func(td *testing.T) {
|
||||
td.Parallel()
|
||||
tmpDir := td.TempDir()
|
||||
pkgTar := tmpDir + "/yay-91.0.0-1-x86_64.pkg.tar.zst"
|
||||
|
||||
@@ -1383,7 +1396,9 @@ func TestInstaller_InstallUpgrade(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
t.Run(tc.desc, func(td *testing.T) {
|
||||
td.Parallel()
|
||||
mockDB := &mock.DBExecutor{}
|
||||
mockRunner := &exe.MockRunner{}
|
||||
cmdBuilder := &exe.CmdBuilder{
|
||||
@@ -1479,7 +1494,9 @@ func TestInstaller_KeepSrc(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
t.Run(tc.desc, func(td *testing.T) {
|
||||
td.Parallel()
|
||||
tmpDir := td.TempDir()
|
||||
pkgTar := tmpDir + "/yay-92.0.0-1-x86_64.pkg.tar.zst"
|
||||
|
||||
@@ -1619,7 +1636,9 @@ func TestInstaller_InstallAsExplicit(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
t.Run(tc.desc, func(td *testing.T) {
|
||||
td.Parallel()
|
||||
pkgTar := tmpDir + "/yay-91.0.0-1-x86_64.pkg.tar.zst"
|
||||
|
||||
captureOverride := func(cmd *exec.Cmd) (stdout string, stderr string, err error) {
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
//go:build !integration
|
||||
// +build !integration
|
||||
|
||||
package workdir
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/Jguer/yay/v12/pkg/runtime"
|
||||
"github.com/Jguer/yay/v12/pkg/settings"
|
||||
"github.com/Jguer/yay/v12/pkg/settings/parser"
|
||||
"github.com/Jguer/yay/v12/pkg/text"
|
||||
)
|
||||
|
||||
func TestMergePkgbuilds(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
builder := &fakeWorkdirCmdBuilder{}
|
||||
dirs := map[string]string{
|
||||
"one": "/tmp/pkg-one",
|
||||
"two": "/tmp/pkg-two",
|
||||
}
|
||||
|
||||
err := mergePkgbuilds(context.Background(), builder, dirs)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, builder.captureCalls, 4)
|
||||
require.True(t, strings.Contains(builder.captureCalls[0], "reset"))
|
||||
require.True(t, strings.Contains(builder.captureCalls[1], "merge"))
|
||||
}
|
||||
|
||||
func TestCleanAfter(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
builder := &fakeWorkdirCmdBuilder{}
|
||||
run := &runtime.Runtime{
|
||||
Logger: text.NewLogger(&strings.Builder{}, &strings.Builder{}, strings.NewReader(""), false, "test"),
|
||||
CmdBuilder: builder,
|
||||
}
|
||||
dirs := map[string]string{
|
||||
"one": "/tmp/pkg-one",
|
||||
"two": "/tmp/pkg-two",
|
||||
}
|
||||
|
||||
cleanAfter(context.Background(), run, builder, dirs)
|
||||
require.Len(t, builder.captureCalls, 2)
|
||||
require.Len(t, builder.showCalls, 2)
|
||||
require.True(t, strings.Contains(builder.captureCalls[0], "reset"))
|
||||
require.True(t, strings.Contains(builder.showCalls[0], "clean"))
|
||||
}
|
||||
|
||||
func TestRemoveMake(t *testing.T) {
|
||||
var old bool
|
||||
old, settings.NoConfirm = settings.NoConfirm, false
|
||||
defer func() { settings.NoConfirm = old }()
|
||||
|
||||
builder := &fakeWorkdirCmdBuilder{}
|
||||
args := parser.MakeArguments()
|
||||
args.AddArg("Q")
|
||||
_ = removeMake(context.Background(), &settings.Configuration{}, builder, []string{"foo", "bar"}, args)
|
||||
|
||||
require.Len(t, builder.showCalls, 1)
|
||||
require.Contains(t, builder.showCalls[0], "pacman")
|
||||
require.Contains(t, builder.showCalls[0], "-R")
|
||||
require.Contains(t, builder.showCalls[0], "foo")
|
||||
require.Contains(t, builder.showCalls[0], "bar")
|
||||
require.True(t, strings.Contains(builder.showCalls[0], "--noconfirm"))
|
||||
}
|
||||
|
||||
type fakeWorkdirCmdBuilder struct {
|
||||
captureCalls []string
|
||||
showCalls []string
|
||||
}
|
||||
|
||||
func (f *fakeWorkdirCmdBuilder) BuildGitCmd(ctx context.Context, dir string, extraArgs ...string) *exec.Cmd {
|
||||
return exec.CommandContext(ctx, "git", extraArgs...)
|
||||
}
|
||||
|
||||
func (f *fakeWorkdirCmdBuilder) BuildPacmanCmd(ctx context.Context, args *parser.Arguments, mode parser.TargetMode, noConfirm bool) *exec.Cmd {
|
||||
cmdArgs := append([]string{"pacman"}, args.FormatGlobals()...)
|
||||
cmdArgs = append(cmdArgs, args.FormatArgs()...)
|
||||
cmdArgs = append(cmdArgs, args.Targets...)
|
||||
if noConfirm {
|
||||
cmdArgs = append(cmdArgs, "--noconfirm")
|
||||
}
|
||||
|
||||
return exec.CommandContext(ctx, cmdArgs[0], cmdArgs[1:]...)
|
||||
}
|
||||
|
||||
func (f *fakeWorkdirCmdBuilder) BuildMakepkgCmd(ctx context.Context, dir string, extraArgs ...string) *exec.Cmd {
|
||||
return exec.CommandContext(ctx, "makepkg", extraArgs...)
|
||||
}
|
||||
|
||||
func (f *fakeWorkdirCmdBuilder) BuildGPGCmd(ctx context.Context, extraArgs ...string) *exec.Cmd {
|
||||
return exec.CommandContext(ctx, "gpg", extraArgs...)
|
||||
}
|
||||
|
||||
func (f *fakeWorkdirCmdBuilder) AddMakepkgFlag(string) {}
|
||||
func (f *fakeWorkdirCmdBuilder) GetKeepSrc() bool { return false }
|
||||
func (f *fakeWorkdirCmdBuilder) SudoLoop() {}
|
||||
|
||||
func (f *fakeWorkdirCmdBuilder) Capture(cmd *exec.Cmd) (string, string, error) {
|
||||
f.captureCalls = append(f.captureCalls, cmd.String())
|
||||
return "", "", nil
|
||||
}
|
||||
|
||||
func (f *fakeWorkdirCmdBuilder) Show(cmd *exec.Cmd) error {
|
||||
f.showCalls = append(f.showCalls, cmd.String())
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
//go:build !integration
|
||||
// +build !integration
|
||||
|
||||
package text
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// TestColorHash is intentionally not parallel because it mutates the
|
||||
// package-level UseColor variable. No other parallel test in this
|
||||
// package reads UseColor, so sequential execution is sufficient.
|
||||
func TestColorHash(t *testing.T) {
|
||||
original := UseColor
|
||||
defer func() { UseColor = original }()
|
||||
|
||||
UseColor = true
|
||||
require.Equal(t, ColorHash("core"), ColorHash("core"))
|
||||
require.NotEqual(t, ColorHash("core"), ColorHash("extra"))
|
||||
|
||||
UseColor = false
|
||||
require.Equal(t, "core", ColorHash("core"))
|
||||
}
|
||||
+2
-52
@@ -81,11 +81,10 @@ func TestContinueTask(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestContinueTaskRU(t *testing.T) {
|
||||
func TestContinueTaskLocalized(t *testing.T) {
|
||||
strCustom := `
|
||||
msgid "yes"
|
||||
msgstr "да"
|
||||
`
|
||||
msgstr "да"`
|
||||
|
||||
// Create Locales directory and files on temp location
|
||||
tmpDir := t.TempDir()
|
||||
@@ -129,55 +128,6 @@ msgstr "да"
|
||||
gotext.SetLanguage("")
|
||||
}
|
||||
|
||||
func TestContinueTaskDE(t *testing.T) {
|
||||
strCustom := `
|
||||
msgid "yes"
|
||||
msgstr "ja"
|
||||
`
|
||||
|
||||
// Create Locales directory and files on temp location
|
||||
tmpDir := t.TempDir()
|
||||
dirname := path.Join(tmpDir, "en_US")
|
||||
err := os.MkdirAll(dirname, os.ModePerm)
|
||||
require.NoError(t, err)
|
||||
|
||||
fDefault, err := os.Create(path.Join(dirname, "yay.po"))
|
||||
require.NoError(t, err)
|
||||
|
||||
defer fDefault.Close()
|
||||
|
||||
_, err = fDefault.WriteString(strCustom)
|
||||
require.NoError(t, err)
|
||||
|
||||
gotext.Configure(tmpDir, "en_US", "yay")
|
||||
require.Equal(t, "ja", gotext.Get("yes"))
|
||||
|
||||
type args struct {
|
||||
s string
|
||||
preset bool
|
||||
noConfirm bool
|
||||
input string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want bool
|
||||
}{
|
||||
{name: "default input false", args: args{s: "", input: "n", preset: true, noConfirm: false}, want: false},
|
||||
{name: "default input true", args: args{s: "", input: "y", preset: false, noConfirm: false}, want: true},
|
||||
{name: "custom input true", args: args{s: "", input: "j", preset: false, noConfirm: false}, want: true},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
in := strings.NewReader(tt.args.input)
|
||||
logger := NewLogger(io.Discard, io.Discard, in, false, "test")
|
||||
got := logger.ContinueTask(tt.args.s, tt.args.preset, tt.args.noConfirm)
|
||||
require.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
gotext.SetLanguage("")
|
||||
}
|
||||
|
||||
func TestCreateRepoLink(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
//go:build !integration
|
||||
// +build !integration
|
||||
|
||||
package text
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestFormatTime(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require.Equal(t, "1970-01-01", FormatTime(0))
|
||||
now := time.Unix(0, 0)
|
||||
require.Equal(t, now.Format("2006-01-02"), FormatTime(0))
|
||||
}
|
||||
|
||||
func TestFormatTimeQuery(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
now := time.Unix(0, 0)
|
||||
require.Equal(t, now.Format("Mon 02 Jan 2006 03:04:05 PM MST"), FormatTimeQuery(0))
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
//go:build !integration
|
||||
// +build !integration
|
||||
|
||||
package text
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestSplitDBFromName(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
db, pkg := SplitDBFromName("core/pkg")
|
||||
require.Equal(t, "core", db)
|
||||
require.Equal(t, "pkg", pkg)
|
||||
|
||||
db, pkg = SplitDBFromName("pkg")
|
||||
require.Equal(t, "", db)
|
||||
require.Equal(t, "pkg", pkg)
|
||||
}
|
||||
|
||||
func TestCreateOSC8Link(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := CreateOSC8Link("https://example.com", "text")
|
||||
require.Equal(t, "\033]8;;https://example.com\033\\text\033]8;;\033\\", got)
|
||||
}
|
||||
|
||||
func TestHumanReadable(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require.Equal(t, "10.0 B", Human(10))
|
||||
require.Equal(t, "1.0 KiB", Human(1024))
|
||||
require.Equal(t, "1.5 KiB", Human(1536))
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
//go:build !integration
|
||||
// +build !integration
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/Jguer/aur"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/Jguer/yay/v12/pkg/dep"
|
||||
)
|
||||
|
||||
func TestInfoToInstallInfo(t *testing.T) {
|
||||
info := infoToInstallInfo([]aur.Pkg{
|
||||
{Name: "foo", PackageBase: "foo-base"},
|
||||
{Name: "bar", PackageBase: "bar-base"},
|
||||
})
|
||||
|
||||
require.Len(t, info, 1)
|
||||
require.Len(t, info[0], 2)
|
||||
require.Equal(t, &dep.InstallInfo{AURBase: ptr("foo-base"), Source: dep.AUR}, info[0]["foo"])
|
||||
require.Equal(t, &dep.InstallInfo{AURBase: ptr("bar-base"), Source: dep.AUR}, info[0]["bar"])
|
||||
}
|
||||
|
||||
func ptr(s string) *string {
|
||||
return &s
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
//go:build !integration
|
||||
// +build !integration
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/Jguer/aur"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
mockaur "github.com/Jguer/yay/v12/pkg/dep/mock"
|
||||
"github.com/Jguer/yay/v12/pkg/text"
|
||||
)
|
||||
|
||||
func TestHandlePackageVoteNoResults(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
logger := text.NewLogger(io.Discard, io.Discard, strings.NewReader(""), false, "test")
|
||||
err := handlePackageVote(context.Background(), []string{"missing"}, &mockaur.MockAUR{
|
||||
GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
|
||||
return nil, nil
|
||||
},
|
||||
}, logger, nil, true)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
Reference in new issue
Block a user