From b840a673bbcaaa55bdd9b5e46436f8a7ccc51a48 Mon Sep 17 00:00:00 2001 From: ogzhanolguncu Date: Tue, 19 Dec 2023 10:39:53 +0300 Subject: [PATCH] Add missing expiry options to EXPIRE command --- pkg/commands/expire.test.ts | 99 ++++++++++++++++++++++++++++++++++++- pkg/commands/expire.ts | 9 ++-- 2 files changed, 103 insertions(+), 5 deletions(-) diff --git a/pkg/commands/expire.test.ts b/pkg/commands/expire.test.ts index bce424db..82a0c584 100644 --- a/pkg/commands/expire.test.ts +++ b/pkg/commands/expire.test.ts @@ -1,6 +1,6 @@ import { keygen, newHttpClient, randomID } from "../test-utils"; -import { afterAll, expect, test } from "bun:test"; +import { afterAll, describe, expect, test } from "bun:test"; import { ExpireCommand } from "./expire"; import { GetCommand } from "./get"; import { SetCommand } from "./set"; @@ -20,3 +20,100 @@ test("expires a key correctly", async () => { expect(res2).toEqual(null); }); + +describe("NX", () => { + test("should set expiry only when the key has no expiry", async () => { + const key = newKey(); + const value = randomID(); + await new SetCommand([key, value]).exec(client); + const res = await new ExpireCommand([key, 1, "NX"]).exec(client); + expect(res).toEqual(1); + await new Promise((res) => setTimeout(res, 2000)); + const res2 = await new GetCommand([key]).exec(client); + + expect(res2).toEqual(null); + }); + + test("should not set expiry when the key has expiry", async () => { + const key = newKey(); + const value = randomID(); + await new SetCommand([key, value, { ex: 1000 }]).exec(client); + const res = await new ExpireCommand([key, 1, "NX"]).exec(client); + expect(res).toEqual(0); + }); +}); + +describe("XX", () => { + test( + "should set expiry only when the key has an existing expiry", + async () => { + const key = newKey(); + const value = randomID(); + await new SetCommand([key, value, { ex: 1 }]).exec(client); + const res = await new ExpireCommand([key, 5, "XX"]).exec(client); + expect(res).toEqual(1); + await new Promise((res) => setTimeout(res, 6000)); + const res2 = await new GetCommand([key]).exec(client); + expect(res2).toEqual(null); + }, + { timeout: 10000 } + ); + + test("should not set expiry when the key does not have an existing expiry", async () => { + const key = newKey(); + const value = randomID(); + await new SetCommand([key, value]).exec(client); + const res = await new ExpireCommand([key, 5, "XX"]).exec(client); + expect(res).toEqual(0); + }); +}); + +describe("GT", () => { + test( + "should set expiry only when the new expiry is greater than current one", + async () => { + const key = newKey(); + const value = randomID(); + await new SetCommand([key, value, { ex: 1 }]).exec(client); + const res = await new ExpireCommand([key, 5, "GT"]).exec(client); + expect(res).toEqual(1); + await new Promise((res) => setTimeout(res, 6000)); + const res2 = await new GetCommand([key]).exec(client); + expect(res2).toEqual(null); + }, + { timeout: 10000 } + ); + + test("should not set expiry when the new expiry is not greater than current one", async () => { + const key = newKey(); + const value = randomID(); + await new SetCommand([key, value, { ex: 10 }]).exec(client); + const res = await new ExpireCommand([key, 5, "GT"]).exec(client); + expect(res).toEqual(0); + }); +}); + +describe("LT", () => { + test( + "should set expiry only when the new expiry is less than current one", + async () => { + const key = newKey(); + const value = randomID(); + await new SetCommand([key, value, { ex: 5 }]).exec(client); + const res = await new ExpireCommand([key, 3, "LT"]).exec(client); + expect(res).toEqual(1); + await new Promise((res) => setTimeout(res, 4000)); + const res2 = await new GetCommand([key]).exec(client); + expect(res2).toEqual(null); + }, + { timeout: 10000 } + ); + + test("should not set expiry when the new expiry is not less than current one", async () => { + const key = newKey(); + const value = randomID(); + await new SetCommand([key, value, { ex: 10 }]).exec(client); + const res = await new ExpireCommand([key, 20, "LT"]).exec(client); + expect(res).toEqual(0); + }); +}); diff --git a/pkg/commands/expire.ts b/pkg/commands/expire.ts index db6f9a0c..13ff821b 100644 --- a/pkg/commands/expire.ts +++ b/pkg/commands/expire.ts @@ -1,10 +1,11 @@ import { Command, CommandOptions } from "./command"; -/** - * @see https://redis.io/commands/expire - */ +type ExpireOptions = "NX" | "nx" | "XX" | "xx" | "GT" | "gt" | "LT" | "lt"; export class ExpireCommand extends Command<"0" | "1", 0 | 1> { - constructor(cmd: [key: string, seconds: number], opts?: CommandOptions<"0" | "1", 0 | 1>) { + constructor( + cmd: [key: string, seconds: number, option?: ExpireOptions], + opts?: CommandOptions<"0" | "1", 0 | 1> + ) { super(["expire", ...cmd], opts); } }