query_builder_test.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. //go:build !integration
  2. // +build !integration
  3. package query
  4. import (
  5. "context"
  6. "io"
  7. "strings"
  8. "testing"
  9. "github.com/Jguer/aur"
  10. "github.com/Jguer/yay/v12/pkg/db/mock"
  11. mockaur "github.com/Jguer/yay/v12/pkg/dep/mock"
  12. "github.com/Jguer/yay/v12/pkg/settings/parser"
  13. "github.com/Jguer/yay/v12/pkg/text"
  14. "github.com/stretchr/testify/assert"
  15. )
  16. func TestSourceQueryBuilder(t *testing.T) {
  17. t.Parallel()
  18. type testCase struct {
  19. desc string
  20. search []string
  21. bottomUp bool
  22. separateSources bool
  23. sortBy string
  24. verbosity SearchVerbosity
  25. targetMode parser.TargetMode
  26. singleLineResults bool
  27. searchBy string
  28. wantResults []string
  29. wantOutput []string
  30. }
  31. testCases := []testCase{
  32. {
  33. desc: "sort-by-votes bottomup separatesources",
  34. search: []string{"linux"},
  35. bottomUp: true,
  36. separateSources: true,
  37. sortBy: "votes",
  38. verbosity: Detailed,
  39. wantResults: []string{"linux-ck", "linux-zen", "linux"},
  40. wantOutput: []string{
  41. "\x1b[1m\x1b[34maur\x1b[0m\x1b[0m/\x1b[1mlinux-ck\x1b[0m \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",
  42. "\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux-zen\x1b[0m \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux ZEN kernel and modules\n",
  43. "\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux\x1b[0m \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux kernel and modules\n",
  44. },
  45. },
  46. {
  47. desc: "sort-by-votes topdown separatesources",
  48. search: []string{"linux"},
  49. bottomUp: false,
  50. separateSources: true,
  51. sortBy: "votes",
  52. verbosity: Detailed,
  53. wantResults: []string{"linux", "linux-zen", "linux-ck"},
  54. wantOutput: []string{
  55. "\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux\x1b[0m \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux kernel and modules\n",
  56. "\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux-zen\x1b[0m \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux ZEN kernel and modules\n",
  57. "\x1b[1m\x1b[34maur\x1b[0m\x1b[0m/\x1b[1mlinux-ck\x1b[0m \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",
  58. },
  59. },
  60. {
  61. desc: "sort-by-votes bottomup noseparatesources",
  62. search: []string{"linux"},
  63. bottomUp: true,
  64. separateSources: false,
  65. sortBy: "votes",
  66. verbosity: Detailed,
  67. wantResults: []string{"linux-zen", "linux-ck", "linux"},
  68. wantOutput: []string{
  69. "\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux-zen\x1b[0m \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux ZEN kernel and modules\n",
  70. "\x1b[1m\x1b[34maur\x1b[0m\x1b[0m/\x1b[1mlinux-ck\x1b[0m \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",
  71. "\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux\x1b[0m \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux kernel and modules\n",
  72. },
  73. },
  74. {
  75. desc: "sort-by-votes topdown noseparatesources",
  76. search: []string{"linux"},
  77. bottomUp: false,
  78. separateSources: false,
  79. sortBy: "votes",
  80. verbosity: Detailed,
  81. wantResults: []string{"linux", "linux-ck", "linux-zen"},
  82. wantOutput: []string{
  83. "\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux\x1b[0m \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux kernel and modules\n",
  84. "\x1b[1m\x1b[34maur\x1b[0m\x1b[0m/\x1b[1mlinux-ck\x1b[0m \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",
  85. "\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux-zen\x1b[0m \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux ZEN kernel and modules\n",
  86. },
  87. },
  88. {
  89. desc: "sort-by-name bottomup separatesources",
  90. search: []string{"linux"},
  91. bottomUp: true,
  92. separateSources: true,
  93. sortBy: "name",
  94. verbosity: Detailed,
  95. wantResults: []string{"linux-ck", "linux", "linux-zen"},
  96. wantOutput: []string{
  97. "\x1b[1m\x1b[34maur\x1b[0m\x1b[0m/\x1b[1mlinux-ck\x1b[0m \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",
  98. "\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux\x1b[0m \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux kernel and modules\n",
  99. "\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux-zen\x1b[0m \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux ZEN kernel and modules\n",
  100. },
  101. },
  102. {
  103. desc: "sort-by-name topdown separatesources",
  104. search: []string{"linux"},
  105. bottomUp: false,
  106. separateSources: true,
  107. sortBy: "name",
  108. verbosity: Detailed,
  109. wantResults: []string{"linux-zen", "linux", "linux-ck"},
  110. wantOutput: []string{
  111. "\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux-zen\x1b[0m \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux ZEN kernel and modules\n",
  112. "\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux\x1b[0m \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux kernel and modules\n",
  113. "\x1b[1m\x1b[34maur\x1b[0m\x1b[0m/\x1b[1mlinux-ck\x1b[0m \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",
  114. },
  115. },
  116. {
  117. desc: "sort-by-name bottomup noseparatesources",
  118. search: []string{"linux"},
  119. bottomUp: true,
  120. separateSources: false,
  121. sortBy: "name",
  122. verbosity: Detailed,
  123. wantResults: []string{"linux", "linux-ck", "linux-zen"},
  124. wantOutput: []string{
  125. "\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux\x1b[0m \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux kernel and modules\n",
  126. "\x1b[1m\x1b[34maur\x1b[0m\x1b[0m/\x1b[1mlinux-ck\x1b[0m \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",
  127. "\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux-zen\x1b[0m \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux ZEN kernel and modules\n",
  128. },
  129. },
  130. {
  131. desc: "sort-by-name topdown noseparatesources",
  132. search: []string{"linux"},
  133. bottomUp: false,
  134. separateSources: false,
  135. sortBy: "name",
  136. verbosity: Detailed,
  137. wantResults: []string{"linux-zen", "linux-ck", "linux"},
  138. wantOutput: []string{
  139. "\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux-zen\x1b[0m \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux ZEN kernel and modules\n",
  140. "\x1b[1m\x1b[34maur\x1b[0m\x1b[0m/\x1b[1mlinux-ck\x1b[0m \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",
  141. "\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux\x1b[0m \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux kernel and modules\n",
  142. },
  143. },
  144. {
  145. desc: "sort-by-votes bottomup separatesources number-menu",
  146. search: []string{"linux"},
  147. bottomUp: true,
  148. separateSources: true,
  149. sortBy: "votes",
  150. verbosity: NumberMenu,
  151. wantResults: []string{"linux-ck", "linux-zen", "linux"},
  152. wantOutput: []string{
  153. "\x1b[35m3\x1b[0m \x1b[1m\x1b[34maur\x1b[0m\x1b[0m/\x1b[1mlinux-ck\x1b[0m \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",
  154. "\x1b[35m2\x1b[0m \x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux-zen\x1b[0m \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux ZEN kernel and modules\n",
  155. "\x1b[35m1\x1b[0m \x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux\x1b[0m \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux kernel and modules\n",
  156. },
  157. },
  158. {
  159. desc: "sort-by-votes topdown separatesources number-menu",
  160. search: []string{"linux"},
  161. bottomUp: false,
  162. separateSources: true,
  163. sortBy: "votes",
  164. verbosity: NumberMenu,
  165. wantResults: []string{"linux", "linux-zen", "linux-ck"},
  166. wantOutput: []string{
  167. "\x1b[35m1\x1b[0m \x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux\x1b[0m \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux kernel and modules\n",
  168. "\x1b[35m2\x1b[0m \x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux-zen\x1b[0m \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux ZEN kernel and modules\n",
  169. "\x1b[35m3\x1b[0m \x1b[1m\x1b[34maur\x1b[0m\x1b[0m/\x1b[1mlinux-ck\x1b[0m \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",
  170. },
  171. },
  172. {
  173. desc: "sort-by-name bottomup separatesources number-menu",
  174. search: []string{"linux"},
  175. bottomUp: true,
  176. separateSources: true,
  177. sortBy: "name",
  178. verbosity: NumberMenu,
  179. wantResults: []string{"linux-ck", "linux", "linux-zen"},
  180. wantOutput: []string{
  181. "\x1b[35m3\x1b[0m \x1b[1m\x1b[34maur\x1b[0m\x1b[0m/\x1b[1mlinux-ck\x1b[0m \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",
  182. "\x1b[35m2\x1b[0m \x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux\x1b[0m \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux kernel and modules\n",
  183. "\x1b[35m1\x1b[0m \x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux-zen\x1b[0m \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux ZEN kernel and modules\n",
  184. },
  185. },
  186. {
  187. desc: "sort-by-name topdown separatesources number-menu",
  188. search: []string{"linux"},
  189. bottomUp: false,
  190. separateSources: true,
  191. sortBy: "name",
  192. verbosity: NumberMenu,
  193. wantResults: []string{"linux-zen", "linux", "linux-ck"},
  194. wantOutput: []string{
  195. "\x1b[35m1\x1b[0m \x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux-zen\x1b[0m \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux ZEN kernel and modules\n",
  196. "\x1b[35m2\x1b[0m \x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux\x1b[0m \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\n The Linux kernel and modules\n",
  197. "\x1b[35m3\x1b[0m \x1b[1m\x1b[34maur\x1b[0m\x1b[0m/\x1b[1mlinux-ck\x1b[0m \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",
  198. },
  199. },
  200. {
  201. desc: "sort-by-name bottomup noseparatesources minimal",
  202. search: []string{"linux"},
  203. bottomUp: true,
  204. separateSources: false,
  205. sortBy: "name",
  206. verbosity: Minimal,
  207. wantResults: []string{"linux", "linux-ck", "linux-zen"},
  208. wantOutput: []string{
  209. "linux\n",
  210. "linux-ck\n",
  211. "linux-zen\n",
  212. },
  213. },
  214. {
  215. desc: "only-aur minimal",
  216. search: []string{"linux"},
  217. bottomUp: true,
  218. separateSources: true,
  219. sortBy: "name",
  220. verbosity: Minimal,
  221. targetMode: parser.ModeAUR,
  222. wantResults: []string{"linux-ck"},
  223. wantOutput: []string{
  224. "linux-ck\n",
  225. },
  226. },
  227. {
  228. desc: "only-repo minimal",
  229. search: []string{"linux"},
  230. bottomUp: true,
  231. separateSources: true,
  232. sortBy: "name",
  233. verbosity: Minimal,
  234. targetMode: parser.ModeRepo,
  235. wantResults: []string{"linux", "linux-zen"},
  236. wantOutput: []string{
  237. "linux\n",
  238. "linux-zen\n",
  239. },
  240. },
  241. {
  242. desc: "sort-by-name singleline",
  243. search: []string{"linux"},
  244. bottomUp: true,
  245. separateSources: true,
  246. sortBy: "name",
  247. verbosity: Detailed,
  248. singleLineResults: true,
  249. wantResults: []string{"linux-ck", "linux", "linux-zen"},
  250. wantOutput: []string{
  251. "\x1b[1m\x1b[34maur\x1b[0m\x1b[0m/\x1b[1mlinux-ck\x1b[0m \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",
  252. "\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux\x1b[0m \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\tThe Linux kernel and modules\n",
  253. "\x1b[1m\x1b[33mcore\x1b[0m\x1b[0m/\x1b[1mlinux-zen\x1b[0m \x1b[36m5.16.0\x1b[0m\x1b[1m (1.0 B 1.0 B) \x1b[0m\tThe Linux ZEN kernel and modules\n",
  254. },
  255. },
  256. {
  257. desc: "sort-by-name search-by-name",
  258. search: []string{"linux-ck"},
  259. bottomUp: true,
  260. separateSources: true,
  261. sortBy: "name",
  262. verbosity: Detailed,
  263. searchBy: "name",
  264. targetMode: parser.ModeAUR,
  265. wantResults: []string{"linux-ck"},
  266. wantOutput: []string{
  267. "\x1b[1m\x1b[34maur\x1b[0m\x1b[0m/\x1b[1mlinux-ck\x1b[0m \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",
  268. },
  269. },
  270. {
  271. desc: "only-aur search-by-several-terms",
  272. search: []string{"linux-ck", "hrtimer"},
  273. bottomUp: true,
  274. separateSources: true,
  275. verbosity: Detailed,
  276. targetMode: parser.ModeAUR,
  277. wantResults: []string{"linux-ck"},
  278. wantOutput: []string{
  279. "\x1b[1m\x1b[34maur\x1b[0m\x1b[0m/\x1b[1mlinux-ck\x1b[0m \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",
  280. },
  281. },
  282. }
  283. mockDB := &mock.DBExecutor{
  284. SyncPackagesFn: func(pkgs ...string) []mock.IPackage {
  285. mockDB := mock.NewDB("core")
  286. return []mock.IPackage{
  287. &mock.Package{
  288. PName: "linux",
  289. PVersion: "5.16.0",
  290. PDescription: "The Linux kernel and modules",
  291. PSize: 1,
  292. PISize: 1,
  293. PDB: mockDB,
  294. },
  295. &mock.Package{
  296. PName: "linux-zen",
  297. PVersion: "5.16.0",
  298. PDescription: "The Linux ZEN kernel and modules",
  299. PSize: 1,
  300. PISize: 1,
  301. PDB: mockDB,
  302. },
  303. }
  304. },
  305. LocalPackageFn: func(string) mock.IPackage {
  306. return nil
  307. },
  308. }
  309. mockAUR := &mockaur.MockAUR{
  310. GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
  311. return []aur.Pkg{
  312. {
  313. Description: "The Linux-ck kernel and modules with ck's hrtimer patches",
  314. FirstSubmitted: 1311346274,
  315. ID: 1045311,
  316. LastModified: 1646250901,
  317. Maintainer: "graysky",
  318. Name: "linux-ck",
  319. NumVotes: 450,
  320. OutOfDate: 0,
  321. PackageBase: "linux-ck",
  322. PackageBaseID: 50911,
  323. Popularity: 1.511141,
  324. URL: "https://wiki.archlinux.org/index.php/Linux-ck",
  325. URLPath: "/cgit/aur.git/snapshot/linux-ck.tar.gz",
  326. Version: "5.16.12-1",
  327. },
  328. }, nil
  329. },
  330. }
  331. for _, tc := range testCases {
  332. t.Run(tc.desc, func(t *testing.T) {
  333. w := &strings.Builder{}
  334. queryBuilder := NewSourceQueryBuilder(mockAUR,
  335. text.NewLogger(w, io.Discard, strings.NewReader(""), false, "test"),
  336. tc.sortBy, tc.targetMode, tc.searchBy, tc.bottomUp,
  337. tc.singleLineResults, tc.separateSources)
  338. queryBuilder.Execute(context.Background(), mockDB, tc.search)
  339. assert.Len(t, queryBuilder.results, len(tc.wantResults))
  340. assert.Equal(t, len(tc.wantResults), queryBuilder.Len())
  341. for i, name := range tc.wantResults {
  342. assert.Equal(t, name, queryBuilder.results[i].name)
  343. }
  344. queryBuilder.Results(mockDB, tc.verbosity)
  345. assert.Equal(t, strings.Join(tc.wantOutput, ""), w.String())
  346. })
  347. }
  348. }