list_test.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. package sprig
  2. import (
  3. "strings"
  4. "testing"
  5. "github.com/stretchr/testify/assert"
  6. )
  7. func TestTuple(t *testing.T) {
  8. tpl := `{{$t := tuple 1 "a" "foo"}}{{index $t 2}}{{index $t 0 }}{{index $t 1}}`
  9. if err := runt(tpl, "foo1a"); err != nil {
  10. t.Error(err)
  11. }
  12. }
  13. func TestList(t *testing.T) {
  14. tpl := `{{$t := list 1 "a" "foo"}}{{index $t 2}}{{index $t 0 }}{{index $t 1}}`
  15. if err := runt(tpl, "foo1a"); err != nil {
  16. t.Error(err)
  17. }
  18. }
  19. func TestPush(t *testing.T) {
  20. // Named `append` in the function map
  21. tests := map[string]string{
  22. `{{ $t := tuple 1 2 3 }}{{ append $t 4 | len }}`: "4",
  23. `{{ $t := tuple 1 2 3 4 }}{{ append $t 5 | join "-" }}`: "1-2-3-4-5",
  24. `{{ $t := regexSplit "/" "foo/bar/baz" -1 }}{{ append $t "qux" | join "-" }}`: "foo-bar-baz-qux",
  25. }
  26. for tpl, expect := range tests {
  27. assert.NoError(t, runt(tpl, expect))
  28. }
  29. }
  30. func TestMustPush(t *testing.T) {
  31. // Named `append` in the function map
  32. tests := map[string]string{
  33. `{{ $t := tuple 1 2 3 }}{{ mustAppend $t 4 | len }}`: "4",
  34. `{{ $t := tuple 1 2 3 4 }}{{ mustAppend $t 5 | join "-" }}`: "1-2-3-4-5",
  35. `{{ $t := regexSplit "/" "foo/bar/baz" -1 }}{{ mustPush $t "qux" | join "-" }}`: "foo-bar-baz-qux",
  36. }
  37. for tpl, expect := range tests {
  38. assert.NoError(t, runt(tpl, expect))
  39. }
  40. }
  41. func TestChunk(t *testing.T) {
  42. tests := map[string]string{
  43. `{{ tuple 1 2 3 4 5 6 7 | chunk 3 | len }}`: "3",
  44. `{{ tuple | chunk 3 | len }}`: "0",
  45. `{{ range ( tuple 1 2 3 4 5 6 7 8 9 | chunk 3 ) }}{{. | join "-"}}|{{end}}`: "1-2-3|4-5-6|7-8-9|",
  46. `{{ range ( tuple 1 2 3 4 5 6 7 8 | chunk 3 ) }}{{. | join "-"}}|{{end}}`: "1-2-3|4-5-6|7-8|",
  47. `{{ range ( tuple 1 2 | chunk 3 ) }}{{. | join "-"}}|{{end}}`: "1-2|",
  48. }
  49. for tpl, expect := range tests {
  50. assert.NoError(t, runt(tpl, expect))
  51. }
  52. }
  53. func TestMustChunk(t *testing.T) {
  54. tests := map[string]string{
  55. `{{ tuple 1 2 3 4 5 6 7 | mustChunk 3 | len }}`: "3",
  56. `{{ tuple | mustChunk 3 | len }}`: "0",
  57. `{{ range ( tuple 1 2 3 4 5 6 7 8 9 | mustChunk 3 ) }}{{. | join "-"}}|{{end}}`: "1-2-3|4-5-6|7-8-9|",
  58. `{{ range ( tuple 1 2 3 4 5 6 7 8 | mustChunk 3 ) }}{{. | join "-"}}|{{end}}`: "1-2-3|4-5-6|7-8|",
  59. `{{ range ( tuple 1 2 | mustChunk 3 ) }}{{. | join "-"}}|{{end}}`: "1-2|",
  60. }
  61. for tpl, expect := range tests {
  62. assert.NoError(t, runt(tpl, expect))
  63. }
  64. err := runt(`{{ tuple `+strings.Repeat(" 0", 10001)+` | mustChunk 1 }}`, "a")
  65. assert.ErrorContains(t, err, "number of chunks 10001 exceeds maximum limit of 10000")
  66. }
  67. func TestPrepend(t *testing.T) {
  68. tests := map[string]string{
  69. `{{ $t := tuple 1 2 3 }}{{ prepend $t 0 | len }}`: "4",
  70. `{{ $t := tuple 1 2 3 4 }}{{ prepend $t 0 | join "-" }}`: "0-1-2-3-4",
  71. `{{ $t := regexSplit "/" "foo/bar/baz" -1 }}{{ prepend $t "qux" | join "-" }}`: "qux-foo-bar-baz",
  72. }
  73. for tpl, expect := range tests {
  74. assert.NoError(t, runt(tpl, expect))
  75. }
  76. }
  77. func TestMustPrepend(t *testing.T) {
  78. tests := map[string]string{
  79. `{{ $t := tuple 1 2 3 }}{{ mustPrepend $t 0 | len }}`: "4",
  80. `{{ $t := tuple 1 2 3 4 }}{{ mustPrepend $t 0 | join "-" }}`: "0-1-2-3-4",
  81. `{{ $t := regexSplit "/" "foo/bar/baz" -1 }}{{ mustPrepend $t "qux" | join "-" }}`: "qux-foo-bar-baz",
  82. }
  83. for tpl, expect := range tests {
  84. assert.NoError(t, runt(tpl, expect))
  85. }
  86. }
  87. func TestFirst(t *testing.T) {
  88. tests := map[string]string{
  89. `{{ list 1 2 3 | first }}`: "1",
  90. `{{ list | first }}`: "<no value>",
  91. `{{ regexSplit "/src/" "foo/src/bar" -1 | first }}`: "foo",
  92. }
  93. for tpl, expect := range tests {
  94. assert.NoError(t, runt(tpl, expect))
  95. }
  96. }
  97. func TestMustFirst(t *testing.T) {
  98. tests := map[string]string{
  99. `{{ list 1 2 3 | mustFirst }}`: "1",
  100. `{{ list | mustFirst }}`: "<no value>",
  101. `{{ regexSplit "/src/" "foo/src/bar" -1 | mustFirst }}`: "foo",
  102. }
  103. for tpl, expect := range tests {
  104. assert.NoError(t, runt(tpl, expect))
  105. }
  106. }
  107. func TestLast(t *testing.T) {
  108. tests := map[string]string{
  109. `{{ list 1 2 3 | last }}`: "3",
  110. `{{ list | last }}`: "<no value>",
  111. `{{ regexSplit "/src/" "foo/src/bar" -1 | last }}`: "bar",
  112. }
  113. for tpl, expect := range tests {
  114. assert.NoError(t, runt(tpl, expect))
  115. }
  116. }
  117. func TestMustLast(t *testing.T) {
  118. tests := map[string]string{
  119. `{{ list 1 2 3 | mustLast }}`: "3",
  120. `{{ list | mustLast }}`: "<no value>",
  121. `{{ regexSplit "/src/" "foo/src/bar" -1 | mustLast }}`: "bar",
  122. }
  123. for tpl, expect := range tests {
  124. assert.NoError(t, runt(tpl, expect))
  125. }
  126. }
  127. func TestInitial(t *testing.T) {
  128. tests := map[string]string{
  129. `{{ list 1 2 3 | initial | len }}`: "2",
  130. `{{ list 1 2 3 | initial | last }}`: "2",
  131. `{{ list 1 2 3 | initial | first }}`: "1",
  132. `{{ list | initial }}`: "[]",
  133. `{{ regexSplit "/" "foo/bar/baz" -1 | initial }}`: "[foo bar]",
  134. }
  135. for tpl, expect := range tests {
  136. assert.NoError(t, runt(tpl, expect))
  137. }
  138. }
  139. func TestMustInitial(t *testing.T) {
  140. tests := map[string]string{
  141. `{{ list 1 2 3 | mustInitial | len }}`: "2",
  142. `{{ list 1 2 3 | mustInitial | last }}`: "2",
  143. `{{ list 1 2 3 | mustInitial | first }}`: "1",
  144. `{{ list | mustInitial }}`: "[]",
  145. `{{ regexSplit "/" "foo/bar/baz" -1 | mustInitial }}`: "[foo bar]",
  146. }
  147. for tpl, expect := range tests {
  148. assert.NoError(t, runt(tpl, expect))
  149. }
  150. }
  151. func TestRest(t *testing.T) {
  152. tests := map[string]string{
  153. `{{ list 1 2 3 | rest | len }}`: "2",
  154. `{{ list 1 2 3 | rest | last }}`: "3",
  155. `{{ list 1 2 3 | rest | first }}`: "2",
  156. `{{ list | rest }}`: "[]",
  157. `{{ regexSplit "/" "foo/bar/baz" -1 | rest }}`: "[bar baz]",
  158. }
  159. for tpl, expect := range tests {
  160. assert.NoError(t, runt(tpl, expect))
  161. }
  162. }
  163. func TestMustRest(t *testing.T) {
  164. tests := map[string]string{
  165. `{{ list 1 2 3 | mustRest | len }}`: "2",
  166. `{{ list 1 2 3 | mustRest | last }}`: "3",
  167. `{{ list 1 2 3 | mustRest | first }}`: "2",
  168. `{{ list | mustRest }}`: "[]",
  169. `{{ regexSplit "/" "foo/bar/baz" -1 | mustRest }}`: "[bar baz]",
  170. }
  171. for tpl, expect := range tests {
  172. assert.NoError(t, runt(tpl, expect))
  173. }
  174. }
  175. func TestReverse(t *testing.T) {
  176. tests := map[string]string{
  177. `{{ list 1 2 3 | reverse | first }}`: "3",
  178. `{{ list 1 2 3 | reverse | rest | first }}`: "2",
  179. `{{ list 1 2 3 | reverse | last }}`: "1",
  180. `{{ list 1 2 3 4 | reverse }}`: "[4 3 2 1]",
  181. `{{ list 1 | reverse }}`: "[1]",
  182. `{{ list | reverse }}`: "[]",
  183. `{{ regexSplit "/" "foo/bar/baz" -1 | reverse }}`: "[baz bar foo]",
  184. }
  185. for tpl, expect := range tests {
  186. assert.NoError(t, runt(tpl, expect))
  187. }
  188. }
  189. func TestMustReverse(t *testing.T) {
  190. tests := map[string]string{
  191. `{{ list 1 2 3 | mustReverse | first }}`: "3",
  192. `{{ list 1 2 3 | mustReverse | rest | first }}`: "2",
  193. `{{ list 1 2 3 | mustReverse | last }}`: "1",
  194. `{{ list 1 2 3 4 | mustReverse }}`: "[4 3 2 1]",
  195. `{{ list 1 | mustReverse }}`: "[1]",
  196. `{{ list | mustReverse }}`: "[]",
  197. `{{ regexSplit "/" "foo/bar/baz" -1 | mustReverse }}`: "[baz bar foo]",
  198. }
  199. for tpl, expect := range tests {
  200. assert.NoError(t, runt(tpl, expect))
  201. }
  202. }
  203. func TestCompact(t *testing.T) {
  204. tests := map[string]string{
  205. `{{ list 1 0 "" "hello" | compact }}`: `[1 hello]`,
  206. `{{ list "" "" | compact }}`: `[]`,
  207. `{{ list | compact }}`: `[]`,
  208. `{{ regexSplit "/" "foo//bar" -1 | compact }}`: "[foo bar]",
  209. }
  210. for tpl, expect := range tests {
  211. assert.NoError(t, runt(tpl, expect))
  212. }
  213. }
  214. func TestMustCompact(t *testing.T) {
  215. tests := map[string]string{
  216. `{{ list 1 0 "" "hello" | mustCompact }}`: `[1 hello]`,
  217. `{{ list "" "" | mustCompact }}`: `[]`,
  218. `{{ list | mustCompact }}`: `[]`,
  219. `{{ regexSplit "/" "foo//bar" -1 | mustCompact }}`: "[foo bar]",
  220. }
  221. for tpl, expect := range tests {
  222. assert.NoError(t, runt(tpl, expect))
  223. }
  224. }
  225. func TestUniq(t *testing.T) {
  226. tests := map[string]string{
  227. `{{ list 1 2 3 4 | uniq }}`: `[1 2 3 4]`,
  228. `{{ list "a" "b" "c" "d" | uniq }}`: `[a b c d]`,
  229. `{{ list 1 1 1 1 2 2 2 2 | uniq }}`: `[1 2]`,
  230. `{{ list "foo" 1 1 1 1 "foo" "foo" | uniq }}`: `[foo 1]`,
  231. `{{ list | uniq }}`: `[]`,
  232. `{{ regexSplit "/" "foo/foo/bar" -1 | uniq }}`: "[foo bar]",
  233. }
  234. for tpl, expect := range tests {
  235. assert.NoError(t, runt(tpl, expect))
  236. }
  237. }
  238. func TestMustUniq(t *testing.T) {
  239. tests := map[string]string{
  240. `{{ list 1 2 3 4 | mustUniq }}`: `[1 2 3 4]`,
  241. `{{ list "a" "b" "c" "d" | mustUniq }}`: `[a b c d]`,
  242. `{{ list 1 1 1 1 2 2 2 2 | mustUniq }}`: `[1 2]`,
  243. `{{ list "foo" 1 1 1 1 "foo" "foo" | mustUniq }}`: `[foo 1]`,
  244. `{{ list | mustUniq }}`: `[]`,
  245. `{{ regexSplit "/" "foo/foo/bar" -1 | mustUniq }}`: "[foo bar]",
  246. }
  247. for tpl, expect := range tests {
  248. assert.NoError(t, runt(tpl, expect))
  249. }
  250. }
  251. func TestWithout(t *testing.T) {
  252. tests := map[string]string{
  253. `{{ without (list 1 2 3 4) 1 }}`: `[2 3 4]`,
  254. `{{ without (list "a" "b" "c" "d") "a" }}`: `[b c d]`,
  255. `{{ without (list 1 1 1 1 2) 1 }}`: `[2]`,
  256. `{{ without (list) 1 }}`: `[]`,
  257. `{{ without (list 1 2 3) }}`: `[1 2 3]`,
  258. `{{ without list }}`: `[]`,
  259. `{{ without (regexSplit "/" "foo/bar/baz" -1 ) "foo" }}`: "[bar baz]",
  260. }
  261. for tpl, expect := range tests {
  262. assert.NoError(t, runt(tpl, expect))
  263. }
  264. }
  265. func TestMustWithout(t *testing.T) {
  266. tests := map[string]string{
  267. `{{ mustWithout (list 1 2 3 4) 1 }}`: `[2 3 4]`,
  268. `{{ mustWithout (list "a" "b" "c" "d") "a" }}`: `[b c d]`,
  269. `{{ mustWithout (list 1 1 1 1 2) 1 }}`: `[2]`,
  270. `{{ mustWithout (list) 1 }}`: `[]`,
  271. `{{ mustWithout (list 1 2 3) }}`: `[1 2 3]`,
  272. `{{ mustWithout list }}`: `[]`,
  273. `{{ mustWithout (regexSplit "/" "foo/bar/baz" -1 ) "foo" }}`: "[bar baz]",
  274. }
  275. for tpl, expect := range tests {
  276. assert.NoError(t, runt(tpl, expect))
  277. }
  278. }
  279. func TestHas(t *testing.T) {
  280. tests := map[string]string{
  281. `{{ list 1 2 3 | has 1 }}`: `true`,
  282. `{{ list 1 2 3 | has 4 }}`: `false`,
  283. `{{ regexSplit "/" "foo/bar/baz" -1 | has "bar" }}`: `true`,
  284. `{{ has "bar" nil }}`: `false`,
  285. }
  286. for tpl, expect := range tests {
  287. assert.NoError(t, runt(tpl, expect))
  288. }
  289. }
  290. func TestMustHas(t *testing.T) {
  291. tests := map[string]string{
  292. `{{ list 1 2 3 | mustHas 1 }}`: `true`,
  293. `{{ list 1 2 3 | mustHas 4 }}`: `false`,
  294. `{{ regexSplit "/" "foo/bar/baz" -1 | mustHas "bar" }}`: `true`,
  295. `{{ mustHas "bar" nil }}`: `false`,
  296. }
  297. for tpl, expect := range tests {
  298. assert.NoError(t, runt(tpl, expect))
  299. }
  300. }
  301. func TestSlice(t *testing.T) {
  302. tests := map[string]string{
  303. `{{ slice (list 1 2 3) }}`: "[1 2 3]",
  304. `{{ slice (list 1 2 3) 0 1 }}`: "[1]",
  305. `{{ slice (list 1 2 3) 1 3 }}`: "[2 3]",
  306. `{{ slice (list 1 2 3) 1 }}`: "[2 3]",
  307. `{{ slice (regexSplit "/" "foo/bar/baz" -1) 1 2 }}`: "[bar]",
  308. }
  309. for tpl, expect := range tests {
  310. assert.NoError(t, runt(tpl, expect))
  311. }
  312. }
  313. func TestMustSlice(t *testing.T) {
  314. tests := map[string]string{
  315. `{{ mustSlice (list 1 2 3) }}`: "[1 2 3]",
  316. `{{ mustSlice (list 1 2 3) 0 1 }}`: "[1]",
  317. `{{ mustSlice (list 1 2 3) 1 3 }}`: "[2 3]",
  318. `{{ mustSlice (list 1 2 3) 1 }}`: "[2 3]",
  319. `{{ mustSlice (regexSplit "/" "foo/bar/baz" -1) 1 2 }}`: "[bar]",
  320. }
  321. for tpl, expect := range tests {
  322. assert.NoError(t, runt(tpl, expect))
  323. }
  324. }
  325. func TestConcat(t *testing.T) {
  326. tests := map[string]string{
  327. `{{ concat (list 1 2 3) }}`: "[1 2 3]",
  328. `{{ concat (list 1 2 3) (list 4 5) }}`: "[1 2 3 4 5]",
  329. `{{ concat (list 1 2 3) (list 4 5) (list) }}`: "[1 2 3 4 5]",
  330. `{{ concat (list 1 2 3) (list 4 5) (list nil) }}`: "[1 2 3 4 5 <nil>]",
  331. `{{ concat (list 1 2 3) (list 4 5) (list ( list "foo" ) ) }}`: "[1 2 3 4 5 [foo]]",
  332. }
  333. for tpl, expect := range tests {
  334. assert.NoError(t, runt(tpl, expect))
  335. }
  336. }