1
0
mirror of https://github.com/redis/node-redis.git synced 2025-08-07 13:22:56 +03:00
This commit is contained in:
Leibale
2023-05-10 16:07:29 +03:00
parent 13f1fa9e58
commit 442a554fce
18 changed files with 276 additions and 225 deletions

View File

@@ -1,19 +1,19 @@
import { strict as assert } from 'assert'; import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils'; import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './ECHO'; import ECHO from './ECHO';
describe('ECHO', () => { describe('ECHO', () => {
it('transformArguments', () => { it('transformArguments', () => {
assert.deepEqual( assert.deepEqual(
transformArguments('message'), ECHO.transformArguments('message'),
['ECHO', 'message'] ['ECHO', 'message']
); );
}); });
testUtils.testWithClient('client.echo', async client => { testUtils.testWithClient('client.echo', async client => {
assert.equal( assert.equal(
await client.echo('message'), await client.echo('message'),
'message' 'message'
); );
}, GLOBAL.SERVERS.OPEN); }, GLOBAL.SERVERS.OPEN);
}); });

View File

@@ -1,29 +1,25 @@
import { strict as assert } from 'assert'; import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils'; import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './EVAL'; import EVAL from './EVAL';
describe('EVAL', () => { describe('EVAL', () => {
it('transformArguments', () => { it('transformArguments', () => {
assert.deepEqual( assert.deepEqual(
transformArguments('return KEYS[1] + ARGV[1]', { EVAL.transformArguments('return KEYS[1] + ARGV[1]', {
keys: ['key'], keys: ['key'],
arguments: ['argument'] arguments: ['argument']
}), }),
['EVAL', 'return KEYS[1] + ARGV[1]', '1', 'key', 'argument'] ['EVAL', 'return KEYS[1] + ARGV[1]', '1', 'key', 'argument']
); );
}); });
testUtils.testWithClient('client.eval', async client => { testUtils.testAll('eval', async client => {
assert.equal( assert.equal(
await client.eval('return 1'), await client.eval('return 1'),
1 1
); );
}, GLOBAL.SERVERS.OPEN); }, {
client: GLOBAL.SERVERS.OPEN,
testUtils.testWithCluster('cluster.eval', async cluster => { cluster: GLOBAL.CLUSTERS.OPEN
assert.equal( });
await cluster.eval('return 1'),
1
);
}, GLOBAL.CLUSTERS.OPEN);
}); });

View File

@@ -1,7 +1,33 @@
import { evalFirstKeyIndex, EvalOptions, pushEvalArguments } from './generic-transformers'; import { RedisArgument, ReplyUnion, Command } from '../RESP/types';
export const FIRST_KEY_INDEX = evalFirstKeyIndex; export interface EvalOptions {
keys?: Array<RedisArgument>;
export function transformArguments(script: string, options?: EvalOptions): Array<string> { arguments?: Array<RedisArgument>;
return pushEvalArguments(['EVAL', script], options);
} }
export function transformEvalArguments(
command: RedisArgument,
script: RedisArgument,
options?: EvalOptions
) {
const args = [command, script];
if (options?.keys) {
args.push(options.keys.length.toString(), ...options.keys);
} else {
args.push('0');
}
if (options?.arguments) {
args.push(...options.arguments);
}
return args;
}
export default {
FIRST_KEY_INDEX: (_, options?: EvalOptions) => options?.keys?.[0],
IS_READ_ONLY: false,
transformArguments: transformEvalArguments.bind(undefined, 'EVAL'),
transformReply: undefined as unknown as () => ReplyUnion
} as const satisfies Command;

View File

@@ -1,14 +1,14 @@
import { strict as assert } from 'assert'; import { strict as assert } from 'assert';
import { transformArguments } from './EVALSHA'; import EVALSHA from './EVALSHA';
describe('EVALSHA', () => { describe('EVALSHA', () => {
it('transformArguments', () => { it('transformArguments', () => {
assert.deepEqual( assert.deepEqual(
transformArguments('sha1', { EVALSHA.transformArguments('sha1', {
keys: ['key'], keys: ['key'],
arguments: ['argument'] arguments: ['argument']
}), }),
['EVALSHA', 'sha1', '1', 'key', 'argument'] ['EVALSHA', 'sha1', '1', 'key', 'argument']
); );
}); });
}); });

