Skip to content

Commit

Permalink
Feat: Add LRANGE support (#335)
Browse files Browse the repository at this point in the history
* Create lrange.js

* Create test file for LRANGE

* Lining issue fix: no-param-reassign

* Add lrange to export list

* Update lrange.js
  • Loading branch information
sseidametov authored and stipsan committed Nov 15, 2017
1 parent aae16cd commit f9dad15
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/commands/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export * from './lpop';
export * from './lpopBuffer';
export * from './lpush';
export * from './lpushx';
export * from './lrange';
export * from './lrem';
export * from './lset';
export * from './mget';
Expand Down
27 changes: 27 additions & 0 deletions src/commands/lrange.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* Returns the specified elements of the list stored at key. The offsets start and stop are zero-based indexes, with 0 being the first element of the list (the head of the list), 1 being the next element and so on.
* These offsets can also be negative numbers indicating offsets starting at the end of the list. For example, -1 is the last element of the list, -2 the penultimate, and so on.
*
* @param {string} key
* @param {string} start Start index
* @param {string} end End index (included in returned range)
* @return {Array} An array in the defined range
*/
export function lrange(key, s, e) {
if (this.data.has(key) && !(this.data.get(key) instanceof Array)) {
throw new Error(`Key ${key} does not contain a list`);
}
let start = parseInt(s, 10);
let end = parseInt(e, 10);

const list = this.data.get(key) || [];

if (start < 0) {
start = list.length + start;
}
if (end < 0) {
end = list.length + end;
}

return list.slice(start, end + 1);
}
67 changes: 67 additions & 0 deletions test/commands/lrange.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import expect from 'expect';

import MockRedis from '../../src';

describe('lrange', () => {
it('should return first 3 items', () => {
const redis = new MockRedis({
data: {
foo: ['1', '2', '3', '4', '5'],
},
});

return redis
.lrange('foo', 0, 2)
.then(res => expect(res).toEqual(['1', '2', '3']));
});

it('should return last 3 items', () => {
const redis = new MockRedis({
data: {
foo: ['1', '2', '3', '4', '5'],
},
});

return redis
.lrange('foo', -3, -1)
.then(res => expect(res).toEqual(['3', '4', '5']));
});

it('should return last all items on larger numbers', () => {
const redis = new MockRedis({
data: {
foo: ['1', '2', '3', '4', '5'],
},
});

return redis
.lrange('foo', 0, 100)
.then(res => expect(res).toEqual(['1', '2', '3', '4', '5']));
});

it('should return empty array if out-of-range', () => {
const redis = new MockRedis({
data: {
foo: ['1', '2', '3', '4', '5'],
},
});

return redis
.lrange('foo', 10, 100)
.then(res => expect(res).toEqual([]));
});

it('should throw an exception if the key contains something other than a list', () => {
const redis = new MockRedis({
data: {
foo: 'not a list',
},
});

return redis
.lrange('foo', 0, 2)
.catch(err =>
expect(err.message).toBe('Key foo does not contain a list')
);
});
});

0 comments on commit f9dad15

Please sign in to comment.