Skip to content

Commit 1f653fd

Browse files
committed
feat: added support for new bitop operations
refactored bitop tests, covered all operations updated default docker version on all packages
1 parent 2b3140b commit 1f653fd

File tree

10 files changed

+77
-13
lines changed

10 files changed

+77
-13
lines changed

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
fail-fast: false
2323
matrix:
2424
node-version: ["18", "20", "22"]
25-
redis-version: ["rs-7.2.0-v13", "rs-7.4.0-v1", "8.0.2"]
25+
redis-version: ["rs-7.2.0-v13", "rs-7.4.0-v1", "8.0.2", "8.2-M01-pre"]
2626
steps:
2727
- uses: actions/checkout@v4
2828
with:

packages/bloom/lib/test-utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import RedisBloomModules from '.';
44
export default TestUtils.createFromConfig({
55
dockerImageName: 'redislabs/client-libs-test',
66
dockerImageVersionArgument: 'redis-version',
7-
defaultDockerVersion: '8.0.2'
7+
defaultDockerVersion: '8.2-M01-pre'
88
});
99

1010
export const GLOBAL = {

packages/client/lib/commands/BITOP.spec.ts

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { strict as assert } from 'node:assert';
22
import testUtils, { GLOBAL } from '../test-utils';
3-
import BITOP from './BITOP';
3+
import BITOP, { BitOperations } from './BITOP';
44
import { parseArgs } from './generic-transformers';
55

66
describe('BITOP', () => {
@@ -20,13 +20,77 @@ describe('BITOP', () => {
2020
});
2121
});
2222

23-
testUtils.testAll('bitOp', async client => {
23+
for (const op of ['AND', 'OR', 'XOR'] as BitOperations[]) {
24+
testUtils.testAll(`bitOp ${op} with non-existing keys`, async client => {
25+
assert.equal(
26+
await client.bitOp(op, '{tag}destKey', ['{tag}key1', '{tag}key2']),
27+
0
28+
);
29+
}, {
30+
client: GLOBAL.SERVERS.OPEN,
31+
cluster: GLOBAL.CLUSTERS.OPEN
32+
});
33+
34+
testUtils.testAll(`bitOp ${op} with existing keys`, async client => {
35+
await client.set('{tag}key1', 'value1');
36+
await client.set('{tag}key2', 'value2');
37+
38+
assert.equal(
39+
await client.bitOp(op, '{tag}destKey', ['{tag}key1', '{tag}key2']),
40+
6
41+
);
42+
}, {
43+
client: GLOBAL.SERVERS.OPEN,
44+
cluster: GLOBAL.CLUSTERS.OPEN
45+
});
46+
}
47+
48+
// NOT operation requires only one key
49+
testUtils.testAll('bitOp NOT with non-existing keys', async client => {
2450
assert.equal(
25-
await client.bitOp('AND', '{tag}destKey', '{tag}key'),
51+
await client.bitOp('NOT', '{tag}destKey', '{tag}key'),
2652
0
2753
);
2854
}, {
2955
client: GLOBAL.SERVERS.OPEN,
3056
cluster: GLOBAL.CLUSTERS.OPEN
3157
});
58+
59+
testUtils.testAll('bitOp NOT with existing keys', async client => {
60+
await client.set('{tag}key', 'value');
61+
62+
assert.equal(
63+
await client.bitOp('NOT', '{tag}destKey', '{tag}key'),
64+
5
65+
);
66+
}, {
67+
client: GLOBAL.SERVERS.OPEN,
68+
cluster: GLOBAL.CLUSTERS.OPEN
69+
});
70+
71+
// newer operations supported since Redis 8.2
72+
for (const op of ['DIFF', 'DIFF1', 'ANDOR', 'ONE'] as BitOperations[]) {
73+
testUtils.testAll(`bitOp ${op} with non-existing keys`, async client => {
74+
assert.equal(
75+
await client.bitOp(op, '{tag}destKey', ['{tag}key1', '{tag}key2']),
76+
0
77+
);
78+
}, {
79+
client: { ...GLOBAL.SERVERS.OPEN, minimumDockerVersion: [8, 2] },
80+
cluster: { ...GLOBAL.CLUSTERS.OPEN, minimumDockerVersion: [8, 2] },
81+
});
82+
83+
testUtils.testAll(`bitOp ${op} with existing keys`, async client => {
84+
await client.set('{tag}key1', 'value1');
85+
await client.set('{tag}key2', 'value2');
86+
87+
assert.equal(
88+
await client.bitOp(op, '{tag}destKey', ['{tag}key1', '{tag}key2']),
89+
6
90+
);
91+
}, {
92+
client: { ...GLOBAL.SERVERS.OPEN, minimumDockerVersion: [8, 2] },
93+
cluster: { ...GLOBAL.CLUSTERS.OPEN, minimumDockerVersion: [8, 2] },
94+
});
95+
}
3296
});

packages/client/lib/commands/BITOP.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ import { CommandParser } from '../client/parser';
22
import { NumberReply, Command, RedisArgument } from '../RESP/types';
33
import { RedisVariadicArgument } from './generic-transformers';
44

5-
export type BitOperations = 'AND' | 'OR' | 'XOR' | 'NOT';
5+
export type BitOperations = 'AND' | 'OR' | 'XOR' | 'NOT' | 'DIFF' | 'DIFF1' | 'ANDOR' | 'ONE';
66

77
export default {
88
IS_READ_ONLY: false,
99
/**
1010
* Performs bitwise operations between strings
1111
* @param parser - The Redis command parser
12-
* @param operation - Bitwise operation to perform: AND, OR, XOR, NOT
12+
* @param operation - Bitwise operation to perform: AND, OR, XOR, NOT, DIFF, DIFF1, ANDOR, ONE
1313
* @param destKey - Destination key to store the result
1414
* @param key - Source key(s) to perform operation on
1515
*/

packages/client/lib/sentinel/test-util.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ export class SentinelFramework extends DockerBase {
174174
this.#testUtils = TestUtils.createFromConfig({
175175
dockerImageName: 'redislabs/client-libs-test',
176176
dockerImageVersionArgument: 'redis-version',
177-
defaultDockerVersion: '8.0.2'
177+
defaultDockerVersion: '8.2-M01-pre'
178178
});
179179
this.#nodeMap = new Map<string, ArrayElement<Awaited<ReturnType<SentinelFramework['spawnRedisSentinelNodes']>>>>();
180180
this.#sentinelMap = new Map<string, ArrayElement<Awaited<ReturnType<SentinelFramework['spawnRedisSentinelSentinels']>>>>();

packages/client/lib/test-utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import RedisBloomModules from '@redis/bloom';
99
const utils = TestUtils.createFromConfig({
1010
dockerImageName: 'redislabs/client-libs-test',
1111
dockerImageVersionArgument: 'redis-version',
12-
defaultDockerVersion: '8.0.2'
12+
defaultDockerVersion: '8.2-M01-pre'
1313
});
1414

1515
export default utils;

packages/entraid/lib/test-utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { EntraidCredentialsProvider } from './entraid-credentials-provider';
66
export const testUtils = TestUtils.createFromConfig({
77
dockerImageName: 'redislabs/client-libs-test',
88
dockerImageVersionArgument: 'redis-version',
9-
defaultDockerVersion: '8.0.2'
9+
defaultDockerVersion: '8.2-M01-pre'
1010
});
1111

1212
const DEBUG_MODE_ARGS = testUtils.isVersionGreaterThan([7]) ?

packages/json/lib/test-utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import RedisJSON from '.';
44
export default TestUtils.createFromConfig({
55
dockerImageName: 'redislabs/client-libs-test',
66
dockerImageVersionArgument: 'redis-version',
7-
defaultDockerVersion: '8.0.2'
7+
defaultDockerVersion: '8.2-M01-pre'
88
});
99

1010
export const GLOBAL = {

packages/search/lib/test-utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { RespVersions } from '@redis/client';
55
export default TestUtils.createFromConfig({
66
dockerImageName: 'redislabs/client-libs-test',
77
dockerImageVersionArgument: 'redis-version',
8-
defaultDockerVersion: '8.0.2'
8+
defaultDockerVersion: '8.2-M01-pre'
99
});
1010

1111
export const GLOBAL = {

packages/time-series/lib/test-utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import TimeSeries from '.';
44
export default TestUtils.createFromConfig({
55
dockerImageName: 'redislabs/client-libs-test',
66
dockerImageVersionArgument: 'redis-version',
7-
defaultDockerVersion: '8.0.2'
7+
defaultDockerVersion: '8.2-M01-pre'
88
});
99

1010
export const GLOBAL = {

0 commit comments

Comments
 (0)