You've already forked node-redis
mirror of
https://github.com/redis/node-redis.git
synced 2025-08-01 16:46:54 +03:00
345 lines
16 KiB
JavaScript
345 lines
16 KiB
JavaScript
'use strict';
|
|
|
|
var assert = require('assert');
|
|
var config = require("./lib/config");
|
|
var helper = require('./helper');
|
|
var redis = config.redis;
|
|
var uuid = require('uuid');
|
|
|
|
describe("The 'batch' method", function () {
|
|
|
|
helper.allTests(function(parser, ip, args) {
|
|
|
|
describe("using " + parser + " and " + ip, function () {
|
|
var key, value;
|
|
|
|
beforeEach(function () {
|
|
key = uuid.v4();
|
|
value = uuid.v4();
|
|
});
|
|
|
|
describe("when not connected", function () {
|
|
var client;
|
|
|
|
beforeEach(function (done) {
|
|
client = redis.createClient.apply(redis.createClient, args);
|
|
client.once("connect", function () {
|
|
client.quit();
|
|
});
|
|
client.on('end', function () {
|
|
return done();
|
|
});
|
|
});
|
|
|
|
it("returns an empty array", function (done) {
|
|
var batch = client.batch();
|
|
batch.exec(function (err, res) {
|
|
assert.strictEqual(err, null);
|
|
assert.strictEqual(res.length, 0);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it("returns an empty array if promisified", function () {
|
|
return client.batch().execAsync().then(function(res) {
|
|
assert.strictEqual(res.length, 0);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("when connected", function () {
|
|
var client;
|
|
|
|
beforeEach(function (done) {
|
|
client = redis.createClient.apply(redis.createClient, args);
|
|
client.once("ready", function () {
|
|
client.flushdb(function (err) {
|
|
return done(err);
|
|
});
|
|
});
|
|
});
|
|
|
|
afterEach(function () {
|
|
client.end();
|
|
});
|
|
|
|
it("returns an empty array", function (done) {
|
|
var batch = client.batch();
|
|
batch.exec(function (err, res) {
|
|
assert.strictEqual(err, null);
|
|
assert.strictEqual(res.length, 0);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it("runs normal calls inbetween batch", function (done) {
|
|
var batch = client.batch();
|
|
batch.set("m1", "123");
|
|
client.set('m2', '456', done);
|
|
});
|
|
|
|
it("returns an empty array if promisified", function () {
|
|
return client.batch().execAsync().then(function(res) {
|
|
assert.strictEqual(res.length, 0);
|
|
});
|
|
});
|
|
|
|
it("returns an empty result array", function (done) {
|
|
var batch = client.batch();
|
|
var async = true;
|
|
var notBuffering = batch.exec(function (err, res) {
|
|
assert.strictEqual(err, null);
|
|
assert.strictEqual(res.length, 0);
|
|
async = false;
|
|
done();
|
|
});
|
|
assert(async);
|
|
assert.strictEqual(notBuffering, true);
|
|
});
|
|
|
|
it('fail individually when one command fails using chaining notation', function (done) {
|
|
var batch1, batch2;
|
|
batch1 = client.batch();
|
|
batch1.mset("batchfoo", "10", "batchbar", "20", helper.isString("OK"));
|
|
|
|
// Provoke an error at queue time
|
|
batch1.set("foo2", helper.isError());
|
|
batch1.incr("batchfoo");
|
|
batch1.incr("batchbar");
|
|
batch1.exec(function () {
|
|
// Confirm that the previous command, while containing an error, still worked.
|
|
batch2 = client.batch();
|
|
batch2.get('foo2', helper.isNull());
|
|
batch2.incr("batchbar", helper.isNumber(22));
|
|
batch2.incr("batchfoo", helper.isNumber(12));
|
|
batch2.exec(function (err, replies) {
|
|
assert.strictEqual(null, replies[0]);
|
|
assert.strictEqual(22, replies[1]);
|
|
assert.strictEqual(12, replies[2]);
|
|
return done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('fail individually when one command fails and emit the error if no callback has been provided', function (done) {
|
|
var batch1;
|
|
client.on('error', function (err) {
|
|
done(err);
|
|
});
|
|
batch1 = client.batch();
|
|
batch1.mset("batchfoo", "10", "batchbar", "20", helper.isString("OK"));
|
|
|
|
// Provoke an error at queue time
|
|
batch1.set("foo2");
|
|
batch1.incr("batchfoo");
|
|
batch1.incr("batchbar");
|
|
batch1.exec(function (err, res) {
|
|
assert.strictEqual(res[1].command, 'SET');
|
|
assert.strictEqual(res[1].code, 'ERR');
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('fail individually when one command in an array of commands fails', function (done) {
|
|
// test nested batch-bulk replies
|
|
client.batch([
|
|
["mget", "batchfoo", "batchbar", function (err, res) {
|
|
assert.strictEqual(2, res.length);
|
|
assert.strictEqual(0, +res[0]);
|
|
assert.strictEqual(0, +res[1]);
|
|
}],
|
|
["set", "foo2", helper.isError()],
|
|
["incr", "batchfoo"],
|
|
["incr", "batchbar"]
|
|
]).exec(function (err, replies) {
|
|
assert.strictEqual(2, replies[0].length);
|
|
assert.strictEqual(null, replies[0][0]);
|
|
assert.strictEqual(null, replies[0][1]);
|
|
assert.strictEqual('SET', replies[1].command);
|
|
assert.strictEqual("1", replies[2].toString());
|
|
assert.strictEqual("1", replies[3].toString());
|
|
return done();
|
|
});
|
|
});
|
|
|
|
it('handles multiple operations being applied to a set', function (done) {
|
|
client.sadd("some set", "mem 1");
|
|
client.sadd(["some set", "mem 2"]);
|
|
client.sadd("some set", "mem 3");
|
|
client.sadd("some set", "mem 4");
|
|
|
|
// make sure empty mb reply works
|
|
client.del("some missing set");
|
|
client.smembers("some missing set", function (err, reply) {
|
|
// make sure empty mb reply works
|
|
assert.strictEqual(0, reply.length);
|
|
});
|
|
|
|
// test nested batch-bulk replies with empty mb elements.
|
|
client.BATCH([
|
|
["smembers", ["some set"]],
|
|
["del", "some set"],
|
|
["smembers", "some set"]
|
|
])
|
|
.scard("some set")
|
|
.exec(function (err, replies) {
|
|
assert.strictEqual(4, replies[0].length);
|
|
assert.strictEqual(0, replies[2].length);
|
|
return done();
|
|
});
|
|
});
|
|
|
|
it('allows multiple operations to be performed using constructor with all kinds of syntax', function (done) {
|
|
var now = Date.now();
|
|
var arr = ["batchhmset", "batchbar", "batchbaz"];
|
|
var arr2 = ['some manner of key', 'otherTypes'];
|
|
var arr3 = [5768, "batchbarx", "batchfoox"];
|
|
var arr4 = ["mset", [578, "batchbar"], helper.isString('OK')];
|
|
client.batch([
|
|
arr4,
|
|
[["mset", "batchfoo2", "batchbar2", "batchfoo3", "batchbar3"], helper.isString('OK')],
|
|
["hmset", arr],
|
|
[["hmset", "batchhmset2", "batchbar2", "batchfoo3", "batchbar3", "test", helper.isString('OK')]],
|
|
["hmset", ["batchhmset", "batchbar", "batchfoo", helper.isString('OK')]],
|
|
["hmset", arr3, helper.isString('OK')],
|
|
['hmset', now, {123456789: "abcdefghij", "some manner of key": "a type of value", "otherTypes": 555}],
|
|
['hmset', 'key2', {"0123456789": "abcdefghij", "some manner of key": "a type of value", "otherTypes": 999}, helper.isString('OK')],
|
|
["HMSET", "batchhmset", ["batchbar", "batchbaz"]],
|
|
["hmset", "batchhmset", ["batchbar", "batchbaz"], helper.isString('OK')],
|
|
])
|
|
.hmget(now, 123456789, 'otherTypes')
|
|
.hmget('key2', arr2, function noop() {})
|
|
.hmget(['batchhmset2', 'some manner of key', 'batchbar3'])
|
|
.mget('batchfoo2', ['batchfoo3', 'batchfoo'], function(err, res) {
|
|
assert(res[0], 'batchfoo3');
|
|
assert(res[1], 'batchfoo');
|
|
})
|
|
.exec(function (err, replies) {
|
|
assert.equal(arr.length, 3);
|
|
assert.equal(arr2.length, 2);
|
|
assert.equal(arr3.length, 3);
|
|
assert.equal(arr4.length, 3);
|
|
assert.strictEqual(null, err);
|
|
assert.equal(replies[10][1], '555');
|
|
assert.equal(replies[11][0], 'a type of value');
|
|
assert.strictEqual(replies[12][0], null);
|
|
assert.equal(replies[12][1], 'test');
|
|
assert.equal(replies[13][0], 'batchbar2');
|
|
assert.equal(replies[13].length, 3);
|
|
assert.equal(replies.length, 14);
|
|
return done();
|
|
});
|
|
});
|
|
|
|
it('converts a non string key to a string', function(done) {
|
|
// TODO: Converting the key might change soon again.
|
|
client.batch().hmset(true, {
|
|
test: 123,
|
|
bar: 'baz'
|
|
}).exec(done);
|
|
});
|
|
|
|
it('runs a batch without any further commands', function(done) {
|
|
var buffering = client.batch().exec(function(err, res) {
|
|
assert.strictEqual(err, null);
|
|
assert.strictEqual(res.length, 0);
|
|
done();
|
|
});
|
|
assert(typeof buffering === 'boolean');
|
|
});
|
|
|
|
it('runs a batch without any further commands and without callback', function() {
|
|
var buffering = client.batch().exec();
|
|
assert.strictEqual(buffering, true);
|
|
});
|
|
|
|
it('allows multiple operations to be performed using a chaining API', function (done) {
|
|
client.batch()
|
|
.mset('some', '10', 'keys', '20')
|
|
.incr('some')
|
|
.incr('keys')
|
|
.mget('some', 'keys')
|
|
.exec(function (err, replies) {
|
|
assert.strictEqual(null, err);
|
|
assert.equal('OK', replies[0]);
|
|
assert.equal(11, replies[1]);
|
|
assert.equal(21, replies[2]);
|
|
assert.equal(11, replies[3][0].toString());
|
|
assert.equal(21, replies[3][1].toString());
|
|
return done();
|
|
});
|
|
});
|
|
|
|
it('allows multiple commands to work the same as normal to be performed using a chaining API', function (done) {
|
|
client.batch()
|
|
.mset(['some', '10', 'keys', '20'])
|
|
.incr(['some', helper.isNumber(11)])
|
|
.incr(['keys'], helper.isNumber(21))
|
|
.mget('some', 'keys')
|
|
.exec(function (err, replies) {
|
|
assert.strictEqual(null, err);
|
|
assert.equal('OK', replies[0]);
|
|
assert.equal(11, replies[1]);
|
|
assert.equal(21, replies[2]);
|
|
assert.equal(11, replies[3][0].toString());
|
|
assert.equal(21, replies[3][1].toString());
|
|
return done();
|
|
});
|
|
});
|
|
|
|
it('allows multiple commands to work the same as normal to be performed using a chaining API promisified', function () {
|
|
return client.batch()
|
|
.mset(['some', '10', 'keys', '20'])
|
|
.incr(['some', helper.isNumber(11)])
|
|
.incr(['keys'], helper.isNumber(21))
|
|
.mget('some', 'keys')
|
|
.execAsync()
|
|
.then(function (replies) {
|
|
assert.equal('OK', replies[0]);
|
|
assert.equal(11, replies[1]);
|
|
assert.equal(21, replies[2]);
|
|
assert.equal(11, replies[3][0].toString());
|
|
assert.equal(21, replies[3][1].toString());
|
|
});
|
|
});
|
|
|
|
it('allows an array to be provided indicating multiple operations to perform', function (done) {
|
|
// test nested batch-bulk replies with nulls.
|
|
client.batch([
|
|
["mget", ["batchfoo", "some", "random value", "keys"]],
|
|
["incr", "batchfoo"]
|
|
])
|
|
.exec(function (err, replies) {
|
|
assert.strictEqual(replies.length, 2);
|
|
assert.strictEqual(replies[0].length, 4);
|
|
return done();
|
|
});
|
|
});
|
|
|
|
it('allows multiple operations to be performed on a hash', function (done) {
|
|
client.batch()
|
|
.hmset("batchhash", "a", "foo", "b", 1)
|
|
.hmset("batchhash", {
|
|
extra: "fancy",
|
|
things: "here"
|
|
})
|
|
.hgetall("batchhash")
|
|
.exec(done);
|
|
});
|
|
|
|
it("should work without any callback", function (done) {
|
|
helper.serverVersionAtLeast.call(this, client, [2, 6, 5]);
|
|
|
|
var batch = client.batch();
|
|
batch.set("baz", "binary");
|
|
batch.set("foo", "bar");
|
|
batch.exec();
|
|
|
|
client.get('foo', helper.isString('bar', done));
|
|
});
|
|
|
|
});
|
|
});
|
|
});
|
|
});
|