Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .github/workflows/doctests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Documentation Tests

on:
push:
tags-ignore:
- '*'
branches:
- 'main'
pull_request:
workflow_dispatch:

jobs:
doctests:
runs-on: ubuntu-latest
services:
redis-stack:
image: redis/redis-stack-server:latest
options: >-
--health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5
ports:
- 6379:6379

steps:
- name: Checkout project
uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v2
with:
java-version: '11'
distribution: 'temurin'
- name: Cache local Maven repository
uses: actions/cache@v4
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
- name: Run doctests
run: |
mvn -Pdoctests test
19 changes: 19 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1288,6 +1288,25 @@
</build>
</profile>

<profile>
<id>doctests</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<includes>
<include>**/examples/reactive/*Example.java</include>
<include>**/examples/async/*Example.java</include>
</includes>
<failIfNoTests>true</failIfNoTests>
</configuration>
</plugin>
</plugins>
</build>
</profile>

</profiles>

</project>
127 changes: 127 additions & 0 deletions src/test/java/io/redis/examples/async/StringExample.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// EXAMPLE: set_tutorial
package io.redis.examples.async;

import io.lettuce.core.*;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.api.StatefulRedisConnection;

// REMOVE_START
import org.junit.jupiter.api.Test;
// REMOVE_END

import java.util.*;
import java.util.concurrent.CompletableFuture;

// REMOVE_START
import static org.assertj.core.api.Assertions.assertThat;
// REMOVE_END

public class StringExample {

// REMOVE_START
@Test
// REMOVE_END
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");

try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisAsyncCommands<String, String> asyncCommands = connection.async();

// STEP_START set_get
CompletableFuture<Void> setAndGet = asyncCommands.set("bike:1", "Deimos").thenCompose(v -> {
System.out.println(v); // OK
// REMOVE_START
assertThat(v).isEqualTo("OK");
// REMOVE_END
return asyncCommands.get("bike:1");
})
// REMOVE_START
.thenApply(res -> {
assertThat(res).isEqualTo("Deimos");
return res;
})
// REMOVE_END
.thenAccept(System.out::println) // Deimos
.toCompletableFuture();
// STEP_END

// STEP_START setnx_xx
CompletableFuture<Void> setnx = asyncCommands.setnx("bike:1", "bike").thenCompose(v -> {
System.out.println(v); // false (because key already exists)
// REMOVE_START
assertThat(v).isFalse();
// REMOVE_END
return asyncCommands.get("bike:1");
})
// REMOVE_START
.thenApply(res -> {
assertThat(res).isEqualTo("Deimos");
return res;
})
// REMOVE_END
.thenAccept(System.out::println) // Deimos (value is unchanged)
.toCompletableFuture();

// set the value to "bike" if it already exists
CompletableFuture<Void> setxx = asyncCommands.set("bike:1", "bike", SetArgs.Builder.xx())
// REMOVE_START
.thenApply(res -> {
assertThat(res).isEqualTo("OK");
return res;
})
// REMOVE_END
.thenAccept(System.out::println) // OK
.toCompletableFuture();
// STEP_END

// STEP_START mset
Map<String, String> bikeMap = new HashMap<>();
bikeMap.put("bike:1", "Deimos");
bikeMap.put("bike:2", "Ares");
bikeMap.put("bike:3", "Vanth");

CompletableFuture<Void> mset = asyncCommands.mset(bikeMap).thenCompose(v -> {
System.out.println(v); // OK
return asyncCommands.mget("bike:1", "bike:2", "bike:3");
})
// REMOVE_START
.thenApply(res -> {
List<KeyValue<String, String>> expected = new ArrayList<>(
Arrays.asList(KeyValue.just("bike:1", "Deimos"), KeyValue.just("bike:2", "Ares"),
KeyValue.just("bike:3", "Vanth")));
assertThat(res).isEqualTo(expected);
return res;
})
// REMOVE_END
.thenAccept(System.out::println) // [KeyValue[bike:1, Deimos], KeyValue[bike:2, Ares], KeyValue[bike:3,
// Vanth]]
.toCompletableFuture();
// STEP_END

// STEP_START incr
CompletableFuture<Void> incrby = asyncCommands.set("total_crashes", "0")
.thenCompose(v -> asyncCommands.incr("total_crashes")).thenCompose(v -> {
System.out.println(v); // 1
// REMOVE_START
assertThat(v).isEqualTo(1L);
// REMOVE_END
return asyncCommands.incrby("total_crashes", 10);
})
// REMOVE_START
.thenApply(res -> {
assertThat(res).isEqualTo(11L);
return res;
})
// REMOVE_END
.thenAccept(System.out::println) // 11
.toCompletableFuture();
// STEP_END

CompletableFuture.allOf(setAndGet, setnx, setxx, mset, incrby).join();

} finally {
redisClient.shutdown();
}
}

}
104 changes: 104 additions & 0 deletions src/test/java/io/redis/examples/reactive/StringExample.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// EXAMPLE: set_tutorial
package io.redis.examples.reactive;

import io.lettuce.core.*;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.api.StatefulRedisConnection;
// REMOVE_START
import org.junit.jupiter.api.Test;
// REMOVE_END
import reactor.core.publisher.Mono;

import java.util.*;

// REMOVE_START
import static org.assertj.core.api.Assertions.assertThat;
// REMOVE_END

public class StringExample {

// REMOVE_START
@Test
// REMOVE_END
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");

try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();

// STEP_START set_get
Mono<Void> setAndGet = reactiveCommands.set("bike:1", "Deimos").doOnNext(v -> {
System.out.println(v); // OK
// REMOVE_START
assertThat(v).isEqualTo("OK");
// REMOVE_END
}).flatMap(v -> reactiveCommands.get("bike:1")).doOnNext(res -> {
// REMOVE_START
assertThat(res).isEqualTo("Deimos");
// REMOVE_END
System.out.println(res); // Deimos
}).then();
// STEP_END

// STEP_START setnx_xx
Mono<Void> setnx = reactiveCommands.setnx("bike:1", "bike").doOnNext(v -> {
System.out.println(v); // false (because key already exists)
// REMOVE_START
assertThat(v).isFalse();
// REMOVE_END
}).flatMap(v -> reactiveCommands.get("bike:1")).doOnNext(res -> {
// REMOVE_START
assertThat(res).isEqualTo("Deimos");
// REMOVE_END
System.out.println(res); // Deimos (value is unchanged)
}).then();

Mono<Void> setxx = reactiveCommands.set("bike:1", "bike", SetArgs.Builder.xx()).doOnNext(res -> {
// REMOVE_START
assertThat(res).isEqualTo("OK");
// REMOVE_END
System.out.println(res); // OK
}).then();
// STEP_END

// STEP_START mset
Map<String, String> bikeMap = new HashMap<>();
bikeMap.put("bike:1", "Deimos");
bikeMap.put("bike:2", "Ares");
bikeMap.put("bike:3", "Vanth");

Mono<Void> mset = reactiveCommands.mset(bikeMap).doOnNext(System.out::println) // OK
.flatMap(v -> reactiveCommands.mget("bike:1", "bike:2", "bike:3").collectList()).doOnNext(res -> {
List<KeyValue<String, String>> expected = new ArrayList<>(
Arrays.asList(KeyValue.just("bike:1", "Deimos"), KeyValue.just("bike:2", "Ares"),
KeyValue.just("bike:3", "Vanth")));
// REMOVE_START
assertThat(res).isEqualTo(expected);
// REMOVE_END
System.out.println(res); // [KeyValue[bike:1, Deimos], KeyValue[bike:2, Ares], KeyValue[bike:3, Vanth]]
}).then();
// STEP_END

// STEP_START incr
Mono<Void> incrby = reactiveCommands.set("total_crashes", "0").flatMap(v -> reactiveCommands.incr("total_crashes"))
.doOnNext(v -> {
System.out.println(v); // 1
// REMOVE_START
assertThat(v).isEqualTo(1L);
// REMOVE_END
}).flatMap(v -> reactiveCommands.incrby("total_crashes", 10)).doOnNext(res -> {
// REMOVE_START
assertThat(res).isEqualTo(11L);
// REMOVE_END
System.out.println(res); // 11
}).then();
// STEP_END

Mono.when(setAndGet, setnx, setxx, mset, incrby).block();

} finally {
redisClient.shutdown();
}
}

}
Loading