print_test.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. //go:build !integration
  2. // +build !integration
  3. package main
  4. import (
  5. "context"
  6. "fmt"
  7. "io"
  8. "os"
  9. "strings"
  10. "testing"
  11. "github.com/Jguer/aur"
  12. alpm "github.com/Jguer/go-alpm/v2"
  13. "github.com/stretchr/testify/assert"
  14. "github.com/stretchr/testify/require"
  15. "github.com/Jguer/yay/v12/pkg/db"
  16. "github.com/Jguer/yay/v12/pkg/db/mock"
  17. mockaur "github.com/Jguer/yay/v12/pkg/dep/mock"
  18. "github.com/Jguer/yay/v12/pkg/runtime"
  19. "github.com/Jguer/yay/v12/pkg/settings"
  20. "github.com/Jguer/yay/v12/pkg/settings/exe"
  21. "github.com/Jguer/yay/v12/pkg/settings/parser"
  22. "github.com/Jguer/yay/v12/pkg/text"
  23. "github.com/Jguer/yay/v12/pkg/vcs"
  24. )
  25. func TestPrintUpdateList(t *testing.T) {
  26. // The current method of capturing os.Stdout hinders parallelization.
  27. // Setting of global settings.NoConfirm in printUpdateList also hinders parallelization.
  28. // t.Parallel()
  29. pacmanBin := t.TempDir() + "/pacman"
  30. f, err := os.OpenFile(pacmanBin, os.O_RDONLY|os.O_CREATE, 0o755)
  31. require.NoError(t, err)
  32. require.NoError(t, f.Close())
  33. mockDBName := mock.NewDB("core")
  34. mockDB := &mock.DBExecutor{
  35. AlpmArchitecturesFn: func() ([]string, error) {
  36. return []string{"x86_64"}, nil
  37. },
  38. RefreshHandleFn: func() error {
  39. return nil
  40. },
  41. ReposFn: func() []string {
  42. return []string{"core"}
  43. },
  44. InstalledRemotePackagesFn: func() map[string]alpm.IPackage {
  45. return map[string]alpm.IPackage{
  46. "vosk-api": &mock.Package{
  47. PName: "vosk-api",
  48. PVersion: "0.3.43-1",
  49. PBase: "vosk-api",
  50. PReason: alpm.PkgReasonExplicit,
  51. },
  52. }
  53. },
  54. InstalledRemotePackageNamesFn: func() []string {
  55. return []string{"vosk-api"}
  56. },
  57. SyncUpgradesFn: func(
  58. bool,
  59. ) (map[string]db.SyncUpgrade, error) {
  60. return map[string]db.SyncUpgrade{
  61. "linux": {
  62. Package: &mock.Package{
  63. PName: "linux",
  64. PVersion: "5.10.0",
  65. PDB: mockDBName,
  66. },
  67. LocalVersion: "4.3.0",
  68. Reason: alpm.PkgReasonExplicit,
  69. },
  70. "go": {
  71. Package: &mock.Package{
  72. PName: "go",
  73. PVersion: "2:1.20.4-1",
  74. PDB: mockDBName,
  75. },
  76. LocalVersion: "2:1.20.3-1",
  77. Reason: alpm.PkgReasonExplicit,
  78. },
  79. }, nil
  80. },
  81. LocalPackageFn: func(s string) mock.IPackage {
  82. if s == "no-update-pkg" {
  83. return &mock.Package{
  84. PName: "no-update-pkg",
  85. PVersion: "3.3.3",
  86. PDB: mockDBName,
  87. }
  88. }
  89. return nil
  90. },
  91. SetLoggerFn: func(logger *text.Logger) {},
  92. }
  93. mockDBNoUpdates := &mock.DBExecutor{
  94. AlpmArchitecturesFn: func() ([]string, error) {
  95. return []string{"x86_64"}, nil
  96. },
  97. RefreshHandleFn: func() error {
  98. return nil
  99. },
  100. ReposFn: func() []string {
  101. return []string{"core"}
  102. },
  103. InstalledRemotePackagesFn: func() map[string]alpm.IPackage {
  104. return map[string]alpm.IPackage{
  105. "vosk-api": &mock.Package{
  106. PName: "vosk-api",
  107. PVersion: "0.3.43-1",
  108. PBase: "vosk-api",
  109. PReason: alpm.PkgReasonExplicit,
  110. },
  111. }
  112. },
  113. InstalledRemotePackageNamesFn: func() []string {
  114. return []string{"vosk-api"}
  115. },
  116. SyncUpgradesFn: func(
  117. bool,
  118. ) (map[string]db.SyncUpgrade, error) {
  119. return map[string]db.SyncUpgrade{}, nil
  120. },
  121. LocalPackageFn: func(s string) mock.IPackage {
  122. return nil
  123. },
  124. SetLoggerFn: func(logger *text.Logger) {},
  125. }
  126. mockAUR := &mockaur.MockAUR{
  127. GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
  128. return []aur.Pkg{
  129. {
  130. Name: "vosk-api",
  131. PackageBase: "vosk-api",
  132. Version: "0.3.45-1",
  133. },
  134. }, nil
  135. },
  136. }
  137. mockAURNoUpdates := &mockaur.MockAUR{
  138. GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
  139. return []aur.Pkg{
  140. {
  141. Name: "vosk-api",
  142. PackageBase: "vosk-api",
  143. Version: "0.3.43-1",
  144. },
  145. }, nil
  146. },
  147. }
  148. type mockData struct {
  149. db *mock.DBExecutor
  150. aurCache *mockaur.MockAUR
  151. }
  152. testCases := []struct {
  153. name string
  154. mockData mockData
  155. args []string
  156. targets []string
  157. wantPkgs []string
  158. wantErr bool
  159. }{
  160. {
  161. name: "Qu",
  162. mockData: mockData{mockDB, mockAUR},
  163. args: []string{"Q", "u"},
  164. targets: []string{},
  165. wantPkgs: []string{
  166. fmt.Sprintf("%s %s -> %s",
  167. text.Bold("linux"),
  168. text.Bold(text.Green("4.3.0")),
  169. text.Bold(text.Green("5.10.0")),
  170. ),
  171. fmt.Sprintf("%s %s -> %s",
  172. text.Bold("go"),
  173. text.Bold(text.Green("2:1.20.3-1")),
  174. text.Bold(text.Green("2:1.20.4-1")),
  175. ),
  176. fmt.Sprintf("%s %s -> %s",
  177. text.Bold("vosk-api"),
  178. text.Bold(text.Green("0.3.43-1")),
  179. text.Bold(text.Green("0.3.45-1")),
  180. ),
  181. },
  182. },
  183. {
  184. name: "Quq",
  185. mockData: mockData{mockDB, mockAUR},
  186. args: []string{"Q", "u", "q"},
  187. targets: []string{},
  188. wantPkgs: []string{"linux", "go", "vosk-api"},
  189. },
  190. {
  191. name: "Quq linux",
  192. mockData: mockData{mockDB, mockAUR},
  193. args: []string{"Q", "u", "q"},
  194. targets: []string{"linux"},
  195. wantPkgs: []string{"linux"},
  196. },
  197. {
  198. name: "Qunq",
  199. mockData: mockData{mockDB, mockAUR},
  200. args: []string{"Q", "u", "n", "q"},
  201. targets: []string{},
  202. wantPkgs: []string{"linux", "go"},
  203. },
  204. {
  205. name: "Qumq",
  206. mockData: mockData{mockDB, mockAUR},
  207. args: []string{"Q", "u", "m", "q"},
  208. targets: []string{},
  209. wantPkgs: []string{"vosk-api"},
  210. },
  211. {
  212. name: "Quq no-update-pkg",
  213. mockData: mockData{mockDB, mockAUR},
  214. args: []string{"Q", "u", "q"},
  215. targets: []string{"no-update-pkg"},
  216. wantPkgs: []string{},
  217. wantErr: true,
  218. },
  219. {
  220. name: "Quq non-existent-pkg",
  221. mockData: mockData{mockDB, mockAUR},
  222. args: []string{"Q", "u", "q"},
  223. targets: []string{"non-existent-pkg"},
  224. wantPkgs: []string{},
  225. wantErr: true,
  226. },
  227. {
  228. name: "Qu no-updates-any",
  229. mockData: mockData{mockDBNoUpdates, mockAURNoUpdates},
  230. args: []string{"Q", "u"},
  231. targets: []string{},
  232. wantPkgs: []string{},
  233. wantErr: true,
  234. },
  235. {
  236. name: "Qun no-updates-native",
  237. mockData: mockData{mockDBNoUpdates, mockAUR},
  238. args: []string{"Q", "u", "n"},
  239. targets: []string{},
  240. wantPkgs: []string{},
  241. wantErr: true,
  242. },
  243. {
  244. name: "Qum no-updates-foreign",
  245. mockData: mockData{mockDB, mockAURNoUpdates},
  246. args: []string{"Q", "u", "m"},
  247. targets: []string{},
  248. wantPkgs: []string{},
  249. wantErr: true,
  250. },
  251. }
  252. for _, tc := range testCases {
  253. t.Run(tc.name, func(t *testing.T) {
  254. cmdBuilder := &exe.CmdBuilder{
  255. SudoBin: "su",
  256. PacmanBin: pacmanBin,
  257. PacmanConfigPath: "/etc/pacman.conf",
  258. Runner: &exe.MockRunner{},
  259. SudoLoopEnabled: false,
  260. }
  261. r, w, _ := os.Pipe()
  262. logger := text.NewLogger(w, io.Discard, strings.NewReader(""), true, "test")
  263. run := &runtime.Runtime{
  264. Cfg: &settings.Configuration{
  265. RemoveMake: "no",
  266. },
  267. Logger: logger,
  268. CmdBuilder: cmdBuilder,
  269. VCSStore: &vcs.Mock{},
  270. AURClient: tc.mockData.aurCache,
  271. }
  272. cmdArgs := parser.MakeArguments()
  273. cmdArgs.AddArg(tc.args...)
  274. cmdArgs.AddTarget(tc.targets...)
  275. err = handleCmd(context.Background(), run, cmdArgs, tc.mockData.db)
  276. w.Close()
  277. out, _ := io.ReadAll(r)
  278. if tc.wantErr {
  279. require.Error(t, err)
  280. assert.EqualError(t, err, "")
  281. } else {
  282. require.NoError(t, err)
  283. }
  284. outStr := string(out)
  285. outPkgs := make([]string, 0)
  286. if outStr != "" {
  287. outPkgs = strings.Split(strings.TrimSuffix(outStr, "\n"), "\n")
  288. }
  289. assert.ElementsMatch(t, outPkgs, tc.wantPkgs, "Lists of packages should match")
  290. })
  291. }
  292. }