1
0
mirror of https://github.com/redis/node-redis.git synced 2025-08-06 02:15:48 +03:00

#2038 Resolve legacy mode hGetAll returning in the wrong format compared to v3 results (#2367)

* Ensure that transformReply is optionally passed through to commands in legacy mode within multi

* Execute transformReply on legacy #sendCommand

* Scope transform changes to hGetAll

* Extensible method of transforming legacy replies, expands RedisCommand interface

* check `TRANSFORM_LEGACY_REPLY` on client creation (rather then on command exec), add tests

Co-authored-by: Leibale Eidelman <me@leibale.com>
This commit is contained in:
Brandon
2023-01-18 10:54:29 -07:00
committed by GitHub
parent e895fa1d71
commit aa75ee49c6
5 changed files with 97 additions and 78 deletions

View File

@@ -8,6 +8,7 @@ import { defineScript } from '../lua-script';
import { spy } from 'sinon';
import { once } from 'events';
import { ClientKillFilters } from '../commands/CLIENT_KILL';
import { promisify } from 'util';
export const SQUARE_SCRIPT = defineScript({
SCRIPT: 'return ARGV[1] * ARGV[1];',
@@ -142,26 +143,9 @@ describe('Client', () => {
});
describe('legacyMode', () => {
function sendCommandAsync<
M extends RedisModules,
F extends RedisFunctions,
S extends RedisScripts
>(
client: RedisClientType<M, F, S>,
args: RedisCommandArguments
): Promise<RedisCommandRawReply> {
return new Promise((resolve, reject) => {
(client as any).sendCommand(args, (err: Error | undefined, reply: RedisCommandRawReply) => {
if (err) return reject(err);
resolve(reply);
});
});
}
testUtils.testWithClient('client.sendCommand should call the callback', async client => {
assert.equal(
await sendCommandAsync(client, ['PING']),
await promisify(client.sendCommand).call(client, 'PING'),
'PONG'
);
}, {
@@ -193,26 +177,9 @@ describe('Client', () => {
}
});
function setAsync<
M extends RedisModules,
F extends RedisFunctions,
S extends RedisScripts
>(
client: RedisClientType<M, F, S>,
...args: Array<any>
): Promise<RedisCommandRawReply> {
return new Promise((resolve, reject) => {
(client as any).set(...args, (err: Error | undefined, reply: RedisCommandRawReply) => {
if (err) return reject(err);
resolve(reply);
});
});
}
testUtils.testWithClient('client.{command} should accept vardict arguments', async client => {
assert.equal(
await setAsync(client, 'a', 'b'),
await promisify(client.set).call(client, 'a', 'b'),
'OK'
);
}, {
@@ -224,7 +191,7 @@ describe('Client', () => {
testUtils.testWithClient('client.{command} should accept arguments array', async client => {
assert.equal(
await setAsync(client, ['a', 'b']),
await promisify(client.set).call(client, ['a', 'b']),
'OK'
);
}, {
@@ -236,7 +203,7 @@ describe('Client', () => {
testUtils.testWithClient('client.{command} should accept mix of arrays and arguments', async client => {
assert.equal(
await setAsync(client, ['a'], 'b', ['EX', 1]),
await promisify(client.set).call(client, ['a'], 'b', ['EX', 1]),
'OK'
);
}, {
@@ -246,6 +213,26 @@ describe('Client', () => {
}
});
testUtils.testWithClient('client.hGetAll should return object', async client => {
await client.v4.hSet('key', 'field', 'value');
assert.deepEqual(
await promisify(client.hGetAll).call(client, 'key'),
Object.create(null, {
field: {
value: 'value',
configurable: true,
enumerable: true
}
})
);
}, {
...GLOBAL.SERVERS.OPEN,
clientOptions: {
legacyMode: true
}
});
function multiExecAsync<
M extends RedisModules,
F extends RedisFunctions,
@@ -330,6 +317,30 @@ describe('Client', () => {
}
});
testUtils.testWithClient('client.multi.hGetAll should return object', async client => {
assert.deepEqual(
await multiExecAsync(
client.multi()
.hSet('key', 'field', 'value')
.hGetAll('key')
),
[
1,
Object.create(null, {
field: {
value: 'value',
configurable: true,
enumerable: true
}
})
]
);
}, {
...GLOBAL.SERVERS.OPEN,
clientOptions: {
legacyMode: true
}
});
});
describe('events', () => {