From d32117ce0c12a81ce6a404e64304bbb198d1ec3f Mon Sep 17 00:00:00 2001 From: Kenshi Kawaguchi Date: Wed, 8 Jul 2015 13:51:20 -0700 Subject: [PATCH 01/10] Failing test for being able to hmset with no callback --- test/redis-mock.hash.test.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/redis-mock.hash.test.js b/test/redis-mock.hash.test.js index 83f4b03..7bb91d2 100644 --- a/test/redis-mock.hash.test.js +++ b/test/redis-mock.hash.test.js @@ -355,6 +355,18 @@ describe("multiple get/set", function () { }); }); + it("should be able to set values with no callback", function (done) { + var r = redismock.createClient(); + var d = {mKey1: mValue1}; + + r.hmset('myKey', {mKey1: mValue1}); + r.hgetall('myKey', function (err, result) { + should(result).have.property(mKey1, mValue1); + done(); + }); + + }); + it("should be able to set multiple keys as an object", function (done) { From 15df41b2a49b418fd889d50579f566d2450f73e8 Mon Sep 17 00:00:00 2001 From: Kenshi Kawaguchi Date: Wed, 8 Jul 2015 13:55:52 -0700 Subject: [PATCH 02/10] Fix hmset with no callback --- lib/hash.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/hash.js b/lib/hash.js index 5758a79..90640d3 100644 --- a/lib/hash.js +++ b/lib/hash.js @@ -183,7 +183,7 @@ exports.hmset = function (mockInstance) { // 0: mockInstance // 1: hash name // 2: key/value object or first key name - if (arguments.length <= 3) { + if (arguments.length < 3) { return; } From 59c017fb27c38dee46dd2326195b15fff6976484 Mon Sep 17 00:00:00 2001 From: Kenshi Kawaguchi Date: Wed, 8 Jul 2015 14:37:06 -0700 Subject: [PATCH 03/10] Rename test --- test/redis-mock.hash.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/redis-mock.hash.test.js b/test/redis-mock.hash.test.js index 7bb91d2..1698ed4 100644 --- a/test/redis-mock.hash.test.js +++ b/test/redis-mock.hash.test.js @@ -355,7 +355,7 @@ describe("multiple get/set", function () { }); }); - it("should be able to set values with no callback", function (done) { + it("should be able to set multiple keys with no callback", function (done) { var r = redismock.createClient(); var d = {mKey1: mValue1}; From 6d8fc0cb022563b894289dce48e9fe26507f2e05 Mon Sep 17 00:00:00 2001 From: Kenshi Kawaguchi Date: Tue, 28 Mar 2017 10:57:39 -0700 Subject: [PATCH 04/10] whitespace --- lib/redis-mock.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/redis-mock.js b/lib/redis-mock.js index 4c02bd5..5d3de34 100755 --- a/lib/redis-mock.js +++ b/lib/redis-mock.js @@ -417,8 +417,3 @@ RedisMock.prototype.createClient = function (port_arg, host_arg, options) { return new RedisClient(); } - - - - - From 70ffce52ea003c26a585fec6be322d20e3704965 Mon Sep 17 00:00:00 2001 From: Kenshi Kawaguchi Date: Tue, 28 Mar 2017 11:19:33 -0700 Subject: [PATCH 05/10] add lrange command --- lib/list.js | 9 +++++++++ lib/redis-mock.js | 4 ++++ test/redis-mock.list.test.js | 30 +++++++++++++++++++++++++++++- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/lib/list.js b/lib/list.js index b9a470b..15f313e 100644 --- a/lib/list.js +++ b/lib/list.js @@ -175,6 +175,15 @@ exports.lindex = function (mockInstance, key, index, callback) { mockInstance._callCallback(callback, null, val); }; +/** + * Lrange + */ +exports.lrange = function (mockInstance, key, start, end, callback) { + var item = mockInstance.storage[key]; + var list = item ? item.value : []; + mockInstance._callCallback(callback, null, list.slice(start, end + 1)); +} + /** * Lset */ diff --git a/lib/redis-mock.js b/lib/redis-mock.js index 5d3de34..af1c59a 100755 --- a/lib/redis-mock.js +++ b/lib/redis-mock.js @@ -349,6 +349,10 @@ RedisClient.prototype.lindex = RedisClient.prototype.LINDEX = function (key, ind listfunctions.lindex.call(this, MockInstance, key, index, callback); } +RedisClient.prototype.lrange = RedisClient.prototype.LRANGE = function (key, start, end, callback) { + listfunctions.lrange.call(this, MockInstance, key, start, end, callback); +} + RedisClient.prototype.lset = RedisClient.prototype.LSET = function (key, index, value, callback) { listfunctions.lset.call(this, MockInstance, key, index, value, callback); } diff --git a/test/redis-mock.list.test.js b/test/redis-mock.list.test.js index 435cce1..4c73d2c 100644 --- a/test/redis-mock.list.test.js +++ b/test/redis-mock.list.test.js @@ -5,7 +5,7 @@ var sinon = require('./timer-helper') if (process.env['VALID_TESTS']) { redismock = require('redis'); - + } describe("basic pushing/poping list", function () { @@ -122,6 +122,34 @@ describe("llen", function () { }); +describe("lrange", function () { + var testKey = "myKey123"; + it("should return empty list", function (done) { + var r = redismock.createClient(); + r.lrange(testKey, 0, 1, function (err, result) { + result.length.should.equal(0); + r.end(); + done(); + }); + }); + + it("should return single value", function (done) { + var r = redismock.createClient(); + r.rpush(testKey, 'foo', function (err, result) { + r.rpush(testKey, 'bar', function (err, result) { + // lrange is right inclusive + r.lrange(testKey, 0, 1, function (err, result) { + result.length.should.equal(2); + result[0].should.equal('foo'); + result[1].should.equal('bar'); + r.end(); + done(); + }); + }); + }); + }); +}); + describe("lindex", function () { var testKey = "myKey4"; var testKey2 = "myKey5"; From c18b14246c47d81e4bd4c3d71d25742159f29737 Mon Sep 17 00:00:00 2001 From: Kenshi Kawaguchi Date: Tue, 28 Mar 2017 11:28:16 -0700 Subject: [PATCH 06/10] add test for wrong operation error for lrange --- lib/list.js | 4 ++++ test/redis-mock.list.test.js | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/lib/list.js b/lib/list.js index 15f313e..e9dfdb5 100644 --- a/lib/list.js +++ b/lib/list.js @@ -179,6 +179,10 @@ exports.lindex = function (mockInstance, key, index, callback) { * Lrange */ exports.lrange = function (mockInstance, key, start, end, callback) { + if (mockInstance.storage[key] && mockInstance.storage[key].type !== "list") { + return mockInstance._callCallback(callback, + new Error("WRONGTYPE Operation against a key holding the wrong kind of value")); + } var item = mockInstance.storage[key]; var list = item ? item.value : []; mockInstance._callCallback(callback, null, list.slice(start, end + 1)); diff --git a/test/redis-mock.list.test.js b/test/redis-mock.list.test.js index 4c73d2c..10ab306 100644 --- a/test/redis-mock.list.test.js +++ b/test/redis-mock.list.test.js @@ -133,6 +133,19 @@ describe("lrange", function () { }); }); + it("should return error for wrong operation", function (done) { + var r = redismock.createClient(); + + r.set(testKey, 'foo', function (err, result) { + r.lrange(testKey, 0, 1, function (err, result) { + should.not.exist(result); + should.exist(err); + r.end(); + done(); + }); + }); + }); + it("should return single value", function (done) { var r = redismock.createClient(); r.rpush(testKey, 'foo', function (err, result) { From c695e398992e4035034cb3da01c83f5ced67fa45 Mon Sep 17 00:00:00 2001 From: Kenshi Kawaguchi Date: Tue, 28 Mar 2017 13:07:51 -0700 Subject: [PATCH 07/10] properly handle negative indices --- lib/list.js | 4 +++- test/redis-mock.list.test.js | 17 ++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/lib/list.js b/lib/list.js index e9dfdb5..08c055c 100644 --- a/lib/list.js +++ b/lib/list.js @@ -185,7 +185,9 @@ exports.lrange = function (mockInstance, key, start, end, callback) { } var item = mockInstance.storage[key]; var list = item ? item.value : []; - mockInstance._callCallback(callback, null, list.slice(start, end + 1)); + var args = end == -1 ? [start] : [start, end + 1]; + var res = list.slice.call(list, args); + mockInstance._callCallback(callback, null, res); } /** diff --git a/test/redis-mock.list.test.js b/test/redis-mock.list.test.js index 10ab306..22ce3da 100644 --- a/test/redis-mock.list.test.js +++ b/test/redis-mock.list.test.js @@ -146,7 +146,7 @@ describe("lrange", function () { }); }); - it("should return single value", function (done) { + it("should return multiple values", function (done) { var r = redismock.createClient(); r.rpush(testKey, 'foo', function (err, result) { r.rpush(testKey, 'bar', function (err, result) { @@ -161,6 +161,21 @@ describe("lrange", function () { }); }); }); + + it("should return full list with negative indexes", function (done) { + var r = redismock.createClient(); + r.rpush(testKey, 'foo', function (err, result) { + r.rpush(testKey, 'bar', function (err, result) { + r.lrange(testKey, 0, -1, function (err, result) { + result.length.should.equal(2); + result[0].should.equal('foo'); + result[1].should.equal('bar'); + r.end(); + done(); + }); + }); + }); + }); }); describe("lindex", function () { From 8a047819450d7f80101a5af562ff2bf054ce2cbc Mon Sep 17 00:00:00 2001 From: Kenshi Kawaguchi Date: Tue, 28 Mar 2017 15:07:30 -0700 Subject: [PATCH 08/10] list functions can be called in a myriad of confusing ways --- lib/redis-mock.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/redis-mock.js b/lib/redis-mock.js index af1c59a..65aaa01 100755 --- a/lib/redis-mock.js +++ b/lib/redis-mock.js @@ -272,11 +272,22 @@ RedisClient.prototype.llen = RedisClient.prototype.LLEN = function (key, callbac } var push = function (fn, key, values, callback) { + var len = arguments.length; + var hasCallback = typeof(arguments[len - 1]) === "function"; + // Kind of a messy interface here... basically we need to support + // - push(key, 'myval') + // - push(key, 'val1', 'val2', ...) + // - push(key, ['val1, 'val2']) + var vals = []; - var hasCallback = typeof(arguments[arguments.length - 1]) === "function"; - for (var i = 2; i < (hasCallback ? arguments.length - 1 : arguments.length); i++) { - vals.push(arguments[i]); + if(Array.isArray(values)) { + vals = values; + } else { + for(var i=2;i < (hasCallback ? len - 1 : len); i++) { + vals.push(arguments[i]); + } } + if (hasCallback) { fn.call(this, MockInstance, key, vals, arguments[arguments.length - 1]); } else { From 7fc37593fe2d80d8874562e8b27f794043962509 Mon Sep 17 00:00:00 2001 From: Kenshi Kawaguchi Date: Tue, 28 Mar 2017 16:15:40 -0700 Subject: [PATCH 09/10] add ltrim command --- lib/list.js | 19 ++++++++++++++++++- lib/redis-mock.js | 4 ++++ test/redis-mock.list.test.js | 21 +++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/lib/list.js b/lib/list.js index 08c055c..21d895d 100644 --- a/lib/list.js +++ b/lib/list.js @@ -186,7 +186,24 @@ exports.lrange = function (mockInstance, key, start, end, callback) { var item = mockInstance.storage[key]; var list = item ? item.value : []; var args = end == -1 ? [start] : [start, end + 1]; - var res = list.slice.call(list, args); + var res = list.slice.apply(list, args); + mockInstance._callCallback(callback, null, res); +} + +/** + * Ltrim + */ +exports.ltrim = function (mockInstance, key, start, end, callback) { + var res = "OK"; + var item = mockInstance.storage[key]; + if (item && item.type !== "list") { + return mockInstance._callCallback(callback, + new Error("WRONGTYPE Operation against a key holding the wrong kind of value")); + } + + var args = end == -1 ? [start] : [start, end + 1]; + var list = item.value; + item.value = list.slice.apply(list, args); mockInstance._callCallback(callback, null, res); } diff --git a/lib/redis-mock.js b/lib/redis-mock.js index 65aaa01..98c5834 100755 --- a/lib/redis-mock.js +++ b/lib/redis-mock.js @@ -364,6 +364,10 @@ RedisClient.prototype.lrange = RedisClient.prototype.LRANGE = function (key, sta listfunctions.lrange.call(this, MockInstance, key, start, end, callback); } +RedisClient.prototype.ltrim = RedisClient.prototype.LTRIM = function (key, start, end, callback) { + listfunctions.ltrim.call(this, MockInstance, key, start, end, callback); +} + RedisClient.prototype.lset = RedisClient.prototype.LSET = function (key, index, value, callback) { listfunctions.lset.call(this, MockInstance, key, index, value, callback); } diff --git a/test/redis-mock.list.test.js b/test/redis-mock.list.test.js index 22ce3da..32865ef 100644 --- a/test/redis-mock.list.test.js +++ b/test/redis-mock.list.test.js @@ -178,6 +178,27 @@ describe("lrange", function () { }); }); +describe("ltrim", function () { + var values = ['a', 'b', 'c', 'd']; + var testKey = 'foo'; + it("should trim list", function (done) { + var r = redismock.createClient(); + r.rpush(testKey, values, function (err, result) { + r.ltrim(testKey, 0, 1, function (err, result) { + result.should.equal('OK'); + r.lrange(testKey, 0, 1, function (err, result) { + result.length.should.equal(2); + result[0].should.equal('a'); + result[1].should.equal('b'); + r.end(); + done(); + }); + }); + }); + }); +}); + + describe("lindex", function () { var testKey = "myKey4"; var testKey2 = "myKey5"; From 91457733d33a63f545921c2ad8cf3582d6113d60 Mon Sep 17 00:00:00 2001 From: Kenshi Kawaguchi Date: Tue, 28 Mar 2017 16:20:59 -0700 Subject: [PATCH 10/10] add another ltrim test --- test/redis-mock.list.test.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/redis-mock.list.test.js b/test/redis-mock.list.test.js index 32865ef..87da333 100644 --- a/test/redis-mock.list.test.js +++ b/test/redis-mock.list.test.js @@ -196,6 +196,22 @@ describe("ltrim", function () { }); }); }); + + it("should trim list with negative start/end", function (done) { + var r = redismock.createClient(); + r.rpush(testKey, values, function (err, result) { + r.ltrim(testKey, -2, -1, function (err, result) { + result.should.equal('OK'); + r.lrange(testKey, 0, 1, function (err, result) { + result.length.should.equal(2); + result[0].should.equal('c'); + result[1].should.equal('d'); + r.end(); + done(); + }); + }); + }); + }); });