diff --git a/packages/client/lib/commands/BGSAVE.spec.ts b/packages/client/lib/commands/BGSAVE.spec.ts index b8e82e2127..51817cbc0f 100644 --- a/packages/client/lib/commands/BGSAVE.spec.ts +++ b/packages/client/lib/commands/BGSAVE.spec.ts @@ -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); diff --git a/packages/client/lib/commands/BLMOVE.spec.ts b/packages/client/lib/commands/BLMOVE.spec.ts index 3b86c1ec91..3afda7f8a0 100644 --- a/packages/client/lib/commands/BLMOVE.spec.ts +++ b/packages/client/lib/commands/BLMOVE.spec.ts @@ -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 + }); }); diff --git a/packages/client/lib/commands/BLMPOP.spec.ts b/packages/client/lib/commands/BLMPOP.spec.ts index 15853a771b..6e87446ca8 100644 --- a/packages/client/lib/commands/BLMPOP.spec.ts +++ b/packages/client/lib/commands/BLMPOP.spec.ts @@ -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 + }); }); diff --git a/packages/client/lib/commands/BLMPOP.ts b/packages/client/lib/commands/BLMPOP.ts index 971b87edef..3122e90860 100644 --- a/packages/client/lib/commands/BLMPOP.ts +++ b/packages/client/lib/commands/BLMPOP.ts @@ -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 diff --git a/packages/client/lib/commands/BLPOP.spec.ts b/packages/client/lib/commands/BLPOP.spec.ts index 84920c851e..35b9d95396 100644 --- a/packages/client/lib/commands/BLPOP.spec.ts +++ b/packages/client/lib/commands/BLPOP.spec.ts @@ -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 + }); }); diff --git a/packages/client/lib/commands/BLPOP.ts b/packages/client/lib/commands/BLPOP.ts index e96617e21d..c40a18b3c8 100644 --- a/packages/client/lib/commands/BLPOP.ts +++ b/packages/client/lib/commands/BLPOP.ts @@ -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; }, diff --git a/packages/client/lib/commands/BRPOP.spec.ts b/packages/client/lib/commands/BRPOP.spec.ts index fc203e1abd..f484036aca 100644 --- a/packages/client/lib/commands/BRPOP.spec.ts +++ b/packages/client/lib/commands/BRPOP.spec.ts @@ -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 + }); }); diff --git a/packages/client/lib/commands/BRPOPLPUSH.spec.ts b/packages/client/lib/commands/BRPOPLPUSH.spec.ts index 214af4553a..1c1484868b 100644 --- a/packages/client/lib/commands/BRPOPLPUSH.spec.ts +++ b/packages/client/lib/commands/BRPOPLPUSH.spec.ts @@ -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 + }); }); diff --git a/packages/client/lib/commands/BZMPOP.spec.ts b/packages/client/lib/commands/BZMPOP.spec.ts index 0e381c114f..60bc3fe471 100644 --- a/packages/client/lib/commands/BZMPOP.spec.ts +++ b/packages/client/lib/commands/BZMPOP.spec.ts @@ -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 + }); }); diff --git a/packages/client/lib/commands/BZMPOP.ts b/packages/client/lib/commands/BZMPOP.ts index b043d5fcf6..030aa20c66 100644 --- a/packages/client/lib/commands/BZMPOP.ts +++ b/packages/client/lib/commands/BZMPOP.ts @@ -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, -// 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; diff --git a/packages/client/lib/commands/BZPOPMAX.spec.ts b/packages/client/lib/commands/BZPOPMAX.spec.ts index d5c1743712..64fb6b85b7 100644 --- a/packages/client/lib/commands/BZPOPMAX.spec.ts +++ b/packages/client/lib/commands/BZPOPMAX.spec.ts @@ -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 + }); }); diff --git a/packages/client/lib/commands/BZPOPMAX.ts b/packages/client/lib/commands/BZPOPMAX.ts index 250bc982b4..64059f1f78 100644 --- a/packages/client/lib/commands/BZPOPMAX.ts +++ b/packages/client/lib/commands/BZPOPMAX.ts @@ -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, -// 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]) -// }; -// } diff --git a/packages/client/lib/commands/BZPOPMIN.spec.ts b/packages/client/lib/commands/BZPOPMIN.spec.ts index 0573a4ac89..399c8f30b9 100644 --- a/packages/client/lib/commands/BZPOPMIN.spec.ts +++ b/packages/client/lib/commands/BZPOPMIN.spec.ts @@ -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 + }); }); diff --git a/packages/client/lib/commands/BZPOPMIN.ts b/packages/client/lib/commands/BZPOPMIN.ts index 967633697a..f27e623528 100644 --- a/packages/client/lib/commands/BZPOPMIN.ts +++ b/packages/client/lib/commands/BZPOPMIN.ts @@ -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, -// timeout: number -// ): RedisCommandArguments { -// const args = pushVariadicArguments(['BZPOPMIN'], key); - -// args.push(timeout.toString()); - -// return args; -// } - -// export { transformReply } from './BZPOPMAX'; diff --git a/packages/client/lib/commands/HGETALL.spec.ts b/packages/client/lib/commands/HGETALL.spec.ts index 9a9a30feaf..28e1dacf83 100644 --- a/packages/client/lib/commands/HGETALL.spec.ts +++ b/packages/client/lib/commands/HGETALL.spec.ts @@ -23,8 +23,7 @@ describe('HGETALL', () => { Object.create(null, { field: { value: 'value', - enumerable: true, - writable: true + enumerable: true } }) ); diff --git a/packages/client/lib/commands/LMPOP.spec.ts b/packages/client/lib/commands/LMPOP.spec.ts index ae9c2b6926..78a0cdd9cc 100644 --- a/packages/client/lib/commands/LMPOP.spec.ts +++ b/packages/client/lib/commands/LMPOP.spec.ts @@ -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 + }); }); diff --git a/packages/client/lib/commands/LMPOP.ts b/packages/client/lib/commands/LMPOP.ts index b828f47f06..49f7272ec4 100644 --- a/packages/client/lib/commands/LMPOP.ts +++ b/packages/client/lib/commands/LMPOP.ts @@ -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, diff --git a/packages/client/lib/commands/XAUTOCLAIM.spec.ts b/packages/client/lib/commands/XAUTOCLAIM.spec.ts index 80382db8d2..bb4b1d6594 100644 --- a/packages/client/lib/commands/XAUTOCLAIM.spec.ts +++ b/packages/client/lib/commands/XAUTOCLAIM.spec.ts @@ -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 + }); +}); diff --git a/packages/client/lib/commands/XAUTOCLAIM_JUSTID.spec.ts b/packages/client/lib/commands/XAUTOCLAIM_JUSTID.spec.ts index ed7b80cabf..872d19100f 100644 --- a/packages/client/lib/commands/XAUTOCLAIM_JUSTID.spec.ts +++ b/packages/client/lib/commands/XAUTOCLAIM_JUSTID.spec.ts @@ -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); +}); diff --git a/packages/client/lib/commands/XGROUP_CREATE.spec.ts b/packages/client/lib/commands/XGROUP_CREATE.spec.ts index 3428f05251..8dee9b5fda 100644 --- a/packages/client/lib/commands/XGROUP_CREATE.spec.ts +++ b/packages/client/lib/commands/XGROUP_CREATE.spec.ts @@ -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 }); }); diff --git a/packages/client/lib/commands/XGROUP_DELCONSUMER.ts b/packages/client/lib/commands/XGROUP_DELCONSUMER.ts index bb10174e1c..53007270e0 100644 --- a/packages/client/lib/commands/XGROUP_DELCONSUMER.ts +++ b/packages/client/lib/commands/XGROUP_DELCONSUMER.ts @@ -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 { diff --git a/packages/client/lib/commands/XINFO_STREAM.spec.ts b/packages/client/lib/commands/XINFO_STREAM.spec.ts index 0c13f27c41..99370fb97f 100644 --- a/packages/client/lib/commands/XINFO_STREAM.spec.ts +++ b/packages/client/lib/commands/XINFO_STREAM.spec.ts @@ -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, diff --git a/packages/client/lib/commands/XINFO_STREAM.ts b/packages/client/lib/commands/XINFO_STREAM.ts index 2dde1ea1a4..00b6b0aa4e 100644 --- a/packages/client/lib/commands/XINFO_STREAM.ts +++ b/packages/client/lib/commands/XINFO_STREAM.ts @@ -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): XInfoStreamReply { -// const parsedReply: Partial = {}; - -// 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'; diff --git a/packages/client/lib/commands/XPENDING_RANGE.spec.ts b/packages/client/lib/commands/XPENDING_RANGE.spec.ts index 2f2d75b40f..ef25b9840c 100644 --- a/packages/client/lib/commands/XPENDING_RANGE.spec.ts +++ b/packages/client/lib/commands/XPENDING_RANGE.spec.ts @@ -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 diff --git a/packages/client/lib/commands/XPENDING_RANGE.ts b/packages/client/lib/commands/XPENDING_RANGE.ts index 9ca37dae9c..4fdf9b2b11 100644 --- a/packages/client/lib/commands/XPENDING_RANGE.ts +++ b/packages/client/lib/commands/XPENDING_RANGE.ts @@ -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 { diff --git a/packages/client/lib/commands/XRANGE.spec.ts b/packages/client/lib/commands/XRANGE.spec.ts index dfcc059064..5557b04c8f 100644 --- a/packages/client/lib/commands/XRANGE.spec.ts +++ b/packages/client/lib/commands/XRANGE.spec.ts @@ -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, diff --git a/packages/client/lib/commands/XREADGROUP.ts b/packages/client/lib/commands/XREADGROUP.ts index f1a2782208..0396f3a93e 100644 --- a/packages/client/lib/commands/XREADGROUP.ts +++ b/packages/client/lib/commands/XREADGROUP.ts @@ -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()); diff --git a/packages/client/lib/commands/XREVRANGE.spec.ts b/packages/client/lib/commands/XREVRANGE.spec.ts index f935f3bcdd..448018a2b9 100644 --- a/packages/client/lib/commands/XREVRANGE.spec.ts +++ b/packages/client/lib/commands/XREVRANGE.spec.ts @@ -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, diff --git a/packages/client/lib/commands/ZADD.spec.ts b/packages/client/lib/commands/ZADD.spec.ts index 9f684237e1..4ca25ee0ee 100644 --- a/packages/client/lib/commands/ZADD.spec.ts +++ b/packages/client/lib/commands/ZADD.spec.ts @@ -133,7 +133,7 @@ describe('ZADD', () => { testUtils.testAll('zAdd', async client => { assert.equal( await client.zAdd('key', { - value: '1', + value: 'a', score: 1 }), 1 diff --git a/packages/client/lib/commands/ZADD_INCR.spec.ts b/packages/client/lib/commands/ZADD_INCR.spec.ts index b2fab832ee..f014160d2e 100644 --- a/packages/client/lib/commands/ZADD_INCR.spec.ts +++ b/packages/client/lib/commands/ZADD_INCR.spec.ts @@ -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 diff --git a/packages/client/lib/commands/ZMPOP.ts b/packages/client/lib/commands/ZMPOP.ts index 6484277ae8..6960006173 100644 --- a/packages/client/lib/commands/ZMPOP.ts +++ b/packages/client/lib/commands/ZMPOP.ts @@ -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, + 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) => { diff --git a/packages/client/lib/commands/ZPOPMAX.ts b/packages/client/lib/commands/ZPOPMAX.ts index 4e1d476c41..fb4d2d958b 100644 --- a/packages/client/lib/commands/ZPOPMAX.ts +++ b/packages/client/lib/commands/ZPOPMAX.ts @@ -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; diff --git a/packages/client/lib/commands/ZPOPMAX_COUNT.spec.ts b/packages/client/lib/commands/ZPOPMAX_COUNT.spec.ts index 222dcf43f8..0806b5977d 100644 --- a/packages/client/lib/commands/ZPOPMAX_COUNT.spec.ts +++ b/packages/client/lib/commands/ZPOPMAX_COUNT.spec.ts @@ -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 diff --git a/packages/client/lib/commands/ZPOPMIN.ts b/packages/client/lib/commands/ZPOPMIN.ts index 42f428ada3..b9da85cc97 100644 --- a/packages/client/lib/commands/ZPOPMIN.ts +++ b/packages/client/lib/commands/ZPOPMIN.ts @@ -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; diff --git a/packages/client/lib/commands/ZPOPMIN_COUNT.spec.ts b/packages/client/lib/commands/ZPOPMIN_COUNT.spec.ts index fc19ba2b9c..2b2f12b348 100644 --- a/packages/client/lib/commands/ZPOPMIN_COUNT.spec.ts +++ b/packages/client/lib/commands/ZPOPMIN_COUNT.spec.ts @@ -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); diff --git a/packages/client/lib/commands/index.ts b/packages/client/lib/commands/index.ts index cca2f9f128..cc98529c59 100644 --- a/packages/client/lib/commands/index.ts +++ b/packages/client/lib/commands/index.ts @@ -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,