diff --git a/red/runtime/nodes/context/index.js b/red/runtime/nodes/context/index.js index 0927dd9c6..0816303a2 100644 --- a/red/runtime/nodes/context/index.js +++ b/red/runtime/nodes/context/index.js @@ -268,7 +268,36 @@ function createContext(id,seed) { } context = getContextStorage(storage); } - context.set(scope, key, value, callback); + if (!Array.isArray(key)) { + context.set(scope, key, value, callback); + } else { + // 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 values = [].concat(value); // Convert the value to an array + var cb = function(err) { + if (err) { + if (callback) { + callback(err); + } + } else { + index++; + if (index === key.length) { + if (callback) { + callback(null); + } + } else { + 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], values[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..73c36eba0 100644 --- a/test/red/runtime/nodes/context/index_spec.js +++ b/test/red/runtime/nodes/context/index_spec.js @@ -615,6 +615,165 @@ 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 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); + 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(){