From d88c30e0e514532995c25a92f1d118c772be6227 Mon Sep 17 00:00:00 2001 From: Asher Gomez Date: Tue, 26 Jul 2022 22:51:38 +1000 Subject: [PATCH] chore: minor tweaks and simplifications --- README.md | 23 +++----- mod.ts | 7 ++- test.ts | 172 ++++++++++++++++++++++++++++++------------------------ 3 files changed, 110 insertions(+), 92 deletions(-) diff --git a/README.md b/README.md index 672a8ac..c808637 100644 --- a/README.md +++ b/README.md @@ -11,33 +11,28 @@ Lightweight Redis client library for Deno. Design principles: Must be run with `--allow-net` permission. -### Basic commands +### Single command ```ts import { sendCommand } from "https://deno.land/x/r2d2/mod.ts"; -const redisConn = await Deno.connect({ port: 6379 }); // Connect to the Redis server - -await sendCommand(redisConn, ["SET", "hello", "world"]); // Returns "OK" - -await sendCommand(redisConn, ["GET", "hello"]); // Returns "world" - -redisConn.close(); // Close the connection to the Redis server -``` +const redisConn = await Deno.connect({ port: 6379 }); -If you'd like to ignore the reply. +// Returns "OK" +await sendCommand(redisConn, ["SET", "hello", "world"]); -```ts -await sendCommand(redis, ["SHUTDOWN"], false); // Returns nothing +// Returns "world" +await sendCommand(redisConn, ["GET", "hello"]); ``` -### Pipelining +### Multiple commands (pipelining) ```ts import { pipelineCommands } from "https://deno.land/x/r2d2/mod.ts"; -const redisConn = await Deno.connect({ port: 6379 }); // Connect to the Redis server +const redisConn = await Deno.connect({ port: 6379 }); +// Returns [1, 2, 3, 4] await pipelineCommands(redisConn, [ ["INCR", "X"], ["INCR", "X"], diff --git a/mod.ts b/mod.ts index 8c21a7c..274e394 100644 --- a/mod.ts +++ b/mod.ts @@ -32,7 +32,6 @@ function createRequest(command: Command): string { return request; } -/** Encodes and sends the request string to the server. */ async function writeRequest( redisConn: Deno.Conn, request: string, @@ -106,9 +105,11 @@ async function readReply(bufReader: BufReader): Promise { * ```ts * const redisConn = await Deno.connect({ port: 6379 }); * - * await sendCommand(redisConn, ["SET", "hello", "world"]); // Returns "OK" + * // Returns "OK" + * await sendCommand(redisConn, ["SET", "hello", "world"]); * - * await sendCommand(redisConn, ["GET", "hello"]); // Returns "world" + * // Returns "world" + * await sendCommand(redisConn, ["GET", "hello"]); * ``` */ export async function sendCommand( diff --git a/test.ts b/test.ts index c03d7b1..7d52834 100644 --- a/test.ts +++ b/test.ts @@ -1,95 +1,117 @@ import { assertEquals, assertRejects } from "./deps.ts"; import { type Command, + listenReplies, pipelineCommands, type Reply, sendCommand, + writeCommand, } from "./mod.ts"; import { REDIS_PORT, SERVER_PROCESS } from "./_util.ts"; -Deno.test("sendCommand and pipelineCommands", async (t) => { - await SERVER_PROCESS.status(); - const redisConn = await Deno.connect({ port: REDIS_PORT }); - - async function flushDB() { - await sendCommand(redisConn, ["FLUSHDB"]); - } - - async function sendCommandTest( - command: Command, - expected: Reply, - ): Promise { - assertEquals(await sendCommand(redisConn, command), expected); - } - - await flushDB(); - - await t.step("parses simple string", async () => { - await sendCommandTest(["PING"], "PONG"); - }); - - await t.step("parses error", () => { - assertRejects(async () => await sendCommand(redisConn, ["helloworld"])); - }); - - await t.step("parses integer", async () => { - await sendCommandTest(["INCR", "integer"], 1); - await sendCommandTest(["INCR", "integer"], 2); - }); - - await t.step("parses bulk string", async () => { - await sendCommand(redisConn, ["SET", "big ups", "west side massive"]); - await sendCommandTest(["GET", "big ups"], "west side massive"); - }); - - await t.step("parses null", async () => { - await sendCommandTest(["GET", "nonexistant"], null); - }); - - await t.step("parses array", async () => { - await sendCommand(redisConn, [ - "HSET", - "hash", - "hello", - "world", - "integer", - 13, - ]); - await sendCommandTest([ - "HMGET", - "hash", - "hello", - "integer", - "nonexistant", - ], ["world", "13", null]); - }); - - await t.step("parses empty array", async () => { - await sendCommandTest(["HGETALL", "nonexistant"], []); - }); - - await t.step("parses null array", async () => { - await sendCommandTest(["BLPOP", "list", 1], null); - }); - - await t.step("transactions work", async () => { - await sendCommandTest(["MULTI"], "OK"); - await sendCommandTest(["INCR", "FOO"], "QUEUED"); - await sendCommandTest(["INCR", "BAR"], "QUEUED"); - await sendCommandTest(["EXEC"], [1, 1]); - }); - - await t.step("pipelining works", async () => { +async function flushDB(redisConn: Deno.Conn): Promise { + await sendCommand(redisConn, ["FLUSHDB"]); +} + +Deno.test({ + name: "sendCommand", + async fn(t) { + await SERVER_PROCESS.status(); + const redisConn = await Deno.connect({ port: REDIS_PORT }); + + async function sendCommandTest( + command: Command, + expected: Reply, + ): Promise { + assertEquals(await sendCommand(redisConn, command), expected); + } + + await flushDB(redisConn); + + await t.step("parses simple string", async () => { + await sendCommandTest(["PING"], "PONG"); + }); + + await t.step("parses error", () => { + assertRejects(async () => await sendCommand(redisConn, ["helloworld"])); + }); + + await t.step("parses integer", async () => { + await sendCommandTest(["INCR", "integer"], 1); + await sendCommandTest(["INCR", "integer"], 2); + }); + + await t.step("parses bulk string", async () => { + await sendCommand(redisConn, ["SET", "big ups", "west side massive"]); + await sendCommandTest(["GET", "big ups"], "west side massive"); + }); + + await t.step("parses null", async () => { + await sendCommandTest(["GET", "nonexistant"], null); + }); + + await t.step("parses array", async () => { + await sendCommand(redisConn, [ + "HSET", + "hash", + "hello", + "world", + "integer", + 13, + ]); + await sendCommandTest([ + "HMGET", + "hash", + "hello", + "integer", + "nonexistant", + ], ["world", "13", null]); + }); + + await t.step("parses empty array", async () => { + await sendCommandTest(["HGETALL", "nonexistant"], []); + }); + + await t.step("parses null array", async () => { + await sendCommandTest(["BLPOP", "list", 1], null); + }); + + await t.step("transactions work", async () => { + await sendCommandTest(["MULTI"], "OK"); + await sendCommandTest(["INCR", "FOO"], "QUEUED"); + await sendCommandTest(["INCR", "BAR"], "QUEUED"); + await sendCommandTest(["EXEC"], [1, 1]); + }); + + await flushDB(redisConn); + redisConn.close(); + }, +}); + +Deno.test({ + name: "pipelineCommands", + async fn() { + await SERVER_PROCESS.status(); + const redisConn = await Deno.connect({ port: REDIS_PORT }); + + await flushDB(redisConn); + assertEquals( await pipelineCommands(redisConn, [ ["INCR", "X"], ["INCR", "X"], ["INCR", "X"], ["INCR", "X"], + ["SET", "hello", "world"], + ["GET", "hello"], ]), - [1, 2, 3, 4], + [1, 2, 3, 4, "OK", "world"], ); - }); + + await flushDB(redisConn); + redisConn.close(); + }, +}); Deno.test({ name: "listenReplies",