1
0
mirror of https://github.com/redis/node-redis.git synced 2025-08-06 02:15:48 +03:00
This commit is contained in:
Leibale
2023-06-29 14:39:49 -04:00
parent ea2d9d2a77
commit c109fbf751
36 changed files with 584 additions and 720 deletions

View File

@@ -23,7 +23,9 @@ describe('BGSAVE', () => {
testUtils.testWithClient('client.bgSave', async client => {
assert.equal(
typeof await client.bgSave(),
typeof await client.bgSave({
SCHEDULE: true // using `SCHEDULE` to make sure it won't throw an error
}),
'string'
);
}, GLOBAL.SERVERS.OPEN);

View File

@@ -1,43 +1,35 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './BLMOVE';
import { commandOptions } from '../../index';
import BLMOVE from './BLMOVE';
describe('BLMOVE', () => {
testUtils.isVersionGreaterThanHook([6, 2]);
testUtils.isVersionGreaterThanHook([6, 2]);
it('transformArguments', () => {
assert.deepEqual(
transformArguments('source', 'destination', 'LEFT', 'RIGHT', 0),
['BLMOVE', 'source', 'destination', 'LEFT', 'RIGHT', '0']
);
});
it('transformArguments', () => {
assert.deepEqual(
BLMOVE.transformArguments('source', 'destination', 'LEFT', 'RIGHT', 0),
['BLMOVE', 'source', 'destination', 'LEFT', 'RIGHT', '0']
);
});
testUtils.testWithClient('client.blMove', async client => {
const [blMoveReply] = await Promise.all([
client.blMove(commandOptions({
isolated: true
}), 'source', 'destination', 'LEFT', 'RIGHT', 0),
client.lPush('source', 'element')
]);
testUtils.testAll('blMove - null', async client => {
assert.equal(
await client.blMove('{tag}source', '{tag}destination', 'LEFT', 'RIGHT', Number.MIN_VALUE),
null
);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
assert.equal(
blMoveReply,
'element'
);
}, GLOBAL.SERVERS.OPEN);
testUtils.testWithCluster('cluster.blMove', async cluster => {
const [blMoveReply] = await Promise.all([
cluster.blMove(commandOptions({
isolated: true
}), '{tag}source', '{tag}destination', 'LEFT', 'RIGHT', 0),
cluster.lPush('{tag}source', 'element')
]);
assert.equal(
blMoveReply,
'element'
);
}, GLOBAL.CLUSTERS.OPEN);
testUtils.testAll('blMove - with member', async client => {
const [, reply] = await Promise.all([
client.lPush('{tag}source', 'element'),
client.blMove('{tag}source', '{tag}destination', 'LEFT', 'RIGHT', Number.MIN_VALUE)
]);
assert.equal(reply, 'element');
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
});

View File

@@ -1,32 +1,49 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './BLMPOP';
import BLMPOP from './BLMPOP';
describe('BLMPOP', () => {
testUtils.isVersionGreaterThanHook([7]);
testUtils.isVersionGreaterThanHook([7]);
describe('transformArguments', () => {
it('simple', () => {
assert.deepEqual(
transformArguments(0, 'key', 'LEFT'),
['BLMPOP', '0', '1', 'key', 'LEFT']
);
});
it('with COUNT', () => {
assert.deepEqual(
transformArguments(0, 'key', 'LEFT', {
COUNT: 2
}),
['BLMPOP', '0', '1', 'key', 'LEFT', 'COUNT', '2']
);
});
describe('transformArguments', () => {
it('simple', () => {
assert.deepEqual(
BLMPOP.transformArguments(0, 'key', 'LEFT'),
['BLMPOP', '0', '1', 'key', 'LEFT']
);
});
testUtils.testWithClient('client.blmPop', async client => {
assert.deepEqual(
await client.blmPop(1, 'key', 'RIGHT'),
null
);
}, GLOBAL.SERVERS.OPEN);
it('with COUNT', () => {
assert.deepEqual(
BLMPOP.transformArguments(0, 'key', 'LEFT', {
COUNT: 1
}),
['BLMPOP', '0', '1', 'key', 'LEFT', 'COUNT', '1']
);
});
});
testUtils.testAll('blmPop - null', async client => {
assert.equal(
await client.blmPop(Number.MIN_VALUE, 'key', 'RIGHT'),
null
);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
testUtils.testAll('blmPop - with member', async client => {
const [, reply] = await Promise.all([
client.lPush('key', 'element'),
client.blmPop(Number.MIN_VALUE, 'key', 'RIGHT')
]);
assert.deepEqual(reply, [
'key',
['element']
]);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
});

View File

@@ -1,21 +1,16 @@
import { Command } from '../RESP/types';
import { ListSide, RedisVariadicArgument } from './generic-transformers';
import LMPOP, { LMPopOptions, transformLMPopArguments } from './LMPOP';
import LMPOP, { LMPopArguments, transformLMPopArguments } from './LMPOP';
export default {
FIRST_KEY_INDEX: 3,
IS_READ_ONLY: false,
transformArguments(
timeout: number,
keys: RedisVariadicArgument,
side: ListSide,
options?: LMPopOptions
...args: LMPopArguments
) {
return transformLMPopArguments(
['BLMPOP', timeout.toString()],
keys,
side,
options
...args
);
},
transformReply: LMPOP.transformReply

View File

@@ -1,79 +1,46 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments, transformReply } from './BLPOP';
import { commandOptions } from '../../index';
import BLPOP from './BLPOP';
describe('BLPOP', () => {
describe('transformArguments', () => {
it('single', () => {
assert.deepEqual(
transformArguments('key', 0),
['BLPOP', 'key', '0']
);
});
it('multiple', () => {
assert.deepEqual(
transformArguments(['key1', 'key2'], 0),
['BLPOP', 'key1', 'key2', '0']
);
});
describe('transformArguments', () => {
it('single', () => {
assert.deepEqual(
BLPOP.transformArguments('key', 0),
['BLPOP', 'key', '0']
);
});
describe('transformReply', () => {
it('null', () => {
assert.equal(
transformReply(null),
null
);
});
it('member', () => {
assert.deepEqual(
transformReply(['key', 'element']),
{
key: 'key',
element: 'element'
}
);
});
it('multiple', () => {
assert.deepEqual(
BLPOP.transformArguments(['1', '2'], 0),
['BLPOP', '1', '2', '0']
);
});
});
testUtils.testWithClient('client.blPop', async client => {
const [ blPopReply ] = await Promise.all([
client.blPop(
commandOptions({ isolated: true }),
'key',
1
),
client.lPush('key', 'element'),
]);
testUtils.testAll('blPop - null', async client => {
assert.equal(
await client.blPop('key', Number.MIN_VALUE),
null
);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
assert.deepEqual(
blPopReply,
{
key: 'key',
element: 'element'
}
);
}, GLOBAL.SERVERS.OPEN);
testUtils.testAll('blPop - with member', async client => {
const [, reply] = await Promise.all([
client.lPush('key', 'element'),
client.blPop('key', 1)
]);
testUtils.testWithCluster('cluster.blPop', async cluster => {
const [ blPopReply ] = await Promise.all([
cluster.blPop(
commandOptions({ isolated: true }),
'key',
1
),
cluster.lPush('key', 'element')
]);
assert.deepEqual(
blPopReply,
{
key: 'key',
element: 'element'
}
);
}, GLOBAL.CLUSTERS.OPEN);
assert.deepEqual(reply, {
key: 'key',
element: 'element'
});
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
});

View File

@@ -8,7 +8,7 @@ export default {
key: RedisVariadicArgument,
timeout: number
) {
const args = pushVariadicArguments(['BRPOP'], key);
const args = pushVariadicArguments(['BLPOP'], key);
args.push(timeout.toString());
return args;
},

View File

@@ -1,79 +1,46 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments, transformReply } from './BRPOP';
import { commandOptions } from '../../index';
import BRPOP from './BRPOP';
describe('BRPOP', () => {
describe('transformArguments', () => {
it('single', () => {
assert.deepEqual(
transformArguments('key', 0),
['BRPOP', 'key', '0']
);
});
it('multiple', () => {
assert.deepEqual(
transformArguments(['key1', 'key2'], 0),
['BRPOP', 'key1', 'key2', '0']
);
});
describe('transformArguments', () => {
it('single', () => {
assert.deepEqual(
BRPOP.transformArguments('key', 0),
['BRPOP', 'key', '0']
);
});
describe('transformReply', () => {
it('null', () => {
assert.equal(
transformReply(null),
null
);
});
it('member', () => {
assert.deepEqual(
transformReply(['key', 'element']),
{
key: 'key',
element: 'element'
}
);
});
it('multiple', () => {
assert.deepEqual(
BRPOP.transformArguments(['1', '2'], 0),
['BRPOP', '1', '2', '0']
);
});
});
testUtils.testWithClient('client.brPop', async client => {
const [ brPopReply ] = await Promise.all([
client.brPop(
commandOptions({ isolated: true }),
'key',
1
),
client.lPush('key', 'element'),
]);
testUtils.testAll('brPop - null', async client => {
assert.equal(
await client.brPop('key', Number.MIN_VALUE),
null
);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
assert.deepEqual(
brPopReply,
{
key: 'key',
element: 'element'
}
);
}, GLOBAL.SERVERS.OPEN);
testUtils.testAll('brPopblPop - with member', async client => {
const [, reply] = await Promise.all([
client.lPush('key', 'element'),
client.brPop('key', 1)
]);
testUtils.testWithCluster('cluster.brPop', async cluster => {
const [ brPopReply ] = await Promise.all([
cluster.brPop(
commandOptions({ isolated: true }),
'key',
1
),
cluster.lPush('key', 'element'),
]);
assert.deepEqual(
brPopReply,
{
key: 'key',
element: 'element'
}
);
}, GLOBAL.CLUSTERS.OPEN);
assert.deepEqual(reply, {
key: 'key',
element: 'element'
});
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
});

View File

@@ -1,47 +1,42 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './BRPOPLPUSH';
import { commandOptions } from '../../index';
import BRPOPLPUSH from './BRPOPLPUSH';
describe('BRPOPLPUSH', () => {
it('transformArguments', () => {
assert.deepEqual(
transformArguments('source', 'destination', 0),
['BRPOPLPUSH', 'source', 'destination', '0']
);
});
it('transformArguments', () => {
assert.deepEqual(
BRPOPLPUSH.transformArguments('source', 'destination', 0),
['BRPOPLPUSH', 'source', 'destination', '0']
);
});
testUtils.testWithClient('client.brPopLPush', async client => {
const [ popReply ] = await Promise.all([
client.brPopLPush(
commandOptions({ isolated: true }),
'source',
'destination',
0
),
client.lPush('source', 'element')
]);
testUtils.testAll('brPopLPush - null', async client => {
assert.equal(
await client.brPopLPush(
'{tag}source',
'{tag}destination',
Number.MIN_VALUE
),
null
);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
assert.equal(
popReply,
'element'
);
}, GLOBAL.SERVERS.OPEN);
testUtils.testAll('brPopLPush - with member', async client => {
const [, reply] = await Promise.all([
client.lPush('{tag}source', 'element'),
client.brPopLPush(
'{tag}source',
'{tag}destination',
0
)
]);
testUtils.testWithCluster('cluster.brPopLPush', async cluster => {
const [ popReply ] = await Promise.all([
cluster.brPopLPush(
commandOptions({ isolated: true }),
'{tag}source',
'{tag}destination',
0
),
cluster.lPush('{tag}source', 'element')
]);
assert.equal(
popReply,
'element'
);
}, GLOBAL.CLUSTERS.OPEN);
assert.equal(reply, 'element');
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
});

View File

@@ -1,32 +1,55 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './BZMPOP';
import BZMPOP from './BZMPOP';
describe('BZMPOP', () => {
testUtils.isVersionGreaterThanHook([7]);
testUtils.isVersionGreaterThanHook([7]);
describe('transformArguments', () => {
it('simple', () => {
assert.deepEqual(
transformArguments(0, 'key', 'MIN'),
['BZMPOP', '0', '1', 'key', 'MIN']
);
});
it('with COUNT', () => {
assert.deepEqual(
transformArguments(0, 'key', 'MIN', {
COUNT: 2
}),
['BZMPOP', '0', '1', 'key', 'MIN', 'COUNT', '2']
);
});
describe('transformArguments', () => {
it('simple', () => {
assert.deepEqual(
BZMPOP.transformArguments(0, 'key', 'MIN'),
['BZMPOP', '0', '1', 'key', 'MIN']
);
});
testUtils.testWithClient('client.bzmPop', async client => {
assert.deepEqual(
await client.bzmPop(1, 'key', 'MAX'),
null
);
}, GLOBAL.SERVERS.OPEN);
it('with COUNT', () => {
assert.deepEqual(
BZMPOP.transformArguments(0, 'key', 'MIN', {
COUNT: 2
}),
['BZMPOP', '0', '1', 'key', 'MIN', 'COUNT', '2']
);
});
});
testUtils.testAll('bzmPop - null', async client => {
assert.equal(
await client.bzmPop(Number.MIN_VALUE, 'key', 'MAX'),
null
);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.SERVERS.OPEN
});
testUtils.testAll('bzmPop - with member', async client => {
const key = 'key',
member = {
value: 'a',
score: 1
},
[, reply] = await Promise.all([
client.zAdd(key, member),
client.bzmPop(Number.MIN_VALUE, key, 'MAX')
]);
assert.deepEqual(reply, {
key,
members: [member]
});
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.SERVERS.OPEN
});
});

View File

@@ -1,34 +1,11 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.';
// import { SortedSetSide, transformZMPopArguments, ZMPopOptions } from './generic-transformers';
// export const FIRST_KEY_INDEX = 3;
// export function transformArguments(
// timeout: number,
// keys: RedisCommandArgument | Array<RedisCommandArgument>,
// side: SortedSetSide,
// options?: ZMPopOptions
// ): RedisCommandArguments {
// return transformZMPopArguments(
// ['BZMPOP', timeout.toString()],
// keys,
// side,
// options
// );
// }
// export { transformReply } from './ZMPOP';
// import { Command } from '../RESP/types';
// import ZMPOP from './ZMPOP';
// export default {
// FIRST_KEY_INDEX: 3,
// IS_READ_ONLY: false,
// transformArguments() {
// return ['BZMPOP'];
// },
// transformReply: ZMPOP.transformReply
// } as const satisfies Command;
import { Command } from '../RESP/types';
import ZMPOP, { ZMPopArguments, transformZMPopArguments } from './ZMPOP';
export default {
FIRST_KEY_INDEX: 3,
IS_READ_ONLY: false,
transformArguments(timeout: number, ...args: ZMPopArguments) {
return transformZMPopArguments(['BZMPOP', timeout.toString()], ...args);
},
transformReply: ZMPOP.transformReply
} as const satisfies Command;

View File

@@ -1,65 +1,51 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments, transformReply } from './BZPOPMAX';
import { commandOptions } from '../../index';
import BZPOPMAX from './BZPOPMAX';
describe('BZPOPMAX', () => {
describe('transformArguments', () => {
it('single', () => {
assert.deepEqual(
transformArguments('key', 0),
['BZPOPMAX', 'key', '0']
);
});
it('multiple', () => {
assert.deepEqual(
transformArguments(['1', '2'], 0),
['BZPOPMAX', '1', '2', '0']
);
});
describe('transformArguments', () => {
it('single', () => {
assert.deepEqual(
BZPOPMAX.transformArguments('key', 0),
['BZPOPMAX', 'key', '0']
);
});
describe('transformReply', () => {
it('null', () => {
assert.equal(
transformReply(null),
null
);
});
it('member', () => {
assert.deepEqual(
transformReply(['key', 'value', '1']),
{
key: 'key',
value: 'value',
score: 1
}
);
});
it('multiple', () => {
assert.deepEqual(
BZPOPMAX.transformArguments(['1', '2'], 0),
['BZPOPMAX', '1', '2', '0']
);
});
});
testUtils.testWithClient('client.bzPopMax', async client => {
const [ bzPopMaxReply ] = await Promise.all([
client.bzPopMax(
commandOptions({ isolated: true }),
'key',
1
),
client.zAdd('key', [{
value: '1',
score: 1
}])
]);
testUtils.testAll('bzPopMax - null', async client => {
assert.equal(
await client.bzPopMax('key', Number.MIN_VALUE),
null
);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.SERVERS.OPEN
});
assert.deepEqual(
bzPopMaxReply,
{
key: 'key',
value: '1',
score: 1
}
);
}, GLOBAL.SERVERS.OPEN);
testUtils.testAll('bzPopMax - with member', async client => {
const key = 'key',
member = {
value: 'a',
score: 1
},
[, reply] = await Promise.all([
client.zAdd(key, member),
client.bzPopMax(key, Number.MIN_VALUE)
]);
assert.deepEqual(reply, {
key,
...member
});
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.SERVERS.OPEN
});
});

View File

@@ -1,29 +1,39 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.';
// import { pushVariadicArguments, transformDoubleReply, ZMember } from './generic-transformers';
import { RedisArgument, Command, NullReply, TuplesReply, BlobStringReply, DoubleReply } from '../RESP/types';
import { RedisVariadicArgument, pushVariadicArguments } from './generic-transformers';
// export const FIRST_KEY_INDEX = 1;
export function transformBZPopArguments(
command: RedisArgument,
key: RedisVariadicArgument,
timeout: number
) {
const args = pushVariadicArguments([command], key);
args.push(timeout.toString());
return args;
}
// export function transformArguments(
// key: RedisCommandArgument | Array<RedisCommandArgument>,
// timeout: number
// ): RedisCommandArguments {
// const args = pushVariadicArguments(['BZPOPMAX'], key);
export type BZPopArguments = typeof transformBZPopArguments extends (_: any, ...args: infer T) => any ? T : never;
// args.push(timeout.toString());
export default {
FIRST_KEY_INDEX: 1,
IS_READ_ONLY: false,
transformArguments(...args: BZPopArguments) {
return transformBZPopArguments('BZPOPMAX', ...args);
},
transformReply: {
2: (reply: NullReply | TuplesReply<[BlobStringReply, BlobStringReply, BlobStringReply]>) => {
return reply === null ? null : {
key: reply[0],
value: reply[1],
score: Number(reply[2])
};
},
3: (reply: NullReply | TuplesReply<[BlobStringReply, BlobStringReply, DoubleReply]>) => {
return reply === null ? null : {
key: reply[0],
value: reply[1],
score: reply[2]
};
}
}
} as const satisfies Command;
// return args;
// }
// type ZMemberRawReply = [key: RedisCommandArgument, value: RedisCommandArgument, score: RedisCommandArgument] | null;
// type BZPopMaxReply = (ZMember & { key: RedisCommandArgument }) | null;
// export function transformReply(reply: ZMemberRawReply): BZPopMaxReply | null {
// if (!reply) return null;
// return {
// key: reply[0],
// value: reply[1],
// score: transformDoubleReply(reply[2])
// };
// }

View File

@@ -1,65 +1,51 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments, transformReply } from './BZPOPMIN';
import { commandOptions } from '../../index';
import BZPOPMIN from './BZPOPMIN';
describe('BZPOPMIN', () => {
describe('transformArguments', () => {
it('single', () => {
assert.deepEqual(
transformArguments('key', 0),
['BZPOPMIN', 'key', '0']
);
});
it('multiple', () => {
assert.deepEqual(
transformArguments(['1', '2'], 0),
['BZPOPMIN', '1', '2', '0']
);
});
describe('transformArguments', () => {
it('single', () => {
assert.deepEqual(
BZPOPMIN.transformArguments('key', 0),
['BZPOPMIN', 'key', '0']
);
});
describe('transformReply', () => {
it('null', () => {
assert.equal(
transformReply(null),
null
);
});
it('member', () => {
assert.deepEqual(
transformReply(['key', 'value', '1']),
{
key: 'key',
value: 'value',
score: 1
}
);
});
it('multiple', () => {
assert.deepEqual(
BZPOPMIN.transformArguments(['1', '2'], 0),
['BZPOPMIN', '1', '2', '0']
);
});
});
testUtils.testWithClient('client.bzPopMin', async client => {
const [ bzPopMinReply ] = await Promise.all([
client.bzPopMin(
commandOptions({ isolated: true }),
'key',
1
),
client.zAdd('key', [{
value: '1',
score: 1
}])
]);
testUtils.testAll('bzPopMin - null', async client => {
assert.equal(
await client.bzPopMin('key', Number.MIN_VALUE),
null
);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.SERVERS.OPEN
});
assert.deepEqual(
bzPopMinReply,
{
key: 'key',
value: '1',
score: 1
}
);
}, GLOBAL.SERVERS.OPEN);
testUtils.testAll('bzPopMin - with member', async client => {
const key = 'key',
member = {
value: 'a',
score: 1
},
[, reply] = await Promise.all([
client.zAdd(key, member),
client.bzPopMin(key, Number.MIN_VALUE)
]);
assert.deepEqual(reply, {
key,
...member
});
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.SERVERS.OPEN
});
});

View File

@@ -1,17 +1,12 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.';
// import { pushVariadicArguments } from './generic-transformers';
import { Command } from '../RESP/types';
import BZPOPMAX, { BZPopArguments, transformBZPopArguments } from './BZPOPMAX';
// export const FIRST_KEY_INDEX = 1;
export default {
FIRST_KEY_INDEX: BZPOPMAX.FIRST_KEY_INDEX,
IS_READ_ONLY: BZPOPMAX.IS_READ_ONLY,
transformArguments(...args: BZPopArguments) {
return transformBZPopArguments('BZPOPMIN', ...args);
},
transformReply: BZPOPMAX.transformReply
} as const satisfies Command;
// export function transformArguments(
// key: RedisCommandArgument | Array<RedisCommandArgument>,
// timeout: number
// ): RedisCommandArguments {
// const args = pushVariadicArguments(['BZPOPMIN'], key);
// args.push(timeout.toString());
// return args;
// }
// export { transformReply } from './BZPOPMAX';

View File

@@ -23,8 +23,7 @@ describe('HGETALL', () => {
Object.create(null, {
field: {
value: 'value',
enumerable: true,
writable: true
enumerable: true
}
})
);

View File

@@ -23,8 +23,8 @@ describe('LMPOP', () => {
});
});
testUtils.testAll('lmPop', async client => {
assert.deepEqual(
testUtils.testAll('lmPop - null', async client => {
assert.equal(
await client.lmPop('key', 'RIGHT'),
null
);
@@ -32,4 +32,19 @@ describe('LMPOP', () => {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.SERVERS.OPEN
});
testUtils.testAll('lmPop - with member', async client => {
const [, reply] = await Promise.all([
client.lPush('key', 'element'),
client.lmPop('key', 'RIGHT')
]);
assert.deepEqual(reply, [
'key',
['element']
]);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.SERVERS.OPEN
});
});

View File

@@ -11,31 +11,24 @@ export function transformLMPopArguments(
side: ListSide,
options?: LMPopOptions
): CommandArguments {
pushVariadicArgument(args, keys);
args = pushVariadicArgument(args, keys);
args.push(side);
if (options?.COUNT) {
if (options?.COUNT !== undefined) {
args.push('COUNT', options.COUNT.toString());
}
return args;
}
export type LMPopArguments = typeof transformLMPopArguments extends (_: any, ...args: infer T) => any ? T : never;
export default {
FIRST_KEY_INDEX: 2,
IS_READ_ONLY: false,
transformArguments(
keys: RedisVariadicArgument,
side: ListSide,
options?: LMPopOptions
) {
return transformLMPopArguments(
['LMPOP'],
keys,
side,
options
);
transformArguments(...args: LMPopArguments) {
return transformLMPopArguments(['LMPOP'], ...args);
},
transformReply: undefined as unknown as () => NullReply | TuplesReply<[
key: BlobStringReply,

View File

@@ -1,42 +1,59 @@
// import { strict as assert } from 'assert';
// import testUtils, { GLOBAL } from '../test-utils';
// import { transformArguments } from './XAUTOCLAIM';
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import XAUTOCLAIM from './XAUTOCLAIM';
// describe('XAUTOCLAIM', () => {
// testUtils.isVersionGreaterThanHook([6, 2]);
describe('XAUTOCLAIM', () => {
testUtils.isVersionGreaterThanHook([6, 2]);
// describe('transformArguments', () => {
// it('simple', () => {
// assert.deepEqual(
// transformArguments('key', 'group', 'consumer', 1, '0-0'),
// ['XAUTOCLAIM', 'key', 'group', 'consumer', '1', '0-0']
// );
// });
describe('transformArguments', () => {
it('simple', () => {
assert.deepEqual(
XAUTOCLAIM.transformArguments('key', 'group', 'consumer', 1, '0-0'),
['XAUTOCLAIM', 'key', 'group', 'consumer', '1', '0-0']
);
});
// it('with COUNT', () => {
// assert.deepEqual(
// transformArguments('key', 'group', 'consumer', 1, '0-0', {
// COUNT: 1
// }),
// ['XAUTOCLAIM', 'key', 'group', 'consumer', '1', '0-0', 'COUNT', '1']
// );
// });
// });
it('with COUNT', () => {
assert.deepEqual(
XAUTOCLAIM.transformArguments('key', 'group', 'consumer', 1, '0-0', {
COUNT: 1
}),
['XAUTOCLAIM', 'key', 'group', 'consumer', '1', '0-0', 'COUNT', '1']
);
});
});
// testUtils.testWithClient('client.xAutoClaim', async client => {
// await Promise.all([
// client.xGroupCreate('key', 'group', '$', {
// MKSTREAM: true
// }),
// client.xGroupCreateConsumer('key', 'group', 'consumer'),
// ]);
testUtils.testAll('xAutoClaim', async client => {
const message = Object.create(null, {
field: {
value: 'value',
enumerable: true
}
});
// assert.deepEqual(
// await client.xAutoClaim('key', 'group', 'consumer', 1, '0-0'),
// {
// nextId: '0-0',
// messages: []
// }
// );
// }, GLOBAL.SERVERS.OPEN);
// });
const [, , id, , reply] = await Promise.all([
client.xGroupCreate('key', 'group', '$', {
MKSTREAM: true
}),
client.xGroupCreateConsumer('key', 'group', 'consumer'),
client.xAdd('key', '*', message),
client.xReadGroup('group', 'consumer', {
key: 'key',
id: '>'
}),
client.xAutoClaim('key', 'group', 'consumer', 0, '0-0')
]);
assert.deepEqual(reply, {
nextId: '0-0',
messages: [{
id,
message
}],
deletedMessages: testUtils.isVersionGreaterThan([7, 0]) ? [] : undefined
});
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
});

View File

@@ -1,31 +1,37 @@
// import { strict as assert } from 'assert';
// import testUtils, { GLOBAL } from '../test-utils';
// import { transformArguments } from './XAUTOCLAIM_JUSTID';
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import XAUTOCLAIM_JUSTID from './XAUTOCLAIM_JUSTID';
// describe('XAUTOCLAIM JUSTID', () => {
// testUtils.isVersionGreaterThanHook([6, 2]);
describe('XAUTOCLAIM JUSTID', () => {
testUtils.isVersionGreaterThanHook([6, 2]);
// it('transformArguments', () => {
// assert.deepEqual(
// transformArguments('key', 'group', 'consumer', 1, '0-0'),
// ['XAUTOCLAIM', 'key', 'group', 'consumer', '1', '0-0', 'JUSTID']
// );
// });
it('transformArguments', () => {
assert.deepEqual(
XAUTOCLAIM_JUSTID.transformArguments('key', 'group', 'consumer', 1, '0-0'),
['XAUTOCLAIM', 'key', 'group', 'consumer', '1', '0-0', 'JUSTID']
);
});
// testUtils.testWithClient('client.xAutoClaimJustId', async client => {
// await Promise.all([
// client.xGroupCreate('key', 'group', '$', {
// MKSTREAM: true
// }),
// client.xGroupCreateConsumer('key', 'group', 'consumer'),
// ]);
testUtils.testWithClient('client.xAutoClaimJustId', async client => {
const [, , id, , reply] = await Promise.all([
client.xGroupCreate('key', 'group', '$', {
MKSTREAM: true
}),
client.xGroupCreateConsumer('key', 'group', 'consumer'),
client.xAdd('key', '*', {
field: 'value'
}),
client.xReadGroup('group', 'consumer', {
key: 'key',
id: '>'
}),
client.xAutoClaimJustId('key', 'group', 'consumer', 0, '0-0')
]);
// assert.deepEqual(
// await client.xAutoClaimJustId('key', 'group', 'consumer', 1, '0-0'),
// {
// nextId: '0-0',
// messages: []
// }
// );
// }, GLOBAL.SERVERS.OPEN);
// });
assert.deepEqual(reply, {
nextId: '0-0',
messages: [id],
deletedMessages: testUtils.isVersionGreaterThan([7, 0]) ? [] : undefined
});
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -1,19 +1,19 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './XGROUP_CREATE';
import XGROUP_CREATE from './XGROUP_CREATE';
describe('XGROUP CREATE', () => {
describe('transformArguments', () => {
it('simple', () => {
assert.deepEqual(
transformArguments('key', 'group', '$'),
XGROUP_CREATE.transformArguments('key', 'group', '$'),
['XGROUP', 'CREATE', 'key', 'group', '$']
);
});
it('with MKSTREAM', () => {
assert.deepEqual(
transformArguments('key', 'group', '$', {
XGROUP_CREATE.transformArguments('key', 'group', '$', {
MKSTREAM: true
}),
['XGROUP', 'CREATE', 'key', 'group', '$', 'MKSTREAM']
@@ -22,7 +22,7 @@ describe('XGROUP CREATE', () => {
it('with ENTRIESREAD', () => {
assert.deepEqual(
transformArguments('key', 'group', '$', {
XGROUP_CREATE.transformArguments('key', 'group', '$', {
ENTRIESREAD: 1
}),
['XGROUP', 'CREATE', 'key', 'group', '$', 'ENTRIESREAD', '1']
@@ -39,6 +39,6 @@ describe('XGROUP CREATE', () => {
);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.SERVERS.OPEN
cluster: GLOBAL.CLUSTERS.OPEN
});
});

View File

@@ -1,17 +1,3 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.';
// export const FIRST_KEY_INDEX = 2;
// export function transformArguments(
// key: RedisCommandArgument,
// group: RedisCommandArgument,
// consumer: RedisCommandArgument
// ): RedisCommandArguments {
// return ['XGROUP', 'DELCONSUMER', key, group, consumer];
// }
// export declare function transformReply(): number;
import { RedisArgument, NumberReply, Command } from '../RESP/types';
export default {

View File

@@ -20,12 +20,15 @@ describe('XINFO STREAM', () => {
assert.deepEqual(reply, {
length: 0,
radixTreeKeys: 0,
radixTreeNodes: 1,
'radix-tree-keys': 0,
'radix-tree-nodes': 1,
'last-generated-id': '0-0',
'max-deleted-entry-id': '0-0',
'entries-added': 0,
'recorded-first-entry-id': '0-0',
groups: 1,
lastGeneratedId: '0-0',
firstEntry: null,
lastEntry: null
'first-entry': null,
'last-entry': null
});
}, {
client: GLOBAL.SERVERS.OPEN,

View File

@@ -1,68 +1,3 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.';
// import { StreamMessageReply, transformTuplesReply } from './generic-transformers';
// export const FIRST_KEY_INDEX = 2;
// export const IS_READ_ONLY = true;
// export function transformArguments(key: RedisCommandArgument): RedisCommandArguments {
// return ['XINFO', 'STREAM', key];
// }
// interface XInfoStreamReply {
// length: number;
// radixTreeKeys: number;
// radixTreeNodes: number;
// groups: number;
// lastGeneratedId: RedisCommandArgument;
// firstEntry: StreamMessageReply | null;
// lastEntry: StreamMessageReply | null;
// }
// export function transformReply(rawReply: Array<any>): XInfoStreamReply {
// const parsedReply: Partial<XInfoStreamReply> = {};
// for (let i = 0; i < rawReply.length; i+= 2) {
// switch (rawReply[i]) {
// case 'length':
// parsedReply.length = rawReply[i + 1];
// break;
// case 'radix-tree-keys':
// parsedReply.radixTreeKeys = rawReply[i + 1];
// break;
// case 'radix-tree-nodes':
// parsedReply.radixTreeNodes = rawReply[i + 1];
// break;
// case 'groups':
// parsedReply.groups = rawReply[i + 1];
// break;
// case 'last-generated-id':
// parsedReply.lastGeneratedId = rawReply[i + 1];
// break;
// case 'first-entry':
// parsedReply.firstEntry = rawReply[i + 1] ? {
// id: rawReply[i + 1][0],
// message: transformTuplesReply(rawReply[i + 1][1])
// } : null;
// break;
// case 'last-entry':
// parsedReply.lastEntry = rawReply[i + 1] ? {
// id: rawReply[i + 1][0],
// message: transformTuplesReply(rawReply[i + 1][1])
// } : null;
// break;
// }
// }
// return parsedReply as XInfoStreamReply;
// }
import { TuplesToMapReply, BlobStringReply, NumberReply, NullReply, Resp2Reply, Command, RespType, RESP_TYPES, RedisArgument } from '../RESP/types';
import { StreamMessageRawReply, transformStreamMessageReply } from './generic-transformers';

View File

@@ -59,7 +59,7 @@ describe('XPENDING RANGE', () => {
assert.equal(reply[0].id, id);
assert.equal(reply[0].consumer, 'consumer');
assert.equal(typeof reply[0].millisecondsSinceLastDelivery, 'number');
assert.equal(reply[0].deliveriesCounter, '1');
assert.equal(reply[0].deliveriesCounter, 1);
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN

View File

@@ -1,48 +1,3 @@
// import { RedisCommandArgument, RedisCommandArguments } from '.';
// export const FIRST_KEY_INDEX = 1;
// export const IS_READ_ONLY = true;
// interface XPendingRangeOptions {
// IDLE?: number;
// consumer?: RedisCommandArgument;
// }
// export function transformArguments(
// key: RedisCommandArgument,
// group: RedisCommandArgument,
// start: string,
// end: string,
// count: number,
// options?: XPendingRangeOptions
// ): RedisCommandArguments {
// const args = ['XPENDING', key, group];
// if (options?.IDLE) {
// args.push('IDLE', options.IDLE.toString());
// }
// args.push(start, end, count.toString());
// if (options?.consumer) {
// args.push(options.consumer);
// }
// return args;
// }
// export function transformReply(reply: XPendingRangeRawReply): XPendingRangeReply {
// return reply.map(([id, owner, millisecondsSinceLastDelivery, deliveriesCounter]) => ({
// id,
// owner,
// millisecondsSinceLastDelivery,
// deliveriesCounter
// }));
// }
import { RedisArgument, ArrayReply, TuplesReply, BlobStringReply, NumberReply, Command } from '../RESP/types';
export interface XPendingRangeOptions {

View File

@@ -22,11 +22,17 @@ describe('XRANGE', () => {
});
testUtils.testAll('xRange', async client => {
const message = { field: 'value' },
[id, reply] = await Promise.all([
client.xAdd('key', '*', message),
client.xRange('key', '-', '+')
]);
const message = Object.create(null, {
field: {
value: 'value',
enumerable: true
}
});
const [id, reply] = await Promise.all([
client.xAdd('key', '*', message),
client.xRange('key', '-', '+')
]);
assert.deepEqual(reply, [{
id,

View File

@@ -22,7 +22,7 @@ export default {
streams: XReadStreams,
options?: XReadGroupOptions
) {
const args = ['XREADGROUP', group, consumer];
const args = ['XREADGROUP', 'GROUP', group, consumer];
if (options?.COUNT !== undefined) {
args.push('COUNT', options.COUNT.toString());

View File

@@ -22,11 +22,17 @@ describe('XREVRANGE', () => {
});
testUtils.testAll('xRevRange', async client => {
const message = { field: 'value' },
[id, reply] = await Promise.all([
client.xAdd('key', '*', message),
client.xRevRange('key', '-', '+')
]);
const message = Object.create(null, {
field: {
value: 'value',
enumerable: true
}
});
const [id, reply] = await Promise.all([
client.xAdd('key', '*', message),
client.xRange('key', '-', '+')
]);
assert.deepEqual(reply, [{
id,

View File

@@ -133,7 +133,7 @@ describe('ZADD', () => {
testUtils.testAll('zAdd', async client => {
assert.equal(
await client.zAdd('key', {
value: '1',
value: 'a',
score: 1
}),
1

View File

@@ -81,7 +81,7 @@ describe('ZADD INCR', () => {
testUtils.testAll('zAddIncr', async client => {
assert.equal(
await client.zAddIncr('key', {
value: '1',
value: 'a',
score: 1
}),
1

View File

@@ -1,4 +1,4 @@
import { NullReply, TuplesReply, BlobStringReply, DoubleReply, ArrayReply, Resp2Reply, Command } from '../RESP/types';
import { NullReply, TuplesReply, BlobStringReply, DoubleReply, ArrayReply, Resp2Reply, Command, RedisArgument } from '../RESP/types';
import { pushVariadicArgument, RedisVariadicArgument, SortedSetSide, transformSortedSetReply } from './generic-transformers';
export interface ZMPopOptions {
@@ -13,23 +13,30 @@ export type ZMPopRawReply = NullReply | TuplesReply<[
]>>
]>;
export function transformZMPopArguments(
args: Array<RedisArgument>,
keys: RedisVariadicArgument,
side: SortedSetSide,
options?: ZMPopOptions
) {
args = pushVariadicArgument(args, keys);
args.push(side);
if (options?.COUNT) {
args.push('COUNT', options.COUNT.toString());
}
return args;
}
export type ZMPopArguments = typeof transformZMPopArguments extends (_: any, ...args: infer T) => any ? T : never;
export default {
FIRST_KEY_INDEX: 2,
IS_READ_ONLY: false,
transformArguments(
keys: RedisVariadicArgument,
side: SortedSetSide,
options?: ZMPopOptions
) {
const args = pushVariadicArgument(['ZMPOP'], keys);
args.push(side);
if (options?.COUNT) {
args.push('COUNT', options.COUNT.toString());
}
return args;
transformArguments(...args: ZMPopArguments) {
return transformZMPopArguments(['ZMPOP'], ...args);
},
transformReply: {
2: (reply: Resp2Reply<ZMPopRawReply>) => {

View File

@@ -1,5 +1,4 @@
import { RedisArgument, NullReply, TuplesReply, BlobStringReply, DoubleReply, Command } from '../RESP/types';
import ZPOPMIN from './ZPOPMIN';
import { RedisArgument, TuplesReply, BlobStringReply, DoubleReply, Command } from '../RESP/types';
export default {
FIRST_KEY_INDEX: 1,
@@ -7,5 +6,22 @@ export default {
transformArguments(key: RedisArgument) {
return ['ZPOPMAX', key];
},
transformReply: ZPOPMIN.transformReply
transformReply: {
2: (reply: TuplesReply<[]> | TuplesReply<[BlobStringReply, BlobStringReply]>) => {
if (reply.length === 0) return null;
return {
value: reply[0],
score: Number(reply[1])
};
},
3: (reply: TuplesReply<[]> | TuplesReply<[BlobStringReply, DoubleReply]>) => {
if (reply.length === 0) return null;
return {
value: reply[0],
score: reply[1]
};
}
}
} as const satisfies Command;

View File

@@ -14,14 +14,17 @@ describe('ZPOPMAX COUNT', () => {
const members = [{
value: '1',
score: 1
}, {
value: '2',
score: 2
}];
const [ , reply] = await Promise.all([
client.zAdd('key', members),
client.zPopMaxCount('key', 1)
client.zPopMaxCount('key', members.length)
]);
assert.deepEqual(reply, members);
assert.deepEqual(reply, members.reverse());
}, {
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.SERVERS.OPEN

View File

@@ -1,4 +1,5 @@
import { RedisArgument, TuplesReply, BlobStringReply, DoubleReply, Command } from '../RESP/types';
import { RedisArgument, Command } from '../RESP/types';
import ZPOPMAX from './ZPOPMAX';
export default {
FIRST_KEY_INDEX: 1,
@@ -6,22 +7,5 @@ export default {
transformArguments(key: RedisArgument) {
return ['ZPOPMIN', key];
},
transformReply: {
2: (reply: TuplesReply<[]> | TuplesReply<[BlobStringReply, BlobStringReply]>) => {
if (reply.length === 0) return null;
return {
value: reply[0],
score: Number(reply[1])
};
},
3: (reply: TuplesReply<[]> | TuplesReply<[BlobStringReply, DoubleReply]>) => {
if (reply.length === 0) return null;
return {
value: reply[0],
score: reply[1]
};
}
}
transformReply: ZPOPMAX.transformReply
} as const satisfies Command;

View File

@@ -14,11 +14,14 @@ describe('ZPOPMIN COUNT', () => {
const members = [{
value: '1',
score: 1
}, {
value: '2',
score: 2
}];
const [ , reply] = await Promise.all([
client.zAdd('key', members),
client.zPopMinCount('key', 1)
client.zPopMinCount('key', members.length)
]);
assert.deepEqual(reply, members);

View File

@@ -26,6 +26,9 @@ import BLMPOP from './BLMPOP';
import BLPOP from './BLPOP';
import BRPOP from './BRPOP';
import BRPOPLPUSH from './BRPOPLPUSH';
import BZMPOP from './BZMPOP';
import BZPOPMAX from './BZPOPMAX';
import BZPOPMIN from './BZPOPMIN';
import CLIENT_CACHING from './CLIENT_CACHING';
import CLIENT_GETNAME from './CLIENT_GETNAME';
import CLIENT_GETREDIR from './CLIENT_GETREDIR';
@@ -345,6 +348,9 @@ type BLMPOP = typeof import('./BLMPOP').default;
type BLPOP = typeof import('./BLPOP').default;
type BRPOP = typeof import('./BRPOP').default;
type BRPOPLPUSH = typeof import('./BRPOPLPUSH').default;
type BZMPOP = typeof import('./BZMPOP').default;
type BZPOPMAX = typeof import('./BZPOPMAX').default;
type BZPOPMIN = typeof import('./BZPOPMIN').default;
type CLIENT_CACHING = typeof import('./CLIENT_CACHING').default;
type CLIENT_GETNAME = typeof import('./CLIENT_GETNAME').default;
type CLIENT_GETREDIR = typeof import('./CLIENT_GETREDIR').default;
@@ -692,6 +698,12 @@ type Commands = {
brPop: BRPOP;
BRPOPLPUSH: BRPOPLPUSH;
brPopLPush: BRPOPLPUSH;
BZMPOP: BZMPOP;
bzmPop: BZMPOP;
BZPOPMAX: BZPOPMAX;
bzPopMax: BZPOPMAX;
BZPOPMIN: BZPOPMIN;
bzPopMin: BZPOPMIN;
CLIENT_CACHING: CLIENT_CACHING;
clientCaching: CLIENT_CACHING;
CLIENT_GETNAME: CLIENT_GETNAME;
@@ -1331,6 +1343,12 @@ export default {
brPop: BRPOP,
BRPOPLPUSH,
brPopLPush: BRPOPLPUSH,
BZMPOP,
bzmPop: BZMPOP,
BZPOPMAX,
bzPopMax: BZPOPMAX,
BZPOPMIN,
bzPopMin: BZPOPMIN,
CLIENT_CACHING,
clientCaching: CLIENT_CACHING,
CLIENT_GETNAME,