View File

@@ -1,7 +1,9 @@
import { evalFirstKeyIndex, EvalOptions, pushEvalArguments } from './generic-transformers'; import { Command } from '../RESP/types';
import EVAL, { transformEvalArguments } from './EVAL';
export const FIRST_KEY_INDEX = evalFirstKeyIndex; export default {
FIRST_KEY_INDEX: EVAL.FIRST_KEY_INDEX,
export function transformArguments(sha1: string, options?: EvalOptions): Array<string> { IS_READ_ONLY: false,
return pushEvalArguments(['EVALSHA', sha1], options); transformArguments: transformEvalArguments.bind(undefined, 'EVALSHA'),
} transformReply: EVAL.transformReply
} as const satisfies Command;

View File

@@ -1,17 +1,17 @@
import { strict as assert } from 'assert'; import { strict as assert } from 'assert';
import testUtils from '../test-utils'; import testUtils from '../test-utils';
import { transformArguments } from './EVALSHA_RO'; import EVALSHA_RO from './EVALSHA_RO';
describe('EVALSHA_RO', () => { describe('EVALSHA_RO', () => {
testUtils.isVersionGreaterThanHook([7]); testUtils.isVersionGreaterThanHook([7]);
it('transformArguments', () => { it('transformArguments', () => {
assert.deepEqual( assert.deepEqual(
transformArguments('sha1', { EVALSHA_RO.transformArguments('sha1', {
keys: ['key'], keys: ['key'],
arguments: ['argument'] arguments: ['argument']
}), }),
['EVALSHA_RO', 'sha1', '1', 'key', 'argument'] ['EVALSHA_RO', 'sha1', '1', 'key', 'argument']
); );
}); });
}); });

View File

@@ -1,9 +1,9 @@
import { evalFirstKeyIndex, EvalOptions, pushEvalArguments } from './generic-transformers'; import { Command } from '../RESP/types';
import EVAL, { transformEvalArguments } from './EVAL';
export const FIRST_KEY_INDEX = evalFirstKeyIndex; export default {
FIRST_KEY_INDEX: EVAL.FIRST_KEY_INDEX,
export const IS_READ_ONLY = true; IS_READ_ONLY: true,
transformArguments: transformEvalArguments.bind(undefined, 'EVALSHA_RO'),
export function transformArguments(sha1: string, options?: EvalOptions): Array<string> { transformReply: EVAL.transformReply
return pushEvalArguments(['EVALSHA_RO', sha1], options); } as const satisfies Command;
}

View File

@@ -1,31 +1,27 @@
import { strict as assert } from 'assert'; import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils'; import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './EVAL_RO'; import EVAL_RO from './EVAL_RO';
describe('EVAL_RO', () => { describe('EVAL_RO', () => {
testUtils.isVersionGreaterThanHook([7]); testUtils.isVersionGreaterThanHook([7]);
it('transformArguments', () => { it('transformArguments', () => {
assert.deepEqual( assert.deepEqual(
transformArguments('return KEYS[1] + ARGV[1]', { EVAL_RO.transformArguments('return KEYS[1] + ARGV[1]', {
keys: ['key'], keys: ['key'],
arguments: ['argument'] arguments: ['argument']
}), }),
['EVAL_RO', 'return KEYS[1] + ARGV[1]', '1', 'key', 'argument'] ['EVAL_RO', 'return KEYS[1] + ARGV[1]', '1', 'key', 'argument']
); );
}); });
testUtils.testWithClient('client.evalRo', async client => { testUtils.testAll('evalRo', async cluster => {
assert.equal( assert.equal(
await client.evalRo('return 1'), await cluster.evalRo('return 1'),
1 1
); );
}, GLOBAL.SERVERS.OPEN); }, {
client: GLOBAL.SERVERS.OPEN,
testUtils.testWithCluster('cluster.evalRo', async cluster => { cluster: GLOBAL.CLUSTERS.OPEN
assert.equal( });
await cluster.evalRo('return 1'),
1
);
}, GLOBAL.CLUSTERS.OPEN);
}); });

View File

