Thanks to visit codestin.com
Credit goes to github.com

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
33 changes: 33 additions & 0 deletions deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pkg/commands/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ export * from "./zremrangebyscore.ts";
export * from "./zrevrank.ts";
export * from "./zscan.ts";
export * from "./zscore.ts";
export * from "./zunion.ts";
export * from "./zunionstore.ts";
export * from "./xadd.ts";
export * from "./xrange.ts";
261 changes: 261 additions & 0 deletions pkg/commands/zunion.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,261 @@
import { keygen, newHttpClient, randomID } from "../test-utils.ts";

import { afterAll } from "https://deno.land/[email protected]/testing/bdd.ts";
import { assertEquals } from "https://deno.land/[email protected]/testing/asserts.ts";
import { ZUnionCommand } from "./zunion.ts";
import { ZAddCommand } from "./zadd.ts";

const client = newHttpClient();

const { newKey, cleanup } = keygen();
afterAll(cleanup);

Deno.test("command format", async (t) => {
await t.step("without options", async (t) => {
await t.step("builds the correct command", () => {
assertEquals(new ZUnionCommand([1, "key"]).command, [
"zunion",
1,
"key",
]);
});
});
await t.step("with multiple keys", async (t) => {
await t.step("builds the correct command", () => {
assertEquals(
new ZUnionCommand([2, ["key1", "key2"]]).command,
["zunion", 2, "key1", "key2"],
);
});
});
await t.step("with single weight", async (t) => {
await t.step("builds the correct command", () => {
assertEquals(
new ZUnionCommand([1, "key", { weight: 4 }])
.command,
["zunion", 1, "key", "weights", 4],
);
});
});
await t.step("with multiple weights", async (t) => {
await t.step("builds the correct command", () => {
assertEquals(
new ZUnionCommand([2, ["key1", "key2"], {
weights: [2, 3],
}]).command,
[
"zunion",
2,
"key1",
"key2",
"weights",
2,
3,
],
);
});
await t.step("with aggregate", async (t) => {
await t.step("sum", async (t) => {
await t.step("builds the correct command", () => {
assertEquals(
new ZUnionCommand([1, "key", {
aggregate: "sum",
}]).command,
["zunion", 1, "key", "aggregate", "sum"],
);
});
});
await t.step("min", async (t) => {
await t.step("builds the correct command", () => {
assertEquals(
new ZUnionCommand([1, "key", {
aggregate: "min",
}]).command,
["zunion", 1, "key", "aggregate", "min"],
);
});
});
await t.step("max", async (t) => {
await t.step("builds the correct command", () => {
assertEquals(
new ZUnionCommand([1, "key", {
aggregate: "max",
}]).command,
["zunion", 1, "key", "aggregate", "max"],
);
});
});
});
await t.step("complex", async (t) => {
await t.step("builds the correct command", () => {
assertEquals(
new ZUnionCommand([2, ["key1", "key2"], {
weights: [4, 2],
aggregate: "max",
}]).command,
[
"zunion",
2,
"key1",
"key2",
"weights",
4,
2,
"aggregate",
"max",
],
);
});
});
});
});

Deno.test("without options", async (t) => {
await t.step("returns the union", async () => {
const key1 = newKey();
const key2 = newKey();
const score1 = 1;
const member1 = randomID();
const score2 = 2;
const member2 = randomID();

await new ZAddCommand([key1, { score: score1, member: member1 }]).exec(
client,
);
await new ZAddCommand([key2, { score: score2, member: member2 }]).exec(
client,
);

const res = await new ZUnionCommand([2, [key1, key2]])
.exec(
client,
);

assertEquals(res.length, 2);
assertEquals(res?.sort(), [member1, member2].sort());
});
});

Deno.test("with weights", async (t) => {
await t.step("returns the set", async () => {
const key1 = newKey();
const key2 = newKey();
const score1 = 1;
const member1 = randomID();
const score2 = 2;
const member2 = randomID();

await new ZAddCommand([key1, { score: score1, member: member1 }]).exec(
client,
);

await new ZAddCommand([key2, { score: score2, member: member2 }]).exec(
client,
);

const res = await new ZUnionCommand([2, [key1, key2], {
weights: [2, 3],
}]).exec(client);

assertEquals(res.length, 2);
});
});

