* Add all sortyby options Previously, only 'name' was a supported sortby option. Now, all sortby options are supported. Whenever there is a tie, the metric is used as a tiebreaker (it is also the default when sortby is not specified). The only behavior that changed is that packages with the same metric are sorted oppositely when sorting bottomUp. This was actually a bug in the previous implementation which inverts the `cmpResult` for bottomUp which returns true if the metrics are the same. According to the docs for Less (https://pkg.go.dev/sort#Interface), Less(i, i) should be false (the same element cannot sort before itself). I mainly structured the code for efficiency by creating the sortby function once rather than checking `separateSources` and `bottomUp` every comparison, but I also think this improves readability compared to having a switch-case in the comparison function. * Fix separating sources on ties and improve test coverage * Remove 'id' and 'baseid' in sortby options
669 lines
24 KiB
Go
669 lines
24 KiB
Go
//go:build !integration
|
|
// +build !integration
|
|
|
|
package query
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/Jguer/aur"
|
|
|
|
"github.com/Jguer/yay/v12/pkg/db/mock"
|
|
mockaur "github.com/Jguer/yay/v12/pkg/dep/mock"
|
|
"github.com/Jguer/yay/v12/pkg/settings/parser"
|
|
"github.com/Jguer/yay/v12/pkg/text"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestSourceQueryBuilder(t *testing.T) {
|
|
t.Parallel()
|
|
type testCase struct {
|
|
desc string
|
|
search []string
|
|
bottomUp bool
|
|
separateSources bool
|
|
sortBy string
|
|
verbosity SearchVerbosity
|
|
targetMode parser.TargetMode
|
|
singleLineResults bool
|
|
searchBy string
|
|
wantResults []string
|
|
wantOutput []string
|
|
}
|
|
|
|
testCases := []testCase{
|
|
{
|
|
desc: "sort-by-metric bottomup separatesources",
|
|
search: []string{"linux"},
|
|
bottomUp: true,
|
|
separateSources: true,
|
|
sortBy: "",
|
|
verbosity: Detailed,
|
|
wantResults: []string{"linux-ck", "linux-zen", "linux"},
|
|
wantOutput: []string{
|
|
"\x1b]8;;https://aur.archlinux.org/packages/linux-ck\x1b\\\x1b[1m\x1b[34maur\x1b[0m\x1b[0m/\x1b[1mlinux-ck\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.12-1\x1b[0m\x1b[1m (+450\x1b[0m \x1b[1m1.51) \x1b[0m\n The Linux-ck kernel and modules with ck's hrtimer patches\n",
|
|
"\x1b]8;;https://archlinux.org/packages/core/x86_64/linux-zen\x1b\\\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux-zen\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux ZEN kernel and modules\n",
|
|
"\x1b]8;;https://archlinux.org/packages/core/x86_64/linux\x1b\\\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux kernel and modules\n",
|
|
},
|
|
},
|
|
{
|
|
desc: "sort-by-metric topdown separatesources",
|
|
search: []string{"linux"},
|
|
bottomUp: false,
|
|
separateSources: true,
|
|
sortBy: "",
|
|
verbosity: Detailed,
|
|
wantResults: []string{"linux", "linux-zen", "linux-ck"},
|
|
wantOutput: []string{
|
|
"\x1b]8;;https://archlinux.org/packages/core/x86_64/linux\x1b\\\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux kernel and modules\n",
|
|
"\x1b]8;;https://archlinux.org/packages/core/x86_64/linux-zen\x1b\\\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux-zen\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux ZEN kernel and modules\n",
|
|
"\x1b]8;;https://aur.archlinux.org/packages/linux-ck\x1b\\\x1b[1m\x1b[34maur\x1b[0m\x1b[0m/\x1b[1mlinux-ck\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.12-1\x1b[0m\x1b[1m (+450\x1b[0m \x1b[1m1.51) \x1b[0m\n The Linux-ck kernel and modules with ck's hrtimer patches\n",
|
|
},
|
|
},
|
|
{
|
|
desc: "sort-by-metric bottomup noseparatesources",
|
|
search: []string{"linux"},
|
|
bottomUp: true,
|
|
separateSources: false,
|
|
sortBy: "",
|
|
verbosity: Detailed,
|
|
wantResults: []string{"linux-zen", "linux-ck", "linux"},
|
|
wantOutput: []string{
|
|
"\x1b]8;;https://archlinux.org/packages/core/x86_64/linux-zen\x1b\\\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux-zen\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux ZEN kernel and modules\n",
|
|
"\x1b]8;;https://aur.archlinux.org/packages/linux-ck\x1b\\\x1b[1m\x1b[34maur\x1b[0m\x1b[0m/\x1b[1mlinux-ck\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.12-1\x1b[0m\x1b[1m (+450\x1b[0m \x1b[1m1.51) \x1b[0m\n The Linux-ck kernel and modules with ck's hrtimer patches\n",
|
|
"\x1b]8;;https://archlinux.org/packages/core/x86_64/linux\x1b\\\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux kernel and modules\n",
|
|
},
|
|
},
|
|
{
|
|
desc: "sort-by-metric topdown noseparatesources",
|
|
search: []string{"linux"},
|
|
bottomUp: false,
|
|
separateSources: false,
|
|
sortBy: "",
|
|
verbosity: Detailed,
|
|
wantResults: []string{"linux", "linux-ck", "linux-zen"},
|
|
wantOutput: []string{
|
|
"\x1b]8;;https://archlinux.org/packages/core/x86_64/linux\x1b\\\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux kernel and modules\n",
|
|
"\x1b]8;;https://aur.archlinux.org/packages/linux-ck\x1b\\\x1b[1m\x1b[34maur\x1b[0m\x1b[0m/\x1b[1mlinux-ck\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.12-1\x1b[0m\x1b[1m (+450\x1b[0m \x1b[1m1.51) \x1b[0m\n The Linux-ck kernel and modules with ck's hrtimer patches\n",
|
|
"\x1b]8;;https://archlinux.org/packages/core/x86_64/linux-zen\x1b\\\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux-zen\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux ZEN kernel and modules\n",
|
|
},
|
|
},
|
|
{
|
|
desc: "sort-by-metric bottomup separatesources number-menu",
|
|
search: []string{"linux"},
|
|
bottomUp: true,
|
|
separateSources: true,
|
|
sortBy: "",
|
|
verbosity: NumberMenu,
|
|
wantResults: []string{"linux-ck", "linux-zen", "linux"},
|
|
wantOutput: []string{
|
|
"\x1b[35m3\x1b[0m \x1b]8;;https://aur.archlinux.org/packages/linux-ck\x1b\\\x1b[1m\x1b[34maur\x1b[0m\x1b[0m/\x1b[1mlinux-ck\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.12-1\x1b[0m\x1b[1m (+450\x1b[0m \x1b[1m1.51) \x1b[0m\n The Linux-ck kernel and modules with ck's hrtimer patches\n",
|
|
"\x1b[35m2\x1b[0m \x1b]8;;https://archlinux.org/packages/core/x86_64/linux-zen\x1b\\\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux-zen\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux ZEN kernel and modules\n",
|
|
"\x1b[35m1\x1b[0m \x1b]8;;https://archlinux.org/packages/core/x86_64/linux\x1b\\\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux kernel and modules\n",
|
|
},
|
|
},
|
|
{
|
|
desc: "sort-by-metric topdown separatesources number-menu",
|
|
search: []string{"linux"},
|
|
bottomUp: false,
|
|
separateSources: true,
|
|
sortBy: "",
|
|
verbosity: NumberMenu,
|
|
wantResults: []string{"linux", "linux-zen", "linux-ck"},
|
|
wantOutput: []string{
|
|
"\x1b[35m1\x1b[0m \x1b]8;;https://archlinux.org/packages/core/x86_64/linux\x1b\\\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux kernel and modules\n",
|
|
"\x1b[35m2\x1b[0m \x1b]8;;https://archlinux.org/packages/core/x86_64/linux-zen\x1b\\\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux-zen\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux ZEN kernel and modules\n",
|
|
"\x1b[35m3\x1b[0m \x1b]8;;https://aur.archlinux.org/packages/linux-ck\x1b\\\x1b[1m\x1b[34maur\x1b[0m\x1b[0m/\x1b[1mlinux-ck\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.12-1\x1b[0m\x1b[1m (+450\x1b[0m \x1b[1m1.51) \x1b[0m\n The Linux-ck kernel and modules with ck's hrtimer patches\n",
|
|
},
|
|
},
|
|
{
|
|
desc: "sort-by-name bottomup separatesources number-menu",
|
|
search: []string{"linux"},
|
|
bottomUp: true,
|
|
separateSources: true,
|
|
sortBy: "name",
|
|
verbosity: NumberMenu,
|
|
wantResults: []string{"linux-ck", "linux", "linux-zen"},
|
|
wantOutput: []string{
|
|
"\x1b[35m3\x1b[0m \x1b]8;;https://aur.archlinux.org/packages/linux-ck\x1b\\\x1b[1m\x1b[34maur\x1b[0m\x1b[0m/\x1b[1mlinux-ck\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.12-1\x1b[0m\x1b[1m (+450\x1b[0m \x1b[1m1.51) \x1b[0m\n The Linux-ck kernel and modules with ck's hrtimer patches\n",
|
|
"\x1b[35m2\x1b[0m \x1b]8;;https://archlinux.org/packages/core/x86_64/linux\x1b\\\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux kernel and modules\n",
|
|
"\x1b[35m1\x1b[0m \x1b]8;;https://archlinux.org/packages/core/x86_64/linux-zen\x1b\\\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux-zen\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux ZEN kernel and modules\n",
|
|
},
|
|
},
|
|
{
|
|
desc: "sort-by-name topdown separatesources number-menu",
|
|
search: []string{"linux"},
|
|
bottomUp: false,
|
|
separateSources: true,
|
|
sortBy: "name",
|
|
verbosity: NumberMenu,
|
|
wantResults: []string{"linux-zen", "linux", "linux-ck"},
|
|
wantOutput: []string{
|
|
"\x1b[35m1\x1b[0m \x1b]8;;https://archlinux.org/packages/core/x86_64/linux-zen\x1b\\\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux-zen\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux ZEN kernel and modules\n",
|
|
"\x1b[35m2\x1b[0m \x1b]8;;https://archlinux.org/packages/core/x86_64/linux\x1b\\\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux kernel and modules\n",
|
|
"\x1b[35m3\x1b[0m \x1b]8;;https://aur.archlinux.org/packages/linux-ck\x1b\\\x1b[1m\x1b[34maur\x1b[0m\x1b[0m/\x1b[1mlinux-ck\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.12-1\x1b[0m\x1b[1m (+450\x1b[0m \x1b[1m1.51) \x1b[0m\n The Linux-ck kernel and modules with ck's hrtimer patches\n",
|
|
},
|
|
},
|
|
{
|
|
desc: "sort-by-name bottomup noseparatesources minimal",
|
|
search: []string{"linux"},
|
|
bottomUp: true,
|
|
separateSources: false,
|
|
sortBy: "name",
|
|
verbosity: Minimal,
|
|
wantResults: []string{"linux", "linux-ck", "linux-zen"},
|
|
wantOutput: []string{
|
|
"linux\n",
|
|
"linux-ck\n",
|
|
"linux-zen\n",
|
|
},
|
|
},
|
|
{
|
|
desc: "only-aur minimal",
|
|
search: []string{"linux"},
|
|
bottomUp: true,
|
|
separateSources: true,
|
|
sortBy: "name",
|
|
verbosity: Minimal,
|
|
targetMode: parser.ModeAUR,
|
|
wantResults: []string{"linux-ck"},
|
|
wantOutput: []string{
|
|
"linux-ck\n",
|
|
},
|
|
},
|
|
{
|
|
desc: "only-repo minimal",
|
|
search: []string{"linux"},
|
|
bottomUp: true,
|
|
separateSources: true,
|
|
sortBy: "name",
|
|
verbosity: Minimal,
|
|
targetMode: parser.ModeRepo,
|
|
wantResults: []string{"linux", "linux-zen"},
|
|
wantOutput: []string{
|
|
"linux\n",
|
|
"linux-zen\n",
|
|
},
|
|
},
|
|
{
|
|
desc: "sort-by-name singleline",
|
|
search: []string{"linux"},
|
|
bottomUp: true,
|
|
separateSources: true,
|
|
sortBy: "name",
|
|
verbosity: Detailed,
|
|
singleLineResults: true,
|
|
wantResults: []string{"linux-ck", "linux", "linux-zen"},
|
|
wantOutput: []string{
|
|
"\x1b]8;;https://aur.archlinux.org/packages/linux-ck\x1b\\\x1b[1m\x1b[34maur\x1b[0m\x1b[0m/\x1b[1mlinux-ck\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.12-1\x1b[0m\x1b[1m (+450\x1b[0m \x1b[1m1.51) \x1b[0m\tThe Linux-ck kernel and modules with ck's hrtimer patches\n",
|
|
"\x1b]8;;https://archlinux.org/packages/core/x86_64/linux\x1b\\\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\tThe Linux kernel and modules\n",
|
|
"\x1b]8;;https://archlinux.org/packages/core/x86_64/linux-zen\x1b\\\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux-zen\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\tThe Linux ZEN kernel and modules\n",
|
|
},
|
|
},
|
|
{
|
|
desc: "sort-by-name search-by-name",
|
|
search: []string{"linux-ck"},
|
|
bottomUp: true,
|
|
separateSources: true,
|
|
sortBy: "name",
|
|
verbosity: Detailed,
|
|
searchBy: "name",
|
|
targetMode: parser.ModeAUR,
|
|
wantResults: []string{"linux-ck"},
|
|
wantOutput: []string{
|
|
"\x1b]8;;https://aur.archlinux.org/packages/linux-ck\x1b\\\x1b[1m\x1b[34maur\x1b[0m\x1b[0m/\x1b[1mlinux-ck\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.12-1\x1b[0m\x1b[1m (+450\x1b[0m \x1b[1m1.51) \x1b[0m\n The Linux-ck kernel and modules with ck's hrtimer patches\n",
|
|
},
|
|
},
|
|
{
|
|
desc: "only-aur search-by-several-terms",
|
|
search: []string{"linux-ck", "hrtimer"},
|
|
bottomUp: true,
|
|
separateSources: true,
|
|
verbosity: Detailed,
|
|
targetMode: parser.ModeAUR,
|
|
wantResults: []string{"linux-ck"},
|
|
wantOutput: []string{
|
|
"\x1b]8;;https://aur.archlinux.org/packages/linux-ck\x1b\\\x1b[1m\x1b[34maur\x1b[0m\x1b[0m/\x1b[1mlinux-ck\x1b[0m\x1b]8;;\x1b\\ \x1b[36m5.16.12-1\x1b[0m\x1b[1m (+450\x1b[0m \x1b[1m1.51) \x1b[0m\n The Linux-ck kernel and modules with ck's hrtimer patches\n",
|
|
},
|
|
},
|
|
}
|
|
|
|
mockDB := &mock.DBExecutor{
|
|
ReposFn: func() []string {
|
|
// Match pacman.conf parsing order for source separation.
|
|
return []string{"core"}
|
|
},
|
|
SyncPackagesFn: func(pkgs ...string) []mock.IPackage {
|
|
mockDB := mock.NewDB("core")
|
|
return []mock.IPackage{
|
|
&mock.Package{
|
|
PBase: "linux",
|
|
PName: "linux",
|
|
PVersion: "5.16.0",
|
|
PDescription: "The Linux kernel and modules",
|
|
PSize: 1,
|
|
PISize: 1,
|
|
PDB: mockDB,
|
|
PArchitecture: "x86_64",
|
|
},
|
|
&mock.Package{
|
|
PBase: "linux-zen",
|
|
PName: "linux-zen",
|
|
PVersion: "5.16.0",
|
|
PDescription: "The Linux ZEN kernel and modules",
|
|
PSize: 1,
|
|
PISize: 1,
|
|
PDB: mockDB,
|
|
PArchitecture: "x86_64",
|
|
},
|
|
}
|
|
},
|
|
LocalPackageFn: func(string) mock.IPackage {
|
|
return nil
|
|
},
|
|
}
|
|
|
|
mockAUR := &mockaur.MockAUR{
|
|
GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
|
|
return []aur.Pkg{
|
|
{
|
|
Description: "The Linux-ck kernel and modules with ck's hrtimer patches",
|
|
FirstSubmitted: 1311346274,
|
|
ID: 1045311,
|
|
LastModified: 1646250901,
|
|
Maintainer: "graysky",
|
|
Name: "linux-ck",
|
|
NumVotes: 450,
|
|
OutOfDate: 0,
|
|
PackageBase: "linux-ck",
|
|
PackageBaseID: 50911,
|
|
Popularity: 1.511141,
|
|
URL: "https://wiki.archlinux.org/index.php/Linux-ck",
|
|
URLPath: "/cgit/aur.git/snapshot/linux-ck.tar.gz",
|
|
Version: "5.16.12-1",
|
|
},
|
|
}, nil
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
w := &strings.Builder{}
|
|
queryBuilder := NewSourceQueryBuilder(mockAUR,
|
|
text.NewLogger(w, io.Discard, strings.NewReader(""), false, "test"),
|
|
tc.sortBy, tc.targetMode, tc.searchBy, tc.bottomUp,
|
|
tc.singleLineResults, tc.separateSources)
|
|
|
|
queryBuilder.Execute(context.Background(), mockDB, tc.search)
|
|
|
|
assert.Len(t, queryBuilder.results, len(tc.wantResults))
|
|
assert.Equal(t, len(tc.wantResults), queryBuilder.Len())
|
|
for i, name := range tc.wantResults {
|
|
assert.Equal(t, name, queryBuilder.results[i].name)
|
|
}
|
|
|
|
queryBuilder.Results(mockDB, tc.verbosity)
|
|
|
|
assert.Equal(t, strings.Join(tc.wantOutput, ""), w.String())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSourceQueryBuilderTieSortsByRepoOrder(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
type testCase struct {
|
|
desc string
|
|
bottomUp bool
|
|
repoOrder []string
|
|
wantNames []string
|
|
}
|
|
|
|
testCases := []testCase{
|
|
{
|
|
desc: "sort-by-metric topdown repo-order-core-extra",
|
|
bottomUp: false,
|
|
repoOrder: []string{"core", "extra"},
|
|
wantNames: []string{"systemd", "systemd-libs", "python-systemd", "systemd-git"},
|
|
},
|
|
{
|
|
desc: "sort-by-metric topdown repo-order-extra-core",
|
|
bottomUp: false,
|
|
repoOrder: []string{"extra", "core"},
|
|
wantNames: []string{"systemd", "python-systemd", "systemd-libs", "systemd-git"},
|
|
},
|
|
{
|
|
desc: "sort-by-metric bottomup repo-order-core-extra",
|
|
bottomUp: true,
|
|
repoOrder: []string{"core", "extra"},
|
|
wantNames: []string{"systemd-git", "python-systemd", "systemd-libs", "systemd"},
|
|
},
|
|
{
|
|
desc: "sort-by-metric bottomup repo-order-extra-core",
|
|
bottomUp: true,
|
|
repoOrder: []string{"extra", "core"},
|
|
wantNames: []string{"systemd-git", "systemd-libs", "python-systemd", "systemd"},
|
|
},
|
|
}
|
|
|
|
mockDB := &mock.DBExecutor{
|
|
SyncPackagesFn: func(pkgs ...string) []mock.IPackage {
|
|
return []mock.IPackage{
|
|
&mock.Package{
|
|
PBase: "systemd",
|
|
PName: "systemd",
|
|
PVersion: "259-1",
|
|
PDescription: "system and service manager",
|
|
PSize: 1,
|
|
PISize: 1,
|
|
PDB: mock.NewDB("core"),
|
|
PArchitecture: "x86_64",
|
|
},
|
|
&mock.Package{
|
|
PBase: "systemd",
|
|
PName: "systemd-libs",
|
|
PVersion: "259-1",
|
|
PDescription: "systemd client libraries",
|
|
PSize: 1,
|
|
PISize: 1,
|
|
PDB: mock.NewDB("core"),
|
|
PArchitecture: "x86_64",
|
|
},
|
|
&mock.Package{
|
|
PBase: "python-systemd",
|
|
PName: "python-systemd",
|
|
PVersion: "235-4",
|
|
PDescription: "Python bindings for systemd",
|
|
PSize: 1,
|
|
PISize: 1,
|
|
PDB: mock.NewDB("extra"),
|
|
PArchitecture: "x86_64",
|
|
},
|
|
}
|
|
},
|
|
LocalPackageFn: func(string) mock.IPackage {
|
|
return nil
|
|
},
|
|
}
|
|
|
|
mockAUR := &mockaur.MockAUR{
|
|
GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
|
|
return []aur.Pkg{
|
|
{
|
|
Description: "system and service manager (git version)",
|
|
FirstSubmitted: 1445633397,
|
|
ID: 1909597,
|
|
LastModified: 1765571424,
|
|
Maintainer: "Atsutane",
|
|
Name: "systemd-git",
|
|
NumVotes: 11,
|
|
OutOfDate: 0,
|
|
PackageBase: "systemd-git",
|
|
PackageBaseID: 102323,
|
|
Popularity: 0.005618,
|
|
URL: "https://www.github.com/systemd/systemd",
|
|
URLPath: "/cgit/aur.git/snapshot/systemd-git.tar.gz",
|
|
Version: "259.rc3.r85286.7524671f74c-1",
|
|
},
|
|
}, nil
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
w := &strings.Builder{}
|
|
mockDB.ReposFn = func() []string {
|
|
return tc.repoOrder
|
|
}
|
|
queryBuilder := NewSourceQueryBuilder(mockAUR,
|
|
text.NewLogger(w, io.Discard, strings.NewReader(""), false, "test"),
|
|
"", parser.ModeAny, "", tc.bottomUp,
|
|
false, true)
|
|
|
|
queryBuilder.Execute(context.Background(), mockDB, []string{"systemd"})
|
|
|
|
gotNames := make([]string, len(queryBuilder.results))
|
|
for i, result := range queryBuilder.results {
|
|
gotNames[i] = result.name
|
|
}
|
|
|
|
assert.Equal(t, tc.wantNames, gotNames)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSourceQueryBuilderTieDoesNotSeparateSources(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
type testCase struct {
|
|
desc string
|
|
bottomUp bool
|
|
wantNames []string
|
|
}
|
|
|
|
testCases := []testCase{
|
|
{
|
|
desc: "sort-by-metric topdown",
|
|
bottomUp: false,
|
|
wantNames: []string{"yay", "ruby-yard", "yay-git"},
|
|
},
|
|
{
|
|
desc: "sort-by-metric bottomup",
|
|
bottomUp: true,
|
|
wantNames: []string{"yay-git", "ruby-yard", "yay"},
|
|
},
|
|
}
|
|
|
|
mockDB, mockAUR := newYayQueryBuilderMocks()
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
w := &strings.Builder{}
|
|
queryBuilder := NewSourceQueryBuilder(mockAUR,
|
|
text.NewLogger(w, io.Discard, strings.NewReader(""), false, "test"),
|
|
"", parser.ModeAny, "", tc.bottomUp,
|
|
false, true)
|
|
|
|
queryBuilder.Execute(context.Background(), mockDB, []string{"yay"})
|
|
|
|
gotNames := make([]string, len(queryBuilder.results))
|
|
for i, result := range queryBuilder.results {
|
|
gotNames[i] = result.name
|
|
}
|
|
|
|
assert.Equal(t, tc.wantNames, gotNames)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSourceQueryBuilderSortByFields(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
type testCase struct {
|
|
desc string
|
|
sortBy string
|
|
bottomUp bool
|
|
wantNames []string
|
|
}
|
|
|
|
testCases := []testCase{
|
|
{
|
|
desc: "sort-by-base topdown",
|
|
sortBy: "base",
|
|
bottomUp: false,
|
|
wantNames: []string{"yay-git", "yay", "ruby-yard"},
|
|
},
|
|
{
|
|
desc: "sort-by-base bottomup",
|
|
sortBy: "base",
|
|
bottomUp: true,
|
|
wantNames: []string{"ruby-yard", "yay", "yay-git"},
|
|
},
|
|
{
|
|
desc: "sort-by-modified topdown",
|
|
sortBy: "modified",
|
|
bottomUp: false,
|
|
wantNames: []string{"yay-git", "yay", "ruby-yard"},
|
|
},
|
|
{
|
|
desc: "sort-by-modified bottomup",
|
|
sortBy: "modified",
|
|
bottomUp: true,
|
|
wantNames: []string{"ruby-yard", "yay", "yay-git"},
|
|
},
|
|
{
|
|
desc: "sort-by-name topdown",
|
|
sortBy: "name",
|
|
bottomUp: false,
|
|
wantNames: []string{"yay-git", "yay", "ruby-yard"},
|
|
},
|
|
{
|
|
desc: "sort-by-name bottomup",
|
|
sortBy: "name",
|
|
bottomUp: true,
|
|
wantNames: []string{"ruby-yard", "yay", "yay-git"},
|
|
},
|
|
{
|
|
desc: "sort-by-popularity topdown",
|
|
sortBy: "popularity",
|
|
bottomUp: false,
|
|
wantNames: []string{"yay", "yay-git", "ruby-yard"},
|
|
},
|
|
{
|
|
desc: "sort-by-popularity bottomup",
|
|
sortBy: "popularity",
|
|
bottomUp: true,
|
|
wantNames: []string{"ruby-yard", "yay-git", "yay"},
|
|
},
|
|
{
|
|
desc: "sort-by-votes topdown",
|
|
sortBy: "votes",
|
|
bottomUp: false,
|
|
wantNames: []string{"yay", "yay-git", "ruby-yard"},
|
|
},
|
|
{
|
|
desc: "sort-by-votes bottomup",
|
|
sortBy: "votes",
|
|
bottomUp: true,
|
|
wantNames: []string{"ruby-yard", "yay-git", "yay"},
|
|
},
|
|
{
|
|
desc: "sort-by-submitted topdown",
|
|
sortBy: "submitted",
|
|
bottomUp: false,
|
|
wantNames: []string{"yay-git", "yay", "ruby-yard"},
|
|
},
|
|
{
|
|
desc: "sort-by-submitted bottomup",
|
|
sortBy: "submitted",
|
|
bottomUp: true,
|
|
wantNames: []string{"ruby-yard", "yay", "yay-git"},
|
|
},
|
|
{
|
|
desc: "sort-by-metric topdown",
|
|
sortBy: "",
|
|
bottomUp: false,
|
|
wantNames: []string{"yay", "yay-git", "ruby-yard"},
|
|
},
|
|
{
|
|
desc: "sort-by-metric bottomup",
|
|
sortBy: "",
|
|
bottomUp: true,
|
|
wantNames: []string{"ruby-yard", "yay-git", "yay"},
|
|
},
|
|
}
|
|
|
|
mockDB, mockAUR := newYayQueryBuilderMocks()
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
w := &strings.Builder{}
|
|
queryBuilder := NewSourceQueryBuilder(mockAUR,
|
|
text.NewLogger(w, io.Discard, strings.NewReader(""), false, "test"),
|
|
tc.sortBy, parser.ModeAny, "", tc.bottomUp,
|
|
false, false)
|
|
|
|
queryBuilder.Execute(context.Background(), mockDB, []string{"yay"})
|
|
|
|
gotNames := make([]string, len(queryBuilder.results))
|
|
for i, result := range queryBuilder.results {
|
|
gotNames[i] = result.name
|
|
}
|
|
|
|
assert.Equal(t, tc.wantNames, gotNames)
|
|
})
|
|
}
|
|
}
|
|
|
|
func newYayQueryBuilderMocks() (*mock.DBExecutor, *mockaur.MockAUR) {
|
|
mockDB := &mock.DBExecutor{
|
|
ReposFn: func() []string {
|
|
// Match pacman.conf parsing order for source separation.
|
|
return []string{"core", "extra"}
|
|
},
|
|
SyncPackagesFn: func(pkgs ...string) []mock.IPackage {
|
|
mockDB := mock.NewDB("extra")
|
|
return []mock.IPackage{
|
|
&mock.Package{
|
|
PBase: "ruby-yard",
|
|
PName: "ruby-yard",
|
|
PVersion: "0.9.34-5",
|
|
PDescription: "YARD is a Ruby Documentation tool. The Y stands for \"Yay!\"",
|
|
PSize: 1,
|
|
PISize: 1,
|
|
PDB: mockDB,
|
|
PArchitecture: "x86_64",
|
|
},
|
|
}
|
|
},
|
|
LocalPackageFn: func(string) mock.IPackage {
|
|
return nil
|
|
},
|
|
}
|
|
|
|
mockAUR := &mockaur.MockAUR{
|
|
GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
|
|
return []aur.Pkg{
|
|
{
|
|
Description: "Yet another yogurt. Pacman wrapper and AUR helper written in go.",
|
|
FirstSubmitted: 1475688004,
|
|
ID: 1911141,
|
|
LastModified: 1765742501,
|
|
Maintainer: "jguer",
|
|
Name: "yay",
|
|
NumVotes: 2461,
|
|
OutOfDate: 0,
|
|
PackageBase: "yay",
|
|
PackageBaseID: 115973,
|
|
Popularity: 34.903162,
|
|
URL: "https://github.com/Jguer/yay",
|
|
URLPath: "/cgit/aur.git/snapshot/yay.tar.gz",
|
|
Version: "12.5.7-1",
|
|
},
|
|
{
|
|
Description: "Yet another yogurt. Pacman wrapper and AUR helper written in go. (development version)",
|
|
FirstSubmitted: 1517205142,
|
|
ID: 1911143,
|
|
LastModified: 1765742519,
|
|
Maintainer: "jguer",
|
|
Name: "yay-git",
|
|
NumVotes: 55,
|
|
OutOfDate: 0,
|
|
PackageBase: "yay-git",
|
|
PackageBaseID: 129573,
|
|
Popularity: 1.850171,
|
|
URL: "https://github.com/Jguer/yay",
|
|
URLPath: "/cgit/aur.git/snapshot/yay-git.tar.gz",
|
|
Version: "12.5.7.r0.g44dfda05-1",
|
|
},
|
|
}, nil
|
|
},
|
|
}
|
|
|
|
return mockDB, mockAUR
|
|
}
|