You've already forked node-redis
mirror of
https://github.com/redis/node-redis.git
synced 2025-08-10 11:43:01 +03:00
fix BITFIELD command
This commit is contained in:
@@ -3,88 +3,39 @@ import { TestRedisServers, itWithClient } from '../test-utils';
|
||||
import { transformArguments } from './BITFIELD';
|
||||
|
||||
describe('BITFIELD', () => {
|
||||
describe('transformArguments', () => {
|
||||
it('simple', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('key'),
|
||||
['BITFIELD', 'key']
|
||||
);
|
||||
});
|
||||
|
||||
it('with GET', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('key', {
|
||||
GET: {
|
||||
type: 'i8',
|
||||
offset: 0
|
||||
}
|
||||
}),
|
||||
['BITFIELD', 'key', 'GET', 'i8', '0']
|
||||
);
|
||||
});
|
||||
|
||||
it('with SET', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('key', {
|
||||
SET: {
|
||||
type: 'i8',
|
||||
offset: 0,
|
||||
value: 0
|
||||
}
|
||||
}),
|
||||
['BITFIELD', 'key', 'SET', 'i8', '0', '0']
|
||||
);
|
||||
});
|
||||
|
||||
it('with INCRBY', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('key', {
|
||||
INCRBY: {
|
||||
type: 'i8',
|
||||
offset: 0,
|
||||
increment: 0
|
||||
}
|
||||
}),
|
||||
['BITFIELD', 'key', 'INCRBY', 'i8', '0', '0']
|
||||
);
|
||||
});
|
||||
|
||||
it('with OVERFLOW', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('key', {
|
||||
OVERFLOW: 'WRAP'
|
||||
}),
|
||||
['BITFIELD', 'key', 'OVERFLOW', 'WRAP']
|
||||
);
|
||||
});
|
||||
|
||||
it('with GET, SET, INCRBY, OVERFLOW', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('key', {
|
||||
GET: {
|
||||
type: 'i8',
|
||||
offset: 0
|
||||
},
|
||||
SET: {
|
||||
type: 'i8',
|
||||
offset: 0,
|
||||
value: 0
|
||||
},
|
||||
INCRBY: {
|
||||
type: 'i8',
|
||||
offset: 0,
|
||||
increment: 0
|
||||
},
|
||||
OVERFLOW: 'WRAP'
|
||||
}),
|
||||
['BITFIELD', 'key', 'GET', 'i8', '0', 'SET', 'i8', '0', '0', 'INCRBY', 'i8', '0', '0', 'OVERFLOW', 'WRAP']
|
||||
);
|
||||
})
|
||||
it('transformArguments', () => {
|
||||
assert.deepEqual(
|
||||
transformArguments('key', [{
|
||||
operation: 'OVERFLOW',
|
||||
behavior: 'WRAP'
|
||||
}, {
|
||||
operation: 'GET',
|
||||
type: 'i8',
|
||||
offset: 0
|
||||
}, {
|
||||
operation: 'OVERFLOW',
|
||||
behavior: 'SAT'
|
||||
}, {
|
||||
operation: 'SET',
|
||||
type: 'i16',
|
||||
offset: 1,
|
||||
value: 0
|
||||
}, {
|
||||
operation: 'OVERFLOW',
|
||||
behavior: 'FAIL'
|
||||
}, {
|
||||
operation: 'INCRBY',
|
||||
type: 'i32',
|
||||
offset: 2,
|
||||
increment: 1
|
||||
}]),
|
||||
['BITFIELD', 'key', 'OVERFLOW', 'WRAP', 'GET', 'i8', '0', 'OVERFLOW', 'SAT', 'SET', 'i16', '1', '0', 'OVERFLOW', 'FAIL', 'INCRBY', 'i32', '2', '1']
|
||||
);
|
||||
});
|
||||
|
||||
itWithClient(TestRedisServers.OPEN, 'client.bitField', async client => {
|
||||
assert.deepEqual(
|
||||
await client.bitField('key'),
|
||||
await client.bitField('key', []),
|
||||
[]
|
||||
);
|
||||
});
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { transformReplyNumber } from './generic-transformers';
|
||||
import { transformReplyNumberNullArray } from './generic-transformers';
|
||||
|
||||
export const FIRST_KEY_INDEX = 1;
|
||||
|
||||
@@ -6,61 +6,79 @@ export const IS_READ_ONLY = true;
|
||||
|
||||
type BitFieldType = string; // TODO 'i[1-64]' | 'u[1-63]'
|
||||
|
||||
interface BitFieldOptions {
|
||||
GET?: {
|
||||
type: BitFieldType;
|
||||
offset: number | string;
|
||||
};
|
||||
SET?: {
|
||||
type: BitFieldType;
|
||||
offset: number | string;
|
||||
value: number;
|
||||
};
|
||||
INCRBY?: {
|
||||
type: BitFieldType;
|
||||
offset: number | string;
|
||||
increment: number;
|
||||
};
|
||||
OVERFLOW?: 'WRAP' | 'SAT' | 'FAIL';
|
||||
interface BitFieldOperation<S extends string> {
|
||||
operation: S;
|
||||
}
|
||||
|
||||
export function transformArguments(key: string, options?: BitFieldOptions): Array<string> {
|
||||
interface BitFieldGetOperation extends BitFieldOperation<'GET'> {
|
||||
type: BitFieldType;
|
||||
offset: number | string;
|
||||
}
|
||||
|
||||
interface BitFieldSetOperation extends BitFieldOperation<'SET'> {
|
||||
type: BitFieldType;
|
||||
offset: number | string;
|
||||
value: number;
|
||||
}
|
||||
|
||||
interface BitFieldIncrByOperation extends BitFieldOperation<'INCRBY'> {
|
||||
type: BitFieldType;
|
||||
offset: number | string;
|
||||
increment: number;
|
||||
}
|
||||
|
||||
interface BitFieldOverflowOperation extends BitFieldOperation<'OVERFLOW'> {
|
||||
behavior: string;
|
||||
}
|
||||
|
||||
type BitFieldOperations = Array<
|
||||
BitFieldGetOperation |
|
||||
BitFieldSetOperation |
|
||||
BitFieldIncrByOperation |
|
||||
BitFieldOverflowOperation
|
||||
>;
|
||||
|
||||
export function transformArguments(key: string, operations: BitFieldOperations): Array<string> {
|
||||
const args = ['BITFIELD', key];
|
||||
|
||||
if (options?.GET) {
|
||||
args.push(
|
||||
'GET',
|
||||
options.GET.type,
|
||||
options.GET.offset.toString()
|
||||
);
|
||||
}
|
||||
for (const options of operations) {
|
||||
switch (options.operation) {
|
||||
case 'GET':
|
||||
args.push(
|
||||
'GET',
|
||||
options.type,
|
||||
options.offset.toString()
|
||||
);
|
||||
break;
|
||||
|
||||
if (options?.SET) {
|
||||
args.push(
|
||||
'SET',
|
||||
options.SET.type,
|
||||
options.SET.offset.toString(),
|
||||
options.SET.value.toString()
|
||||
);
|
||||
}
|
||||
case 'SET':
|
||||
args.push(
|
||||
'SET',
|
||||
options.type,
|
||||
options.offset.toString(),
|
||||
options.value.toString()
|
||||
);
|
||||
break;
|
||||
|
||||
if (options?.INCRBY) {
|
||||
args.push(
|
||||
'INCRBY',
|
||||
options.INCRBY.type,
|
||||
options.INCRBY.offset.toString(),
|
||||
options.INCRBY.increment.toString()
|
||||
);
|
||||
}
|
||||
case 'INCRBY':
|
||||
args.push(
|
||||
'INCRBY',
|
||||
options.type,
|
||||
options.offset.toString(),
|
||||
options.increment.toString()
|
||||
)
|
||||
break;
|
||||
|
||||
if (options?.OVERFLOW) {
|
||||
args.push(
|
||||
'OVERFLOW',
|
||||
options.OVERFLOW
|
||||
);
|
||||
case 'OVERFLOW':
|
||||
args.push(
|
||||
'OVERFLOW',
|
||||
options.behavior
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
export const transformReply = transformReplyNumber;
|
||||
export const transformReply = transformReplyNumberNullArray;
|
||||
|
@@ -10,6 +10,10 @@ export function transformReplyNumberArray(reply: Array<number>): Array<number> {
|
||||
return reply;
|
||||
}
|
||||
|
||||
export function transformReplyNumberNullArray(reply: Array<number | null>): Array<number | null> {
|
||||
return reply;
|
||||
}
|
||||
|
||||
export function transformReplyString(reply: string): string {
|
||||
return reply;
|
||||
}
|
||||
|
Reference in New Issue
Block a user