Repository: fppt/jedis-mock
Pull request #60 (2019-09-23 16:56:34)

Support for zrangebylex


Patch:
diff --git a/src/main/java/com/github/fppt/jedismock/operations/OperationFactory.java b/src/main/java/com/github/fppt/jedismock/operations/OperationFactory.java
index 64d17e3..21b08f9 100644
--- a/src/main/java/com/github/fppt/jedismock/operations/OperationFactory.java
+++ b/src/main/java/com/github/fppt/jedismock/operations/OperationFactory.java
@@ -80,6 +80,7 @@ public class OperationFactory {
         TRANSACTIONAL_OPERATIONS.put("zadd", RO_zadd::new);
         TRANSACTIONAL_OPERATIONS.put("zcard", RO_zcard::new);
         TRANSACTIONAL_OPERATIONS.put("zrange", RO_zrange::new);
+        TRANSACTIONAL_OPERATIONS.put("zrangebylex", RO_zrangebylex::new);
         TRANSACTIONAL_OPERATIONS.put("zrem", RO_zrem::new);
     }
 
@@ -104,6 +105,8 @@ public class OperationFactory {
                 return Optional.of(new RO_unsubscribe(state, params));
             case "quit":
                 return Optional.of(new RO_quit(state));
+            case "auth":
+                return Optional.of(new RO_auth(state));
             case "exec":
                 return Optional.of(new RO_exec(state));
             default:
diff --git a/src/main/java/com/github/fppt/jedismock/operations/RO_auth.java b/src/main/java/com/github/fppt/jedismock/operations/RO_auth.java
new file mode 100644
index 0000000..75d4b92
--- /dev/null
+++ b/src/main/java/com/github/fppt/jedismock/operations/RO_auth.java
@@ -0,0 +1,19 @@
+package com.github.fppt.jedismock.operations;
+
+import com.github.fppt.jedismock.server.Response;
+import com.github.fppt.jedismock.server.Slice;
+import com.github.fppt.jedismock.storage.OperationExecutorState;
+
+public class RO_auth implements RedisOperation {
+    private OperationExecutorState state;
+
+    public RO_auth(OperationExecutorState state) {
+        this.state = state;
+    }
+
+    @Override
+    public Slice execute() {
+        state.owner().sendResponse(Response.clientResponse("auth", Response.OK), "auth");
+        return Response.SKIP;
+    }
+}
diff --git a/src/main/java/com/github/fppt/jedismock/operations/RO_zrangebylex.java b/src/main/java/com/github/fppt/jedismock/operations/RO_zrangebylex.java
new file mode 100644
index 0000000..8eaabd6
--- /dev/null
+++ b/src/main/java/com/github/fppt/jedismock/operations/RO_zrangebylex.java
@@ -0,0 +1,62 @@
+package com.github.fppt.jedismock.operations;
+
+import com.github.fppt.jedismock.server.Response;
+import com.github.fppt.jedismock.server.Slice;
+import com.github.fppt.jedismock.storage.RedisBase;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+class RO_zrangebylex extends AbstractRedisOperation {
+
+    private static final String START_UNBOUNDED = "-";
+    private static final String END_UNBOUNDED = "+";
+    private static final String INCLUSIVE_PREFIX = "[";
+    private static final String EXCLUSIVE_PREFIX = "(";
+
+    RO_zrangebylex(RedisBase base, List<Slice> params) {
+        super(base, params);
+    }
+
+    @Override
+    Slice response() {
+        Slice key = params().get(0);
+        LinkedHashMap<Slice, Double> map = getDataFromBase(key, new LinkedHashMap<>());
+
+        String start = params().get(1).toString();
+        if (!START_UNBOUNDED.equals(start)
+                && !start.startsWith(INCLUSIVE_PREFIX)
+                && !start.startsWith(EXCLUSIVE_PREFIX)) {
+            throw new RuntimeException("Valid start must start with '" + INCLUSIVE_PREFIX + "' or '"
+                    + EXCLUSIVE_PREFIX + "'");
+        }
+
+        final Predicate<Slice> compareToStart = p -> START_UNBOUNDED.equals(start) ||
+                (start.startsWith(INCLUSIVE_PREFIX)
+                        ? p.toString().compareTo(start.substring(1)) >= 0
+                        : p.toString().compareTo(start.substring(1)) > 0);
+
+        String end = params().get(2).toString();
+        if (!END_UNBOUNDED.equals(end)
+                && !end.startsWith(INCLUSIVE_PREFIX)
+                && !end.startsWith(EXCLUSIVE_PREFIX)) {
+            throw new RuntimeException("Valid end must start with '" + INCLUSIVE_PREFIX + "' or '"
+                    + EXCLUSIVE_PREFIX + "'");
+        }
+
+        final Predicate<Slice> compareToEnd = p -> END_UNBOUNDED.equals(end) ||
+                (end.startsWith(INCLUSIVE_PREFIX)
+                        ? p.toString().compareTo(end.substring(1)) <= 0
+                        : p.toString().compareTo(end.substring(1)) < 0);
+
+        List<Slice> values = map.keySet().stream()
+                .filter(compareToStart.and(compareToEnd))
+                .sorted()
+                .map(Response::bulkString)
+                .collect(Collectors.toList());
+
+        return Response.array(values);
+    }
+}


Test patch:
diff --git a/src/test/java/com/github/fppt/jedismock/comparisontests/SimpleOperationsTest.java b/src/test/java/com/github/fppt/jedismock/comparisontests/SimpleOperationsTest.java
index c8112e0..90596dc 100644
--- a/src/test/java/com/github/fppt/jedismock/comparisontests/SimpleOperationsTest.java
+++ b/src/test/java/com/github/fppt/jedismock/comparisontests/SimpleOperationsTest.java
@@ -770,4 +770,34 @@ public class SimpleOperationsTest extends ComparisonBase {
         assertEquals("myvalue4", results.get(3).getElement());
         assertEquals(20d, results.get(3).getScore(), 0);
     }
+
+    @Theory
+    public void zrangebylexKeysCorrectOrder(Jedis jedis) {
+        jedis.flushDB();
+
+        String key = "mykey";
+        Map<String, Double> members = new HashMap<>();
+        members.put("bbb", 0d);
+        members.put("ddd", 0d);
+        members.put("ccc", 0d);
+        members.put("aaa", 0d);
+
+        long result = jedis.zadd(key, members);
+
+        assertEquals(4L, result);
+
+        List<String> results = new ArrayList<>(jedis.zrangeByLex(key, "-", "+"));
+
+        assertEquals(4, results.size());
+        assertEquals("aaa", results.get(0));
+        assertEquals("bbb", results.get(1));
+        assertEquals("ccc", results.get(2));
+        assertEquals("ddd", results.get(3));
+
+        results = new ArrayList<>(jedis.zrangeByLex(key, "[bbb", "(ddd"));
+
+        assertEquals(2, results.size());
+        assertEquals("bbb", results.get(0));
+        assertEquals("ccc", results.get(1));
+    }
 }