From 6b2f5fbb197500d38e346a3137008364c8455082 Mon Sep 17 00:00:00 2001 From: HirokiUchikawa Date: Thu, 12 Jul 2018 19:19:55 +0900 Subject: [PATCH 1/2] Allow multiple keys and values to be passed to `set` --- red/runtime/nodes/context/index.js | 24 +++++++++++- test/red/runtime/nodes/context/index_spec.js | 40 ++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/red/runtime/nodes/context/index.js b/red/runtime/nodes/context/index.js index 0927dd9c6..a409c46dc 100644 --- a/red/runtime/nodes/context/index.js +++ b/red/runtime/nodes/context/index.js @@ -268,7 +268,29 @@ function createContext(id,seed) { } context = getContextStorage(storage); } - context.set(scope, key, value, callback); + if (!Array.isArray(key) || !Array.isArray(value) || key.length !== value.length) { + context.set(scope, key, value, callback); + } else { + // If key and value are Array and each length is same, set each key-value pair. + var index = 0; + var cb = function(err, v) { + if (err) { + if (callback) { + callback(err); + } + } else { + index++; + if (index === key.length) { + if (callback) { + callback(null); + } + } else { + context.set(scope, key[index], value[index], cb); + } + } + }; + context.set(scope, key[index], value[index], cb); + } }; obj.keys = function(storage, callback) { var context; diff --git a/test/red/runtime/nodes/context/index_spec.js b/test/red/runtime/nodes/context/index_spec.js index d4f33059e..8ac1d96c2 100644 --- a/test/red/runtime/nodes/context/index_spec.js +++ b/test/red/runtime/nodes/context/index_spec.js @@ -615,6 +615,46 @@ describe('context', function() { }); }).catch(function(err){ done(err); }); }); + + it('should store multiple properties if key and value are arrays', function(done) { + Context.init({contextStorage:memoryStorage}); + Context.load().then(function(){ + var context = Context.get("1","flow"); + context.set(["foo1","foo2","foo3"], ["bar1","bar2","bar3"], "memory", function(err){ + if (err) { + done(err); + } else { + context.get(["foo1","foo2","foo3"], "memory", function(err,foo1,foo2,foo3){ + if (err) { + done(err); + } else { + foo1.should.be.equal("bar1"); + foo2.should.be.equal("bar2"); + foo3.should.be.equal("bar3"); + done(); + } + }); + } + }); + }); + }); + + it('should return an error if an error occurs in storing multiple values', function(done) { + Context.init({contextStorage:contextStorage}); + stubSet.onFirstCall().callsArgWith(3, null); + stubSet.onSecondCall().callsArgWith(3, "error2"); + stubSet.onThirdCall().callsArgWith(3, null); + Context.load().then(function(){ + var context = Context.get("1","flow"); + context.set(["foo1","foo2","foo3"], ["bar1","bar2","bar3"], "memory", function(err){ + if (err === "error2") { + done(); + } else { + done("An error occurred"); + } + }); + }).catch(function(err){ done(err); }); + }); }); describe('delete context',function(){ From 050acd239c59ec5bc48195dbdd17116444c64173 Mon Sep 17 00:00:00 2001 From: HirokiUchikawa Date: Fri, 13 Jul 2018 20:59:45 +0900 Subject: [PATCH 2/2] Allow arrays of different lengths to be passed to `set`. --- red/runtime/nodes/context/index.js | 17 ++- test/red/runtime/nodes/context/index_spec.js | 119 +++++++++++++++++++ 2 files changed, 131 insertions(+), 5 deletions(-) diff --git a/red/runtime/nodes/context/index.js b/red/runtime/nodes/context/index.js index a409c46dc..0816303a2 100644 --- a/red/runtime/nodes/context/index.js +++ b/red/runtime/nodes/context/index.js @@ -268,12 +268,14 @@ function createContext(id,seed) { } context = getContextStorage(storage); } - if (!Array.isArray(key) || !Array.isArray(value) || key.length !== value.length) { + if (!Array.isArray(key)) { context.set(scope, key, value, callback); } else { - // If key and value are Array and each length is same, set each key-value pair. + // If key is an array, set each key-value pair. + // If the value array is longer than the key array, then the extra values are ignored. var index = 0; - var cb = function(err, v) { + var values = [].concat(value); // Convert the value to an array + var cb = function(err) { if (err) { if (callback) { callback(err); @@ -285,11 +287,16 @@ function createContext(id,seed) { callback(null); } } else { - context.set(scope, key[index], value[index], cb); + if(index < values.length) { + context.set(scope, key[index], values[index], cb); + } else { + // If the value array is shorter than the key array, use null for missing values. + context.set(scope, key[index], null, cb); + } } } }; - context.set(scope, key[index], value[index], cb); + context.set(scope, key[index], values[index], cb); } }; obj.keys = function(storage, callback) { diff --git a/test/red/runtime/nodes/context/index_spec.js b/test/red/runtime/nodes/context/index_spec.js index 8ac1d96c2..73c36eba0 100644 --- a/test/red/runtime/nodes/context/index_spec.js +++ b/test/red/runtime/nodes/context/index_spec.js @@ -639,6 +639,125 @@ describe('context', function() { }); }); + it('should deletes multiple properties', function(done) { + Context.init({contextStorage:memoryStorage}); + Context.load().then(function(){ + var context = Context.get("1","flow"); + context.set(["foo1","foo2","foo3"], ["bar1","bar2","bar3"], "memory", function(err){ + if (err) { + done(err); + } else { + context.get(["foo1","foo2","foo3"], "memory", function(err,foo1,foo2,foo3){ + if (err) { + done(err); + } else { + foo1.should.be.equal("bar1"); + foo2.should.be.equal("bar2"); + foo3.should.be.equal("bar3"); + context.set(["foo1","foo2","foo3"], new Array(3), "memory", function(err){ + if (err) { + done(err); + } else { + context.get(["foo1","foo2","foo3"], "memory", function(err,foo1,foo2,foo3){ + if (err) { + done(err); + } else { + should.not.exist(foo1); + should.not.exist(foo2); + should.not.exist(foo3); + done(); + } + }); + } + }); + } + }); + } + }); + }); + }); + + it('should use null for missing values if the value array is shorter than the key array', function(done) { + Context.init({contextStorage:memoryStorage}); + Context.load().then(function(){ + var context = Context.get("1","flow"); + context.set(["foo1","foo2","foo3"], ["bar1","bar2"], "memory", function(err){ + if (err) { + done(err); + } else { + context.keys(function(err, keys){ + keys.should.have.length(3); + keys.should.eql(["foo1","foo2","foo3"]); + context.get(["foo1","foo2","foo3"], "memory", function(err,foo1,foo2,foo3){ + if (err) { + done(err); + } else { + foo1.should.be.equal("bar1"); + foo2.should.be.equal("bar2"); + should(foo3).be.null(); + done(); + } + }); + }); + } + }); + }); + }); + + it('should use null for missing values if the value is not array', function(done) { + Context.init({contextStorage:memoryStorage}); + Context.load().then(function(){ + var context = Context.get("1","flow"); + context.set(["foo1","foo2","foo3"], "bar1", "memory", function(err){ + if (err) { + done(err); + } else { + context.keys(function(err, keys){ + keys.should.have.length(3); + keys.should.eql(["foo1","foo2","foo3"]); + context.get(["foo1","foo2","foo3"], "memory", function(err,foo1,foo2,foo3){ + if (err) { + done(err); + } else { + foo1.should.be.equal("bar1"); + should(foo2).be.null(); + should(foo3).be.null(); + done(); + } + }); + }); + } + }); + }); + }); + + it('should ignore the extra values if the value array is longer than the key array', function(done) { + Context.init({contextStorage:memoryStorage}); + Context.load().then(function(){ + var context = Context.get("1","flow"); + context.set(["foo1","foo2","foo3"], ["bar1","bar2","bar3","ignored"], "memory", function(err){ + if (err) { + done(err); + } else { + context.keys(function(err, keys){ + keys.should.have.length(3); + keys.should.eql(["foo1","foo2","foo3"]); + context.get(["foo1","foo2","foo3"], "memory", function(err,foo1,foo2,foo3){ + if (err) { + done(err); + } else { + foo1.should.be.equal("bar1"); + foo2.should.be.equal("bar2"); + foo3.should.be.equal("bar3"); + done(); + } + }); + }); + } + }); + }); + }); + it('should return an error if an error occurs in storing multiple values', function(done) { Context.init({contextStorage:contextStorage}); stubSet.onFirstCall().callsArgWith(3, null);