Deno.test("aggregate", async (t) => {
await t.step("sum", async (t) => {
await t.step("returns the set", async () => {
const key1 = newKey();
const key2 = newKey();
const score1 = 1;
const member1 = randomID();
const score2 = 2;
const member2 = randomID();

await new ZAddCommand([key1, { score: score1, member: member1 }]).exec(
client,
);
await new ZAddCommand([key2, { score: score2, member: member2 }]).exec(
client,
);

const res = await new ZUnionCommand([2, [key1, key2], {
aggregate: "sum",
}]).exec(client);

assertEquals(Array.isArray(res), true);
assertEquals(res.length, 2);
});
});
await t.step("min", async (t) => {
await t.step("returns the set ", async () => {
const key1 = newKey();
const key2 = newKey();
const score1 = 1;
const member1 = randomID();
const score2 = 2;
const member2 = randomID();

await new ZAddCommand([key1, { score: score1, member: member1 }]).exec(
client,
);
await new ZAddCommand([key2, { score: score2, member: member2 }]).exec(
client,
);

const res = await new ZUnionCommand([2, [key1, key2], {
aggregate: "min",
}]).exec(client);
assertEquals(res.length, 2);
});
});
await t.step("max", async (t) => {
await t.step("returns the set ", async () => {
const key1 = newKey();
const key2 = newKey();
const score1 = 1;
const member1 = randomID();
const score2 = 2;
const member2 = randomID();

await new ZAddCommand([key1, { score: score1, member: member1 }]).exec(
client,
);
await new ZAddCommand([key2, { score: score2, member: member2 }]).exec(
client,
);

const res = await new ZUnionCommand([2, [key1, key2], {
aggregate: "max",
}]).exec(client);
assertEquals(res.length, 2);
});
});
});

Deno.test("withscores", async (t) => {
await t.step("returns the set", async () => {
const key1 = newKey();
const score1 = 1;
const member1 = randomID();

const key2 = newKey();
const member2 = randomID();
const score2 = 5;

await new ZAddCommand([key1, { score: score1, member: member1 }]).exec(
client,
);

await new ZAddCommand([key2, { score: score2, member: member2 }]).exec(
client,
);

const res = await new ZUnionCommand([2, [key1, key2], {
withScores: true,
}]).exec(client);

assertEquals(res.length, 4);
assertEquals(res[0], member1);
assertEquals(res[1], score1);
});
});
64 changes: 64 additions & 0 deletions pkg/commands/zunion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { Command, CommandOptions } from "./command.ts";

export type ZUnionCommandOptions =
& {
withScores?: boolean;
aggregate?: "sum" | "min" | "max";
}
& (
| { weight: number; weights?: never }
| { weight?: never; weights: number[] }
| { weight?: never; weights?: never }
);

/**
* @see https://redis.io/commands/zunion
*/
export class ZUnionCommand<TData extends unknown[]>
extends Command<string[], TData> {
constructor(
cmd: [
numKeys: 1,
key: string,
opts?: ZUnionCommandOptions,
],
cmdOpts?: CommandOptions<string[], TData>,
);
constructor(
cmd: [
numKeys: number,
keys: string[],
opts?: ZUnionCommandOptions,
],
cmdOpts?: CommandOptions<string[], TData>,
);
constructor(
[numKeys, keyOrKeys, opts]: [
numKeys: number,
keyOrKeys: string | string[],
opts?: ZUnionCommandOptions,
],
cmdOpts?: CommandOptions<string[], TData>,
) {
const command: unknown[] = ["zunion", numKeys];
if (Array.isArray(keyOrKeys)) {
command.push(...keyOrKeys);
} else {
command.push(keyOrKeys);
}
if (opts) {
if ("weights" in opts && opts.weights) {
command.push("weights", ...opts.weights);
} else if ("weight" in opts && typeof opts.weight === "number") {
command.push("weights", opts.weight);
}
if ("aggregate" in opts) {
command.push("aggregate", opts.aggregate);
}
if (opts?.withScores) {
command.push("withscores");
}
}
super(command, cmdOpts);
}
}
3 changes: 2 additions & 1 deletion pkg/pipeline.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,10 @@ Deno.test("use all the things", async (t) => {
.zscan(newKey(), 0)
.zscore(newKey(), "member")
.zunionstore(newKey(), 1, [newKey()])
.zunion(1, [newKey()])
.json.set(newKey(), "$", { hello: "world" });

const res = await p.exec();
assertEquals(res.length, 120);
assertEquals(res.length, 121);
});
});
Loading