Skip to content

Commit fca9a03

Browse files
committed
Add tests
1 parent 2e3a4f6 commit fca9a03

File tree

4 files changed

+136
-29
lines changed

4 files changed

+136
-29
lines changed

README.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,20 @@ This module exports all the commands that Redis supports.
77
## Install
88

99
```shell
10-
$ npm install ioredis-commands
10+
$ npm install redis-commands
1111
```
1212

1313
## Usage
1414

1515
```javascript
16-
var commands = require('ioredis-commands');
16+
var commands = require('redis-commands');
17+
```
1718

18-
Object.keys(commands).forEach(function (command) {
19+
commands.list.forEach(function (command) {
1920
console.log(command);
2021
});
2122
```
23+
24+
## Acknowledgment
25+
26+
Thank [@Yuan Chuan](https://github.com/yuanchuan) for the package name. The original redis-commands is renamed to [@yuanchuan/redis-commands](https://www.npmjs.com/package/@yuanchuan/redis-commands).

index.js

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,26 @@
1+
'use strict';
2+
13
var commands = require('./commands');
24

3-
exports.commands = Object.keys(commands);
5+
/**
6+
* Redis command list
7+
*
8+
* All commands are lowercased.
9+
*
10+
* @var {string[]}
11+
* @public
12+
*/
13+
exports.list = Object.keys(commands);
414

15+
/**
16+
* Check if the command has the flag
17+
*
18+
* Some of possible flags: readonly, noscript, loading
19+
* @param {string} commandName - the command name
20+
* @param {string} flag - the flag to check
21+
* @return {boolean} result
22+
* @public
23+
*/
524
exports.hasFlag = function (commandName, flag) {
625
var command = commands[commandName];
726
if (!command) {
@@ -19,6 +38,22 @@ exports.hasFlag = function (commandName, flag) {
1938
return false;
2039
};
2140

41+
/**
42+
* Get indexes of keys in the command arguments
43+
*
44+
* @param {string} commandName - the command name
45+
* @param {string[]} args - the arguments of the command
46+
* @param {object} [options] - options
47+
* @param {boolean} [options.parseExternalKey] - parse external keys
48+
* @return {number[]} - the list of the index
49+
* @public
50+
*
51+
* @example
52+
* ```javascript
53+
* getKeyIndexes('set', ['key', 'value']) // [0]
54+
* getKeyIndexes('mget', ['key1', 'key2']) // [0, 1]
55+
* ```
56+
*/
2257
exports.getKeyIndexes = function (commandName, args, options) {
2358
var command = commands[commandName];
2459
if (!command) {
@@ -29,7 +64,7 @@ exports.getKeyIndexes = function (commandName, args, options) {
2964
throw new Error('Expect args to be an array');
3065
}
3166

32-
var parsePartialKey = options && options.parsePartialKey;
67+
var parseExternalKey = options && options.parseExternalKey;
3368

3469
var keys = [];
3570
var i, range, keyStart, keyStop;
@@ -51,16 +86,16 @@ exports.getKeyIndexes = function (commandName, args, options) {
5186
if (directive === 'GET') {
5287
i += 1;
5388
if (args[i] !== '#') {
54-
if (parsePartialKey && (range = getPartialKeyRange(args[i]))) {
55-
keys.push([i, range]);
89+
if (parseExternalKey) {
90+
keys.push([i, getExternalKeyNameLength(args[i])]);
5691
} else {
5792
keys.push(i);
5893
}
5994
}
6095
} else if (directive === 'BY') {
6196
i += 1;
62-
if (parsePartialKey && (range = getPartialKeyRange(args[i]))) {
63-
keys.push([i, range]);
97+
if (parseExternalKey) {
98+
keys.push([i, getExternalKeyNameLength(args[i])]);
6499
} else {
65100
keys.push(i);
66101
}
@@ -79,25 +114,23 @@ exports.getKeyIndexes = function (commandName, args, options) {
79114
}
80115
break;
81116
default:
82-
keyStart = def.keyStart - 1;
83-
keyStop = def.keyStop > 0 ? def.keyStop : args.length + def.keyStop + 1;
84-
if (keyStart >= 0 && keyStop <= args.length && keyStop > keyStart && def.step > 0) {
85-
for (i = keyStart; i < keyStop; i += def.step) {
117+
keyStart = command.keyStart - 1;
118+
keyStop = command.keyStop > 0 ? command.keyStop : args.length + command.keyStop + 1;
119+
if (keyStart >= 0 && keyStop <= args.length && keyStop > keyStart && command.step > 0) {
120+
for (i = keyStart; i < keyStop; i += command.step) {
86121
keys.push(i);
87122
}
88123
}
89124
break;
90125
}
126+
127+
return keys;
91128
};
92129

93-
function getPartialKeyRange(key) {
94-
var starPos = key.indexOf('*');
95-
if (starPos === -1) {
96-
return;
97-
}
98-
var hashPos = key.indexOf('->', starPos + 1);
99-
if (hashPos === 1) {
100-
return;
130+
function getExternalKeyNameLength(key) {
131+
if (typeof key !== 'string') {
132+
key = String(key);
101133
}
102-
return [0, hashPos];
134+
var hashPos = key.indexOf('->');
135+
return hashPos === -1 ? key.length : hashPos;
103136
}

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222
},
2323
"homepage": "https://github.com/luin/redis-commonds",
2424
"devDependencies": {
25+
"chai": "^3.4.0",
2526
"ioredis": "^1.0.8",
2627
"json-stable-stringify": "^1.0.0",
27-
"mocha": "^2.2.1",
28-
"superfetch": "^1.1.0"
28+
"mocha": "^2.2.1"
2929
}
3030
}

test/index.js

Lines changed: 74 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,77 @@
1-
var index = require('..');
2-
var assert = require('assert');
1+
'use strict';
32

4-
describe('redis commands', function () {
5-
it('should have a value', function () {
6-
assert(index);
3+
var commands = require('..');
4+
var expect = require('chai').expect;
5+
6+
describe('redis-commands', function () {
7+
describe('.list', function () {
8+
it('should be an array', function () {
9+
expect(commands.list).to.be.instanceof(Array);
10+
});
11+
12+
it('should ensure every command is lowercase', function () {
13+
commands.list.forEach(function (command) {
14+
expect(command.toLowerCase()).to.eql(command);
15+
});
16+
});
17+
18+
it('should not contain multi-word commands', function () {
19+
commands.list.forEach(function (command) {
20+
expect(command.indexOf(' ')).to.eql(-1);
21+
});
22+
});
23+
});
24+
25+
describe('.hasFlag', function () {
26+
it('should return true if the command has the flag', function () {
27+
expect(commands.hasFlag('set', 'write')).to.eql(true);
28+
expect(commands.hasFlag('set', 'denyoom')).to.eql(true);
29+
expect(commands.hasFlag('select', 'fast')).to.eql(true);
30+
});
31+
32+
it('should return false otherwise', function () {
33+
expect(commands.hasFlag('set', 'fast')).to.eql(false);
34+
expect(commands.hasFlag('set', 'readonly')).to.eql(false);
35+
expect(commands.hasFlag('select', 'denyoom')).to.eql(false);
36+
});
37+
});
38+
39+
describe('.getKeyIndexes', function () {
40+
var index = commands.getKeyIndexes;
41+
42+
it('should return key indexes', function () {
43+
expect(index('set', ['foo', 'bar'])).to.eql([0]);
44+
expect(index('get', ['foo'])).to.eql([0]);
45+
expect(index('mget', ['foo', 'bar'])).to.eql([0, 1]);
46+
expect(index('mset', ['foo', 'v1', 'bar', 'v2'])).to.eql([0, 2]);
47+
expect(index('hmset', ['key', 'foo', 'v1', 'bar', 'v2'])).to.eql([0]);
48+
expect(index('blpop', ['key1', 'key2', '17'])).to.eql([0, 1]);
49+
expect(index('evalsha', ['23123', '2', 'foo', 'bar', 'zoo'])).to.eql([2, 3]);
50+
expect(index('sort', ['key'])).to.eql([0]);
51+
expect(index('zunionstore', ['out', '2', 'zset1', 'zset2', 'WEIGHTS', '2', '3'])).to.eql([0, 2, 3]);
52+
});
53+
54+
it('should support numeric argument', function () {
55+
expect(index('evalsha', ['23123', 2, 'foo', 'bar', 'zoo'])).to.eql([2, 3]);
56+
expect(index('zinterstore', ['out', 2, 'zset1', 'zset2', 'WEIGHTS', 2, 3])).to.eql([0, 2, 3]);
57+
});
58+
59+
context('disable parseExternalKey', function () {
60+
it('should not parse external keys', function () {
61+
expect(index('sort', ['key', 'BY', 'hash:*->field'])).to.eql([0, 2]);
62+
expect(index('sort', ['key', 'BY', 'hash:*->field', 'LIMIT', 2, 3, 'GET', 'gk', 'GET', '#', 'Get', 'gh->f*', 'DESC', 'ALPHA', 'STORE', 'store'])).to.eql([0, 2, 7, 11, 15]);
63+
});
64+
});
65+
66+
context('enable parseExternalKey', function () {
67+
it('should parse external keys', function () {
68+
expect(index('sort', ['key', 'BY', 'hash:*->field'], {
69+
parseExternalKey: true
70+
})).to.eql([0, [2, 6]]);
71+
expect(index('sort', ['key', 'BY', 'hash:*->field', 'LIMIT', 2, 3, 'GET', 'gk', 'GET', '#', 'Get', 'gh->f*', 'DESC', 'ALPHA', 'STORE', 'store'], {
72+
parseExternalKey: true
73+
})).to.eql([0, [2, 6], [7, 2], [11, 2], 15]);
74+
});
75+
});
776
});
877
});

0 commit comments

Comments
 (0)