print_test.go 7.4 KB

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