print_test.go 7.3 KB

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