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