@@ -1,9 +1,9 @@
import { evalFirstKeyIndex, EvalOptions, pushEvalArguments } from './generic-transformers'; import { Command } from '../RESP/types';
import EVAL, { transformEvalArguments } from './EVAL';
export const FIRST_KEY_INDEX = evalFirstKeyIndex; export default {
FIRST_KEY_INDEX: EVAL.FIRST_KEY_INDEX,
export const IS_READ_ONLY = true; IS_READ_ONLY: true,
transformArguments: transformEvalArguments.bind(undefined, 'EVAL_RO'),
export function transformArguments(script: string, options?: EvalOptions): Array<string> { transformReply: EVAL.transformReply
return pushEvalArguments(['EVAL_RO', script], options); } as const satisfies Command;
}

View File

@@ -5,3 +5,15 @@ export const FIRST_KEY_INDEX = evalFirstKeyIndex;
export function transformArguments(fn: string, options?: EvalOptions): Array<string> { export function transformArguments(fn: string, options?: EvalOptions): Array<string> {
return pushEvalArguments(['FCALL', fn], options); return pushEvalArguments(['FCALL', fn], options);
} }
import { SimpleStringReply, Command } from '../RESP/types';
export default {
FIRST_KEY_INDEX: undefined,
IS_READ_ONLY: false,
transformArguments() {
return ['FCALL'];
},
transformReply: undefined as unknown as () => SimpleStringReply
} as const satisfies Command;

View File

@@ -1,76 +1,71 @@
import { strict as assert } from 'assert'; import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils'; import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './HELLO'; import HELLO from './HELLO';
describe('HELLO', () => { describe('HELLO', () => {
testUtils.isVersionGreaterThanHook([6]); testUtils.isVersionGreaterThanHook([6]);
describe('transformArguments', () => { describe('transformArguments', () => {
it('simple', () => { it('simple', () => {
assert.deepEqual( assert.deepEqual(
transformArguments(), HELLO.transformArguments(),
['HELLO'] ['HELLO']
); );
});
it('with protover', () => {
assert.deepEqual(
transformArguments({
protover: 3
}),
['HELLO', '3']
);
});
it('with protover, auth', () => {
assert.deepEqual(
transformArguments({
protover: 3,
auth: {
username: 'username',
password: 'password'
}
}),
['HELLO', '3', 'AUTH', 'username', 'password']
);
});
it('with protover, clientName', () => {
assert.deepEqual(
transformArguments({
protover: 3,
clientName: 'clientName'
}),
['HELLO', '3', 'SETNAME', 'clientName']
);
});
it('with protover, auth, clientName', () => {
assert.deepEqual(
transformArguments({
protover: 3,
auth: {
username: 'username',
password: 'password'
},
clientName: 'clientName'
}),
['HELLO', '3', 'AUTH', 'username', 'password', 'SETNAME', 'clientName']
);
});
}); });
testUtils.testWithClient('client.hello', async client => { it('with protover', () => {
const reply = await client.hello(); assert.deepEqual(
assert.equal(reply.server, 'redis'); HELLO.transformArguments(3),
assert.equal(typeof reply.version, 'string'); ['HELLO', '3']
assert.equal(reply.proto, 2); );
assert.equal(typeof reply.id, 'number');
assert.equal(reply.mode, 'standalone');
assert.equal(reply.role, 'master');
assert.deepEqual(reply.modules, []);
}, {
...GLOBAL.SERVERS.OPEN,
minimumDockerVersion: [6, 2]
}); });
it('with protover, AUTH', () => {
assert.deepEqual(
HELLO.transformArguments(3, {
AUTH: {
username: 'username',
password: 'password'
}
}),
['HELLO', '3', 'AUTH', 'username', 'password']
);
});
it('with protover, SETNAME', () => {
assert.deepEqual(
HELLO.transformArguments(3, {
SETNAME: 'name'
}),
['HELLO', '3', 'SETNAME', 'name']
);
});
it('with protover, AUTH, SETNAME', () => {
assert.deepEqual(
HELLO.transformArguments(3, {
AUTH: {
username: 'username',
password: 'password'
},
SETNAME: 'name'
}),
['HELLO', '3', 'AUTH', 'username', 'password', 'SETNAME', 'name']
);
});
});
testUtils.testWithClient('client.hello', async client => {
const reply = await client.hello();
assert.equal(reply.server, 'redis');
assert.equal(typeof reply.version, 'string');
assert.equal(reply.proto, 2);
assert.equal(typeof reply.id, 'number');
assert.equal(reply.mode, 'standalone');
assert.equal(reply.role, 'master');
assert.deepEqual(reply.modules, []);
}, {
...GLOBAL.SERVERS.OPEN,
minimumDockerVersion: [6, 2]
});
}); });

