From e106644572377841c9c4cba624280cfa595a41c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Bolina?= Date: Tue, 20 Aug 2024 17:55:41 -0300 Subject: [PATCH] fix: Lcs response parse * Handle parsing `len` and `matches` in any order; --- .../core/output/StringMatchResultOutput.java | 20 ++++++--- .../StringMatchResultOutputUnitTests.java | 43 +++++++++++++++++++ 2 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 src/test/java/io/lettuce/core/output/StringMatchResultOutputUnitTests.java diff --git a/src/main/java/io/lettuce/core/output/StringMatchResultOutput.java b/src/main/java/io/lettuce/core/output/StringMatchResultOutput.java index 2653f8f2cc..d062966a7b 100644 --- a/src/main/java/io/lettuce/core/output/StringMatchResultOutput.java +++ b/src/main/java/io/lettuce/core/output/StringMatchResultOutput.java @@ -23,6 +23,7 @@ import static io.lettuce.core.StringMatchResult.Position; import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; @@ -37,6 +38,8 @@ */ public class StringMatchResultOutput extends CommandOutput { + private static final ByteBuffer LEN = StandardCharsets.US_ASCII.encode("len"); + private final boolean withIdx; private String matchString; @@ -45,6 +48,8 @@ public class StringMatchResultOutput extends CommandOutput positions; + private boolean readingLen = true; + private final List matchedPositions = new ArrayList<>(); public StringMatchResultOutput(RedisCodec codec, boolean withIdx) { @@ -57,18 +62,23 @@ public void set(ByteBuffer bytes) { if (!withIdx && matchString == null) { matchString = (String) codec.decodeKey(bytes); + } else { + readingLen = LEN.equals(bytes); } } @Override public void set(long integer) { - this.len = (int) integer; - - if (positions == null) { - positions = new ArrayList<>(); + if (readingLen) { + this.len = (int) integer; + } else { + if (positions == null) { + positions = new ArrayList<>(); + } + positions.add(integer); } - positions.add(integer); + } @Override diff --git a/src/test/java/io/lettuce/core/output/StringMatchResultOutputUnitTests.java b/src/test/java/io/lettuce/core/output/StringMatchResultOutputUnitTests.java new file mode 100644 index 0000000000..a10a400c65 --- /dev/null +++ b/src/test/java/io/lettuce/core/output/StringMatchResultOutputUnitTests.java @@ -0,0 +1,43 @@ +package io.lettuce.core.output; + +import io.lettuce.core.StringMatchResult; +import io.lettuce.core.codec.StringCodec; +import org.junit.jupiter.api.Test; + +import java.nio.ByteBuffer; + +import static org.assertj.core.api.Assertions.assertThat; + +public class StringMatchResultOutputUnitTests { + + @Test + void parseLenAndMatches() { + StringMatchResultOutput output = new StringMatchResultOutput<>(new StringCodec(), false); + + output.set(ByteBuffer.wrap("len".getBytes())); + output.set(42); + + output.set(ByteBuffer.wrap("matches".getBytes())); + output.set(0); + output.set(5); + output.set(10); + output.set(15); + + output.complete(2); + output.complete(0); + + StringMatchResult result = output.get(); + + assertThat(result.getLen()).isEqualTo(42); + + assertThat(result.getMatches()).hasSize(1).satisfies(m -> assertMatchedPositions(m.get(0), 0, 5, 10, 15)); + } + + private void assertMatchedPositions(StringMatchResult.MatchedPosition match, int... expected) { + assertThat(match.getA().getStart()).isEqualTo(expected[0]); + assertThat(match.getA().getEnd()).isEqualTo(expected[1]); + assertThat(match.getB().getStart()).isEqualTo(expected[2]); + assertThat(match.getB().getEnd()).isEqualTo(expected[3]); + } + +}