]> git.saurik.com Git - redis.git/blob - tests/unit/type/list.tcl
8f58cc5fe316d5ca11bfa8bef4cdedffa4c207b5
[redis.git] / tests / unit / type / list.tcl
1 start_server {
2 tags {"list"}
3 overrides {
4 "list-max-ziplist-value" 16
5 "list-max-ziplist-entries" 256
6 }
7 } {
8 source "tests/unit/type/list-common.tcl"
9
10 test {LPUSH, RPUSH, LLENGTH, LINDEX - ziplist} {
11 # first lpush then rpush
12 assert_equal 1 [r lpush myziplist1 a]
13 assert_equal 2 [r rpush myziplist1 b]
14 assert_equal 3 [r rpush myziplist1 c]
15 assert_equal 3 [r llen myziplist1]
16 assert_equal a [r lindex myziplist1 0]
17 assert_equal b [r lindex myziplist1 1]
18 assert_equal c [r lindex myziplist1 2]
19 assert_encoding ziplist myziplist1
20
21 # first rpush then lpush
22 assert_equal 1 [r rpush myziplist2 a]
23 assert_equal 2 [r lpush myziplist2 b]
24 assert_equal 3 [r lpush myziplist2 c]
25 assert_equal 3 [r llen myziplist2]
26 assert_equal c [r lindex myziplist2 0]
27 assert_equal b [r lindex myziplist2 1]
28 assert_equal a [r lindex myziplist2 2]
29 assert_encoding ziplist myziplist2
30 }
31
32 test {LPUSH, RPUSH, LLENGTH, LINDEX - regular list} {
33 # first lpush then rpush
34 assert_equal 1 [r lpush mylist1 $largevalue(linkedlist)]
35 assert_encoding linkedlist mylist1
36 assert_equal 2 [r rpush mylist1 b]
37 assert_equal 3 [r rpush mylist1 c]
38 assert_equal 3 [r llen mylist1]
39 assert_equal $largevalue(linkedlist) [r lindex mylist1 0]
40 assert_equal b [r lindex mylist1 1]
41 assert_equal c [r lindex mylist1 2]
42
43 # first rpush then lpush
44 assert_equal 1 [r rpush mylist2 $largevalue(linkedlist)]
45 assert_encoding linkedlist mylist2
46 assert_equal 2 [r lpush mylist2 b]
47 assert_equal 3 [r lpush mylist2 c]
48 assert_equal 3 [r llen mylist2]
49 assert_equal c [r lindex mylist2 0]
50 assert_equal b [r lindex mylist2 1]
51 assert_equal $largevalue(linkedlist) [r lindex mylist2 2]
52 }
53
54 test {Variadic RPUSH/LPUSH} {
55 r del mylist
56 assert_equal 4 [r lpush mylist a b c d]
57 assert_equal 8 [r rpush mylist 0 1 2 3]
58 assert_equal {d c b a 0 1 2 3} [r lrange mylist 0 -1]
59 }
60
61 test {DEL a list - ziplist} {
62 assert_equal 1 [r del myziplist2]
63 assert_equal 0 [r exists myziplist2]
64 assert_equal 0 [r llen myziplist2]
65 }
66
67 test {DEL a list - regular list} {
68 assert_equal 1 [r del mylist2]
69 assert_equal 0 [r exists mylist2]
70 assert_equal 0 [r llen mylist2]
71 }
72
73 proc create_ziplist {key entries} {
74 r del $key
75 foreach entry $entries { r rpush $key $entry }
76 assert_encoding ziplist $key
77 }
78
79 proc create_linkedlist {key entries} {
80 r del $key
81 foreach entry $entries { r rpush $key $entry }
82 assert_encoding linkedlist $key
83 }
84
85 foreach {type large} [array get largevalue] {
86 test "BLPOP, BRPOP: single existing list - $type" {
87 set rd [redis_deferring_client]
88 create_$type blist "a b $large c d"
89
90 $rd blpop blist 1
91 assert_equal {blist a} [$rd read]
92 $rd brpop blist 1
93 assert_equal {blist d} [$rd read]
94
95 $rd blpop blist 1
96 assert_equal {blist b} [$rd read]
97 $rd brpop blist 1
98 assert_equal {blist c} [$rd read]
99 }
100
101 test "BLPOP, BRPOP: multiple existing lists - $type" {
102 set rd [redis_deferring_client]
103 create_$type blist1 "a $large c"
104 create_$type blist2 "d $large f"
105
106 $rd blpop blist1 blist2 1
107 assert_equal {blist1 a} [$rd read]
108 $rd brpop blist1 blist2 1
109 assert_equal {blist1 c} [$rd read]
110 assert_equal 1 [r llen blist1]
111 assert_equal 3 [r llen blist2]
112
113 $rd blpop blist2 blist1 1
114 assert_equal {blist2 d} [$rd read]
115 $rd brpop blist2 blist1 1
116 assert_equal {blist2 f} [$rd read]
117 assert_equal 1 [r llen blist1]
118 assert_equal 1 [r llen blist2]
119 }
120
121 test "BLPOP, BRPOP: second list has an entry - $type" {
122 set rd [redis_deferring_client]
123 r del blist1
124 create_$type blist2 "d $large f"
125
126 $rd blpop blist1 blist2 1
127 assert_equal {blist2 d} [$rd read]
128 $rd brpop blist1 blist2 1
129 assert_equal {blist2 f} [$rd read]
130 assert_equal 0 [r llen blist1]
131 assert_equal 1 [r llen blist2]
132 }
133
134 test "BRPOPLPUSH - $type" {
135 r del target
136
137 set rd [redis_deferring_client]
138 create_$type blist "a b $large c d"
139
140 $rd brpoplpush blist target 1
141 assert_equal d [$rd read]
142
143 assert_equal d [r rpop target]
144 assert_equal "a b $large c" [r lrange blist 0 -1]
145 }
146 }
147
148 test "BLPOP with variadic LPUSH" {
149 set rd [redis_deferring_client]
150 r del blist target
151 $rd blpop blist 0
152 assert_equal 2 [r lpush blist foo bar]
153 assert_equal {blist foo} [$rd read]
154 assert_equal bar [lindex [r lrange blist 0 -1] 0]
155 }
156
157 test "BRPOPLPUSH with zero timeout should block indefinitely" {
158 set rd [redis_deferring_client]
159 r del blist target
160 $rd brpoplpush blist target 0
161 after 1000
162 r rpush blist foo
163 assert_equal foo [$rd read]
164 assert_equal {foo} [r lrange target 0 -1]
165 }
166
167 test "BRPOPLPUSH with a client BLPOPing the target list" {
168 set rd [redis_deferring_client]
169 set rd2 [redis_deferring_client]
170 r del blist target
171 $rd2 blpop target 0
172 $rd brpoplpush blist target 0
173 after 1000
174 r rpush blist foo
175 assert_equal foo [$rd read]
176 assert_equal {target foo} [$rd2 read]
177 assert_equal 0 [r exists target]
178 }
179
180 test "BRPOPLPUSH with wrong source type" {
181 set rd [redis_deferring_client]
182 r del blist target
183 r set blist nolist
184 $rd brpoplpush blist target 1
185 assert_error "ERR*wrong kind*" {$rd read}
186 }
187
188 test "BRPOPLPUSH with wrong destination type" {
189 set rd [redis_deferring_client]
190 r del blist target
191 r set target nolist
192 r lpush blist foo
193 $rd brpoplpush blist target 1
194 assert_error "ERR*wrong kind*" {$rd read}
195
196 set rd [redis_deferring_client]
197 r del blist target
198 r set target nolist
199 $rd brpoplpush blist target 0
200 after 1000
201 r rpush blist foo
202 assert_error "ERR*wrong kind*" {$rd read}
203 assert_equal {foo} [r lrange blist 0 -1]
204 }
205
206 test "BRPOPLPUSH with multiple blocked clients" {
207 set rd1 [redis_deferring_client]
208 set rd2 [redis_deferring_client]
209 r del blist target1 target2
210 r set target1 nolist
211 $rd1 brpoplpush blist target1 0
212 $rd2 brpoplpush blist target2 0
213 r lpush blist foo
214
215 assert_error "ERR*wrong kind*" {$rd1 read}
216 assert_equal {foo} [$rd2 read]
217 assert_equal {foo} [r lrange target2 0 -1]
218 }
219
220 test "Linked BRPOPLPUSH" {
221 set rd1 [redis_deferring_client]
222 set rd2 [redis_deferring_client]
223
224 r del list1 list2 list3
225
226 $rd1 brpoplpush list1 list2 0
227 $rd2 brpoplpush list2 list3 0
228
229 r rpush list1 foo
230
231 assert_equal {} [r lrange list1 0 -1]
232 assert_equal {} [r lrange list2 0 -1]
233 assert_equal {foo} [r lrange list3 0 -1]
234 }
235
236 test "Circular BRPOPLPUSH" {
237 set rd1 [redis_deferring_client]
238 set rd2 [redis_deferring_client]
239
240 r del list1 list2
241
242 $rd1 brpoplpush list1 list2 0
243 $rd2 brpoplpush list2 list1 0
244
245 r rpush list1 foo
246
247 assert_equal {foo} [r lrange list1 0 -1]
248 assert_equal {} [r lrange list2 0 -1]
249 }
250
251 test "Self-referential BRPOPLPUSH" {
252 set rd [redis_deferring_client]
253
254 r del blist
255
256 $rd brpoplpush blist blist 0
257
258 r rpush blist foo
259
260 assert_equal {foo} [r lrange blist 0 -1]
261 }
262
263 test "BRPOPLPUSH inside a transaction" {
264 r del xlist target
265 r lpush xlist foo
266 r lpush xlist bar
267
268 r multi
269 r brpoplpush xlist target 0
270 r brpoplpush xlist target 0
271 r brpoplpush xlist target 0
272 r lrange xlist 0 -1
273 r lrange target 0 -1
274 r exec
275 } {foo bar {} {} {bar foo}}
276
277 test {BRPOPLPUSH timeout} {
278 set rd [redis_deferring_client]
279
280 $rd brpoplpush foo_list bar_list 1
281 after 2000
282 $rd read
283 } {}
284
285 foreach {pop} {BLPOP BRPOP} {
286 test "$pop: with single empty list argument" {
287 set rd [redis_deferring_client]
288 r del blist1
289 $rd $pop blist1 1
290 r rpush blist1 foo
291 assert_equal {blist1 foo} [$rd read]
292 assert_equal 0 [r exists blist1]
293 }
294
295 test "$pop: with negative timeout" {
296 set rd [redis_deferring_client]
297 $rd $pop blist1 -1
298 assert_error "ERR*is negative*" {$rd read}
299 }
300
301 test "$pop: with non-integer timeout" {
302 set rd [redis_deferring_client]
303 $rd $pop blist1 1.1
304 assert_error "ERR*not an integer*" {$rd read}
305 }
306
307 test "$pop: with zero timeout should block indefinitely" {
308 # To test this, use a timeout of 0 and wait a second.
309 # The blocking pop should still be waiting for a push.
310 set rd [redis_deferring_client]
311 $rd $pop blist1 0
312 after 1000
313 r rpush blist1 foo
314 assert_equal {blist1 foo} [$rd read]
315 }
316
317 test "$pop: second argument is not a list" {
318 set rd [redis_deferring_client]
319 r del blist1 blist2
320 r set blist2 nolist
321 $rd $pop blist1 blist2 1
322 assert_error "ERR*wrong kind*" {$rd read}
323 }
324
325 test "$pop: timeout" {
326 set rd [redis_deferring_client]
327 r del blist1 blist2
328 $rd $pop blist1 blist2 1
329 assert_equal {} [$rd read]
330 }
331
332 test "$pop: arguments are empty" {
333 set rd [redis_deferring_client]
334 r del blist1 blist2
335
336 $rd $pop blist1 blist2 1
337 r rpush blist1 foo
338 assert_equal {blist1 foo} [$rd read]
339 assert_equal 0 [r exists blist1]
340 assert_equal 0 [r exists blist2]
341
342 $rd $pop blist1 blist2 1
343 r rpush blist2 foo
344 assert_equal {blist2 foo} [$rd read]
345 assert_equal 0 [r exists blist1]
346 assert_equal 0 [r exists blist2]
347 }
348 }
349
350 test {BLPOP inside a transaction} {
351 r del xlist
352 r lpush xlist foo
353 r lpush xlist bar
354 r multi
355 r blpop xlist 0
356 r blpop xlist 0
357 r blpop xlist 0
358 r exec
359 } {{xlist bar} {xlist foo} {}}
360
361 test {LPUSHX, RPUSHX - generic} {
362 r del xlist
363 assert_equal 0 [r lpushx xlist a]
364 assert_equal 0 [r llen xlist]
365 assert_equal 0 [r rpushx xlist a]
366 assert_equal 0 [r llen xlist]
367 }
368
369 foreach {type large} [array get largevalue] {
370 test "LPUSHX, RPUSHX - $type" {
371 create_$type xlist "$large c"
372 assert_equal 3 [r rpushx xlist d]
373 assert_equal 4 [r lpushx xlist a]
374 assert_equal "a $large c d" [r lrange xlist 0 -1]
375 }
376
377 test "LINSERT - $type" {
378 create_$type xlist "a $large c d"
379 assert_equal 5 [r linsert xlist before c zz]
380 assert_equal "a $large zz c d" [r lrange xlist 0 10]
381 assert_equal 6 [r linsert xlist after c yy]
382 assert_equal "a $large zz c yy d" [r lrange xlist 0 10]
383 assert_equal 7 [r linsert xlist after d dd]
384 assert_equal -1 [r linsert xlist after bad ddd]
385 assert_equal "a $large zz c yy d dd" [r lrange xlist 0 10]
386 assert_equal 8 [r linsert xlist before a aa]
387 assert_equal -1 [r linsert xlist before bad aaa]
388 assert_equal "aa a $large zz c yy d dd" [r lrange xlist 0 10]
389
390 # check inserting integer encoded value
391 assert_equal 9 [r linsert xlist before aa 42]
392 assert_equal 42 [r lrange xlist 0 0]
393 }
394 }
395
396 test {LPUSHX, RPUSHX convert from ziplist to list} {
397 set large $largevalue(linkedlist)
398
399 # convert when a large value is pushed
400 create_ziplist xlist a
401 assert_equal 2 [r rpushx xlist $large]
402 assert_encoding linkedlist xlist
403 create_ziplist xlist a
404 assert_equal 2 [r lpushx xlist $large]
405 assert_encoding linkedlist xlist
406
407 # convert when the length threshold is exceeded
408 create_ziplist xlist [lrepeat 256 a]
409 assert_equal 257 [r rpushx xlist b]
410 assert_encoding linkedlist xlist
411 create_ziplist xlist [lrepeat 256 a]
412 assert_equal 257 [r lpushx xlist b]
413 assert_encoding linkedlist xlist
414 }
415
416 test {LINSERT convert from ziplist to list} {
417 set large $largevalue(linkedlist)
418
419 # convert when a large value is inserted
420 create_ziplist xlist a
421 assert_equal 2 [r linsert xlist before a $large]
422 assert_encoding linkedlist xlist
423 create_ziplist xlist a
424 assert_equal 2 [r linsert xlist after a $large]
425 assert_encoding linkedlist xlist
426
427 # convert when the length threshold is exceeded
428 create_ziplist xlist [lrepeat 256 a]
429 assert_equal 257 [r linsert xlist before a a]
430 assert_encoding linkedlist xlist
431 create_ziplist xlist [lrepeat 256 a]
432 assert_equal 257 [r linsert xlist after a a]
433 assert_encoding linkedlist xlist
434
435 # don't convert when the value could not be inserted
436 create_ziplist xlist [lrepeat 256 a]
437 assert_equal -1 [r linsert xlist before foo a]
438 assert_encoding ziplist xlist
439 create_ziplist xlist [lrepeat 256 a]
440 assert_equal -1 [r linsert xlist after foo a]
441 assert_encoding ziplist xlist
442 }
443
444 foreach {type num} {ziplist 250 linkedlist 500} {
445 proc check_numbered_list_consistency {key} {
446 set len [r llen $key]
447 for {set i 0} {$i < $len} {incr i} {
448 assert_equal $i [r lindex $key $i]
449 assert_equal [expr $len-1-$i] [r lindex $key [expr (-$i)-1]]
450 }
451 }
452
453 proc check_random_access_consistency {key} {
454 set len [r llen $key]
455 for {set i 0} {$i < $len} {incr i} {
456 set rint [expr int(rand()*$len)]
457 assert_equal $rint [r lindex $key $rint]
458 assert_equal [expr $len-1-$rint] [r lindex $key [expr (-$rint)-1]]
459 }
460 }
461
462 test "LINDEX consistency test - $type" {
463 r del mylist
464 for {set i 0} {$i < $num} {incr i} {
465 r rpush mylist $i
466 }
467 assert_encoding $type mylist
468 check_numbered_list_consistency mylist
469 }
470
471 test "LINDEX random access - $type" {
472 assert_encoding $type mylist
473 check_random_access_consistency mylist
474 }
475
476 test "Check if list is still ok after a DEBUG RELOAD - $type" {
477 r debug reload
478 assert_encoding $type mylist
479 check_numbered_list_consistency mylist
480 check_random_access_consistency mylist
481 }
482 }
483
484 test {LLEN against non-list value error} {
485 r del mylist
486 r set mylist foobar
487 assert_error ERR* {r llen mylist}
488 }
489
490 test {LLEN against non existing key} {
491 assert_equal 0 [r llen not-a-key]
492 }
493
494 test {LINDEX against non-list value error} {
495 assert_error ERR* {r lindex mylist 0}
496 }
497
498 test {LINDEX against non existing key} {
499 assert_equal "" [r lindex not-a-key 10]
500 }
501
502 test {LPUSH against non-list value error} {
503 assert_error ERR* {r lpush mylist 0}
504 }
505
506 test {RPUSH against non-list value error} {
507 assert_error ERR* {r rpush mylist 0}
508 }
509
510 foreach {type large} [array get largevalue] {
511 test "RPOPLPUSH base case - $type" {
512 r del mylist1 mylist2
513 create_$type mylist1 "a $large c d"
514 assert_equal d [r rpoplpush mylist1 mylist2]
515 assert_equal c [r rpoplpush mylist1 mylist2]
516 assert_equal "a $large" [r lrange mylist1 0 -1]
517 assert_equal "c d" [r lrange mylist2 0 -1]
518 assert_encoding ziplist mylist2
519 }
520
521 test "RPOPLPUSH with the same list as src and dst - $type" {
522 create_$type mylist "a $large c"
523 assert_equal "a $large c" [r lrange mylist 0 -1]
524 assert_equal c [r rpoplpush mylist mylist]
525 assert_equal "c a $large" [r lrange mylist 0 -1]
526 }
527
528 foreach {othertype otherlarge} [array get largevalue] {
529 test "RPOPLPUSH with $type source and existing target $othertype" {
530 create_$type srclist "a b c $large"
531 create_$othertype dstlist "$otherlarge"
532 assert_equal $large [r rpoplpush srclist dstlist]
533 assert_equal c [r rpoplpush srclist dstlist]
534 assert_equal "a b" [r lrange srclist 0 -1]
535 assert_equal "c $large $otherlarge" [r lrange dstlist 0 -1]
536
537 # When we rpoplpush'ed a large value, dstlist should be
538 # converted to the same encoding as srclist.
539 if {$type eq "linkedlist"} {
540 assert_encoding linkedlist dstlist
541 }
542 }
543 }
544 }
545
546 test {RPOPLPUSH against non existing key} {
547 r del srclist dstlist
548 assert_equal {} [r rpoplpush srclist dstlist]
549 assert_equal 0 [r exists srclist]
550 assert_equal 0 [r exists dstlist]
551 }
552
553 test {RPOPLPUSH against non list src key} {
554 r del srclist dstlist
555 r set srclist x
556 assert_error ERR* {r rpoplpush srclist dstlist}
557 assert_type string srclist
558 assert_equal 0 [r exists newlist]
559 }
560
561 test {RPOPLPUSH against non list dst key} {
562 create_ziplist srclist {a b c d}
563 r set dstlist x
564 assert_error ERR* {r rpoplpush srclist dstlist}
565 assert_type string dstlist
566 assert_equal {a b c d} [r lrange srclist 0 -1]
567 }
568
569 test {RPOPLPUSH against non existing src key} {
570 r del srclist dstlist
571 assert_equal {} [r rpoplpush srclist dstlist]
572 } {}
573
574 foreach {type large} [array get largevalue] {
575 test "Basic LPOP/RPOP - $type" {
576 create_$type mylist "$large 1 2"
577 assert_equal $large [r lpop mylist]
578 assert_equal 2 [r rpop mylist]
579 assert_equal 1 [r lpop mylist]
580 assert_equal 0 [r llen mylist]
581
582 # pop on empty list
583 assert_equal {} [r lpop mylist]
584 assert_equal {} [r rpop mylist]
585 }
586 }
587
588 test {LPOP/RPOP against non list value} {
589 r set notalist foo
590 assert_error ERR*kind* {r lpop notalist}
591 assert_error ERR*kind* {r rpop notalist}
592 }
593
594 foreach {type num} {ziplist 250 linkedlist 500} {
595 test "Mass RPOP/LPOP - $type" {
596 r del mylist
597 set sum1 0
598 for {set i 0} {$i < $num} {incr i} {
599 r lpush mylist $i
600 incr sum1 $i
601 }
602 assert_encoding $type mylist
603 set sum2 0
604 for {set i 0} {$i < [expr $num/2]} {incr i} {
605 incr sum2 [r lpop mylist]
606 incr sum2 [r rpop mylist]
607 }
608 assert_equal $sum1 $sum2
609 }
610 }
611
612 foreach {type large} [array get largevalue] {
613 test "LRANGE basics - $type" {
614 create_$type mylist "$large 1 2 3 4 5 6 7 8 9"
615 assert_equal {1 2 3 4 5 6 7 8} [r lrange mylist 1 -2]
616 assert_equal {7 8 9} [r lrange mylist -3 -1]
617 assert_equal {4} [r lrange mylist 4 4]
618 }
619
620 test "LRANGE inverted indexes - $type" {
621 create_$type mylist "$large 1 2 3 4 5 6 7 8 9"
622 assert_equal {} [r lrange mylist 6 2]
623 }
624
625 test "LRANGE out of range indexes including the full list - $type" {
626 create_$type mylist "$large 1 2 3"
627 assert_equal "$large 1 2 3" [r lrange mylist -1000 1000]
628 }
629
630 test "LRANGE out of range negative end index - $type" {
631 create_$type mylist "$large 1 2 3"
632 assert_equal $large [r lrange mylist 0 -4]
633 assert_equal {} [r lrange mylist 0 -5]
634 }
635 }
636
637 test {LRANGE against non existing key} {
638 assert_equal {} [r lrange nosuchkey 0 1]
639 }
640
641 foreach {type large} [array get largevalue] {
642 proc trim_list {type min max} {
643 upvar 1 large large
644 r del mylist
645 create_$type mylist "1 2 3 4 $large"
646 r ltrim mylist $min $max
647 r lrange mylist 0 -1
648 }
649
650 test "LTRIM basics - $type" {
651 assert_equal "1" [trim_list $type 0 0]
652 assert_equal "1 2" [trim_list $type 0 1]
653 assert_equal "1 2 3" [trim_list $type 0 2]
654 assert_equal "2 3" [trim_list $type 1 2]
655 assert_equal "2 3 4 $large" [trim_list $type 1 -1]
656 assert_equal "2 3 4" [trim_list $type 1 -2]
657 assert_equal "4 $large" [trim_list $type -2 -1]
658 assert_equal "$large" [trim_list $type -1 -1]
659 assert_equal "1 2 3 4 $large" [trim_list $type -5 -1]
660 assert_equal "1 2 3 4 $large" [trim_list $type -10 10]
661 assert_equal "1 2 3 4 $large" [trim_list $type 0 5]
662 assert_equal "1 2 3 4 $large" [trim_list $type 0 10]
663 }
664
665 test "LTRIM out of range negative end index - $type" {
666 assert_equal {1} [trim_list $type 0 -5]
667 assert_equal {} [trim_list $type 0 -6]
668 }
669
670 }
671
672 foreach {type large} [array get largevalue] {
673 test "LSET - $type" {
674 create_$type mylist "99 98 $large 96 95"
675 r lset mylist 1 foo
676 r lset mylist -1 bar
677 assert_equal "99 foo $large 96 bar" [r lrange mylist 0 -1]
678 }
679
680 test "LSET out of range index - $type" {
681 assert_error ERR*range* {r lset mylist 10 foo}
682 }
683 }
684
685 test {LSET against non existing key} {
686 assert_error ERR*key* {r lset nosuchkey 10 foo}
687 }
688
689 test {LSET against non list value} {
690 r set nolist foobar
691 assert_error ERR*value* {r lset nolist 0 foo}
692 }
693
694 foreach {type e} [array get largevalue] {
695 test "LREM remove all the occurrences - $type" {
696 create_$type mylist "$e foo bar foobar foobared zap bar test foo"
697 assert_equal 2 [r lrem mylist 0 bar]
698 assert_equal "$e foo foobar foobared zap test foo" [r lrange mylist 0 -1]
699 }
700
701 test "LREM remove the first occurrence - $type" {
702 assert_equal 1 [r lrem mylist 1 foo]
703 assert_equal "$e foobar foobared zap test foo" [r lrange mylist 0 -1]
704 }
705
706 test "LREM remove non existing element - $type" {
707 assert_equal 0 [r lrem mylist 1 nosuchelement]
708 assert_equal "$e foobar foobared zap test foo" [r lrange mylist 0 -1]
709 }
710
711 test "LREM starting from tail with negative count - $type" {
712 create_$type mylist "$e foo bar foobar foobared zap bar test foo foo"
713 assert_equal 1 [r lrem mylist -1 bar]
714 assert_equal "$e foo bar foobar foobared zap test foo foo" [r lrange mylist 0 -1]
715 }
716
717 test "LREM starting from tail with negative count (2) - $type" {
718 assert_equal 2 [r lrem mylist -2 foo]
719 assert_equal "$e foo bar foobar foobared zap test" [r lrange mylist 0 -1]
720 }
721
722 test "LREM deleting objects that may be int encoded - $type" {
723 create_$type myotherlist "$e 1 2 3"
724 assert_equal 1 [r lrem myotherlist 1 2]
725 assert_equal 3 [r llen myotherlist]
726 }
727 }
728 }