View File

@@ -1,6 +1,7 @@
import { RedisArgument, ArrayReply, BlobStringReply, Command, NumberReply, Resp2Reply, RespVersions, TuplesToMapReply } from '../RESP/types'; import { RedisArgument, ArrayReply, BlobStringReply, Command, NumberReply, Resp2Reply, RespVersions, TuplesToMapReply } from '../RESP/types';
export interface HelloOptions { export interface HelloOptions {
protover?: RespVersions;
AUTH?: { AUTH?: {
username: RedisArgument; username: RedisArgument;
password: RedisArgument; password: RedisArgument;
@@ -19,22 +20,26 @@ export type HelloReply = TuplesToMapReply<[
]>; ]>;
export default { export default {
transformArguments(protoover: RespVersions, options?: HelloOptions) { transformArguments(protover?: RespVersions, options?: HelloOptions) {
const args: Array<RedisArgument> = ['HELLO', protoover.toString()]; const args: Array<RedisArgument> = ['HELLO'];
if (options?.AUTH) { if (protover) {
args.push( args.push(protover.toString());
'AUTH',
options.AUTH.username,
options.AUTH.password
);
}
if (options?.SETNAME) { if (options?.AUTH) {
args.push( args.push(
'SETNAME', 'AUTH',
options.SETNAME options.AUTH.username,
); options.AUTH.password
);
}
if (options?.SETNAME) {
args.push(
'SETNAME',
options.SETNAME
);
}
} }
return args; return args;

View File

@@ -1,16 +1,16 @@
import { strict as assert } from 'assert'; import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils'; import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './LASTSAVE'; import LASTSAVE from './LASTSAVE';
describe('LASTSAVE', () => { describe('LASTSAVE', () => {
it('transformArguments', () => { it('transformArguments', () => {
assert.deepEqual( assert.deepEqual(
transformArguments(), LASTSAVE.transformArguments(),
['LASTSAVE'] ['LASTSAVE']
); );
}); });
testUtils.testWithClient('client.lastSave', async client => { testUtils.testWithClient('client.lastSave', async client => {
assert.ok((await client.lastSave()) instanceof Date); assert.ok(typeof await client.lastSave() === 'number');
}, GLOBAL.SERVERS.OPEN); }, GLOBAL.SERVERS.OPEN);
}); });

View File

@@ -1,9 +1,10 @@
export const IS_READ_ONLY = true; import { NumberReply, Command } from '../RESP/types';
export function transformArguments(): Array<string> { export default {
FIRST_KEY_INDEX: undefined,
IS_READ_ONLY: true,
transformArguments() {
return ['LASTSAVE']; return ['LASTSAVE'];
} },
transformReply: undefined as unknown as () => NumberReply
export function transformReply(reply: number): Date { } as const satisfies Command;
return new Date(reply);
}

View File

@@ -14,7 +14,7 @@ describe('LCS_LEN', () => {
testUtils.testAll('lcsLen', async client => { testUtils.testAll('lcsLen', async client => {
assert.equal( assert.equal(
await client.lcsLen('1', '2'), await client.lcsLen('{tag}1', '{tag}2'),
0 0
); );
}, { }, {

View File

@@ -10,13 +10,10 @@ describe('MOVE', () => {
); );
}); });
testUtils.testAll('move', async client => { testUtils.testWithClient('client.move', async client => {
assert.equal( assert.equal(
await client.move('key', 1), await client.move('key', 1),
0 0
); );
}, { }, GLOBAL.SERVERS.OPEN);
client: GLOBAL.SERVERS.OPEN,
cluster: GLOBAL.CLUSTERS.OPEN
});
}); });

View File

@@ -1,19 +1,19 @@
import { strict as assert } from 'assert'; import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils'; import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './PUBLISH'; import PUBLISH from './PUBLISH';
describe('PUBLISH', () => { describe('PUBLISH', () => {
it('transformArguments', () => { it('transformArguments', () => {
assert.deepEqual( assert.deepEqual(
transformArguments('channel', 'message'), PUBLISH.transformArguments('channel', 'message'),
['PUBLISH', 'channel', 'message'] ['PUBLISH', 'channel', 'message']
); );
}); });
testUtils.testWithClient('client.publish', async client => { testUtils.testWithClient('client.publish', async client => {
assert.equal( assert.equal(
await client.publish('channel', 'message'), await client.publish('channel', 'message'),
0 0
); );
}, GLOBAL.SERVERS.OPEN); }, GLOBAL.SERVERS.OPEN);
}); });

View File

@@ -45,6 +45,11 @@ import DECR from './DECR';
import DECRBY from './DECRBY'; import DECRBY from './DECRBY';
import DEL from './DEL'; import DEL from './DEL';
import DUMP from './DUMP'; import DUMP from './DUMP';
import ECHO from './ECHO';
import EVAL_RO from './EVAL_RO';
import EVAL from './EVAL';
import EVALSHA_RO from './EVALSHA_RO';
import EVALSHA from './EVALSHA';
import GEOADD from './GEOADD'; import GEOADD from './GEOADD';
import GEODIST from './GEODIST'; import GEODIST from './GEODIST';
import GEOHASH from './GEOHASH'; import GEOHASH from './GEOHASH';
@@ -75,6 +80,7 @@ import EXPIRETIME from './EXPIRETIME';
import FLUSHALL from './FLUSHALL'; import FLUSHALL from './FLUSHALL';
import FLUSHDB from './FLUSHDB'; import FLUSHDB from './FLUSHDB';
import HDEL from './HDEL'; import HDEL from './HDEL';
import HELLO from './HELLO';
import HEXISTS from './HEXISTS'; import HEXISTS from './HEXISTS';
import HGET from './HGET'; import HGET from './HGET';
import HGETALL from './HGETALL'; import HGETALL from './HGETALL';
@@ -96,6 +102,7 @@ import INCRBY from './INCRBY';
import INCRBYFLOAT from './INCRBYFLOAT'; import INCRBYFLOAT from './INCRBYFLOAT';
import INFO from './INFO'; import INFO from './INFO';
import KEYS from './KEYS'; import KEYS from './KEYS';
import LASTSAVE from './LASTSAVE';
// import LCS_IDX_WITHMATCHLEN from './LCS_IDX_WITHMATCHLEN'; // import LCS_IDX_WITHMATCHLEN from './LCS_IDX_WITHMATCHLEN';
// import LCS_IDX from './LCS_IDX'; // import LCS_IDX from './LCS_IDX';
import LCS_LEN from './LCS_LEN'; import LCS_LEN from './LCS_LEN';
@@ -320,6 +327,16 @@ export default {
del: DEL, del: DEL,
DUMP, DUMP,
dump: DUMP, dump: DUMP,
ECHO,
echo: ECHO,
EVAL_RO,
evalRo: EVAL_RO,
EVAL,
eval: EVAL,
EVALSHA_RO,
evalShaRo: EVALSHA_RO,
EVALSHA,
evalSha: EVALSHA,
EXISTS, EXISTS,
exists: EXISTS, exists: EXISTS,
EXPIRE, EXPIRE,
@@ -380,6 +397,8 @@ export default {
getSet: GETSET, getSet: GETSET,
HDEL, HDEL,
hDel: HDEL, hDel: HDEL,
HELLO,
hello: HELLO,
HEXISTS, HEXISTS,
hExists: HEXISTS, hExists: HEXISTS,
HGET, HGET,
@@ -422,6 +441,8 @@ export default {
info: INFO, info: INFO,
KEYS, KEYS,
keys: KEYS, keys: KEYS,
LASTSAVE,
lastSave: LASTSAVE,
// LCS_IDX_WITHMATCHLEN, // LCS_IDX_WITHMATCHLEN,
// LCS_IDX, // LCS_IDX,
LCS_LEN, LCS_LEN,