Adds support to lPop or rPop N elements from a Redis List in ReactiveListOperations.

Closes #2692
Original pull request: #2704
This commit is contained in:
John Blum
2023-09-07 16:58:33 -07:00
committed by Mark Paluch
parent ea4acad379
commit 157f5e4b1d
5 changed files with 165 additions and 10 deletions

View File

@@ -15,10 +15,8 @@
*/
package org.springframework.data.redis.core;
import static org.assertj.core.api.Assertions.*;
import static org.assertj.core.api.Assumptions.*;
import reactor.test.StepVerifier;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.assertj.core.api.Assumptions.assumeThat;
import java.time.Duration;
import java.util.Collection;
@@ -35,11 +33,14 @@ import org.springframework.data.redis.test.condition.EnabledOnCommand;
import org.springframework.data.redis.test.extension.parametrized.MethodSource;
import org.springframework.data.redis.test.extension.parametrized.ParameterizedRedisTest;
import reactor.test.StepVerifier;
/**
* Integration tests for {@link DefaultReactiveListOperations}.
*
* @author Mark Paluch
* @author Christoph Strobl
* @author John Blum
*/
@MethodSource("testParams")
@SuppressWarnings("unchecked")
@@ -458,6 +459,38 @@ public class DefaultReactiveListOperationsIntegrationTests<K, V> {
listOperations.leftPop(key).as(StepVerifier::create).expectNext(value2).verifyComplete();
}
@ParameterizedRedisTest // GH-2692
@SuppressWarnings("all")
void leftPopWithNullKey() {
assertThatIllegalArgumentException()
.isThrownBy(() -> this.listOperations.leftPop(null, 100L))
.withMessage("Key must not be null")
.withNoCause();
}
@ParameterizedRedisTest // GH-2692
void leftPopWithCount() {
assumeThat(this.valueFactory).isInstanceOf(ByteBufferObjectFactory.class);
K key = keyFactory.instance();
V value1 = valueFactory.instance();
V value2 = valueFactory.instance();
V value3 = valueFactory.instance();
listOperations.leftPushAll(key, value1, value2, value3)
.as(StepVerifier::create)
.expectNext(3L)
.verifyComplete();
listOperations.leftPop(key, 2)
.as(StepVerifier::create)
.expectNext(value3)
.expectNext(value2)
.verifyComplete();
}
@ParameterizedRedisTest // DATAREDIS-602
void rightPop() {
@@ -472,6 +505,38 @@ public class DefaultReactiveListOperationsIntegrationTests<K, V> {
listOperations.rightPop(key).as(StepVerifier::create).expectNext(value2).verifyComplete();
}
@ParameterizedRedisTest // GH-2692
@SuppressWarnings("all")
void rightPopWithNullKey() {
assertThatIllegalArgumentException()
.isThrownBy(() -> this.listOperations.rightPop(null, 100L))
.withMessage("Key must not be null")
.withNoCause();
}
@ParameterizedRedisTest // GH-2692
void rightPopWithCount() {
assumeThat(this.valueFactory).isInstanceOf(ByteBufferObjectFactory.class);
K key = keyFactory.instance();
V value1 = valueFactory.instance();
V value2 = valueFactory.instance();
V value3 = valueFactory.instance();
listOperations.rightPushAll(key, value3, value2, value1)
.as(StepVerifier::create)
.expectNext(3L)
.verifyComplete();
listOperations.rightPop(key, 2)
.as(StepVerifier::create)
.expectNext(value1)
.expectNext(value2)
.verifyComplete();
}
@ParameterizedRedisTest // DATAREDIS-602
void leftPopWithTimeout() {

View File

@@ -32,6 +32,7 @@ import java.time.Duration
* @author Mark Paluch
* @author Sebastien Deleuze
* @author Wonwoo Lee
* @author John Blum
*/
class ReactiveListOperationsExtensionsUnitTests {
@@ -290,11 +291,27 @@ class ReactiveListOperationsExtensionsUnitTests {
}
}
@Test // GH-2692
fun leftPopWithCount() {
val operations = mockk<ReactiveListOperations<String, String>>()
every { operations.leftPop(any(), any<Long>()) } returns Flux.just("foo", "bar", "baz")
runBlocking {
assertThat(operations.leftPopAsFlow("TestKey", 3L).toList()).containsExactly("foo", "bar", "baz")
}
verify {
operations.leftPop("TestKey", 3L)
}
}
@Test // DATAREDIS-937
fun blockingLeftPop() {
val operations = mockk<ReactiveListOperations<String, String>>()
every { operations.leftPop(any(), any()) } returns Mono.just("foo")
every { operations.leftPop(any(), any<Duration>()) } returns Mono.just("foo")
runBlocking {
assertThat(operations.leftPopAndAwait("foo", Duration.ofDays(1))).isEqualTo("foo")
@@ -320,11 +337,28 @@ class ReactiveListOperationsExtensionsUnitTests {
}
}
@Test // GH-2692
fun rightPopWithCount() {
val operations = mockk<ReactiveListOperations<String, String>>()
every { operations.rightPop(any(), any<Long>()) } returns Flux.just("foo", "bar", "baz")
runBlocking {
assertThat(operations.rightPopAsFlow("TestKey", 3L).toList())
.containsExactly("foo", "bar", "baz")
}
verify {
operations.rightPop("TestKey", 3L)
}
}
@Test // DATAREDIS-937
fun blockingRightPop() {
val operations = mockk<ReactiveListOperations<String, String>>()
every { operations.rightPop(any(), any()) } returns Mono.just("foo")
every { operations.rightPop(any(), any<Duration>()) } returns Mono.just("foo")
runBlocking {
assertThat(operations.rightPopAndAwait("foo", Duration.ofDays(1))).isEqualTo("foo")