diff --git a/src/seamless-immutable.js b/src/seamless-immutable.js index 191f9a9..3e714ae 100644 --- a/src/seamless-immutable.js +++ b/src/seamless-immutable.js @@ -577,6 +577,15 @@ function immutableInit(config) { return result; } + function objectReduce(callback, initialValue) { + var keys = Object.keys(this); + var self = this; + var values = keys.map(function(key) { return self[key] }); + return values.reduce(function(accumulator, currentValue, index) { + return callback(accumulator, currentValue, keys[index], index, this) + }, initialValue); + } + // Creates plain object to be used for cloning function instantiatePlainObject() { return {}; @@ -586,6 +595,7 @@ function immutableInit(config) { function makeImmutableObject(obj) { if (!globalConfig.use_static) { addPropertyTo(obj, "merge", merge); + addPropertyTo(obj, "reduce", objectReduce); addPropertyTo(obj, "replace", objectReplace); addPropertyTo(obj, "without", without); addPropertyTo(obj, "asMutable", asMutableObject); @@ -723,6 +733,7 @@ function immutableInit(config) { Immutable.getIn = toStatic(getIn); Immutable.flatMap = toStatic(flatMap); Immutable.asObject = toStatic(asObject); + Immutable.reduce = toStaticObjectOrArray(objectReduce, Array.prototype.reduce); if (!globalConfig.use_static) { Immutable.static = immutableInit({ use_static: true diff --git a/test/ImmutableObject.spec.js b/test/ImmutableObject.spec.js index f65ef88..cd76e45 100644 --- a/test/ImmutableObject.spec.js +++ b/test/ImmutableObject.spec.js @@ -1,11 +1,12 @@ var testMerge = require("./ImmutableObject/test-merge.js"); -var testReplace = require("./ImmutableObject/test-replace.js"); +var testReplace = require("./ImmutableObject/test-replace.js"); var testCompat = require("./ImmutableObject/test-compat.js"); var testWithout = require("./ImmutableObject/test-without.js"); var testAsMutable = require("./ImmutableObject/test-asMutable.js"); var testSet = require("./ImmutableObject/test-set.js"); var testUpdate = require("./ImmutableObject/test-update.js"); -var testGetIn = require("./ImmutableObject/test-getIn.js"); +var testGetIn = require("./ImmutableObject/test-getIn.js"); +var testReduce = require("./ImmutableObject/test-reduce"); var devBuild = require("../seamless-immutable.development.js"); var prodBuild = require("../seamless-immutable.production.min.js"); var getTestUtils = require("./TestUtils.js"); @@ -27,6 +28,7 @@ var getTestUtils = require("./TestUtils.js"); testSet(config); testUpdate(config); testGetIn(config); + testReduce(config) }); }); }); diff --git a/test/ImmutableObject/test-reduce.js b/test/ImmutableObject/test-reduce.js new file mode 100644 index 0000000..c4d97d6 --- /dev/null +++ b/test/ImmutableObject/test-reduce.js @@ -0,0 +1,73 @@ +var JSC = require("jscheck"); +var assert = require("chai").assert; +var _ = require("lodash"); +var getTestUtils = require("../TestUtils.js"); + + +module.exports = function(config) { + var Immutable = config.implementation; + var TestUtils = getTestUtils(Immutable); + + describe("#reduce", function() { + it("static reduces object to array", function () { + var ob = { + key1: 'value1', + key2: { + key3: 'value3' + } + }; + var expected = Immutable([ + ['key1', 'value1'], + ['key2', { key3: 'value3' }], + ]); + var immutable = Immutable(ob); + + TestUtils.assertJsonEqual( + Immutable.reduce(immutable, function(accumulator, currentValue, key, index, object) { + return accumulator.concat([[key, currentValue]]); + }, Immutable([])), + expected + ); + }); + + it("non-static reduces object to array", function () { + var ob = { + key1: 'value1', + key2: { + key3: 'value3' + } + }; + var expected = Immutable([ + ['key1', 'value1'], + ['key2', { key3: 'value3' }], + ]); + var immutable = Immutable(ob); + + TestUtils.assertJsonEqual( + immutable.reduce(function(accumulator, currentValue, key, index, object) { + return accumulator.concat([[key, currentValue]]); + }, Immutable([])), + expected + ); + }); + it("static reduces non-immutable object", function () { + var ob = { + key1: 'value1', + key2: { + key3: 'value3' + } + }; + var expected = [ + ['key1', 'value1'], + ['key2', { key3: 'value3' }], + ]; + + TestUtils.assertJsonEqual( + Immutable.reduce(ob, function(accumulator, currentValue, key, index, object) { + return accumulator.concat([[key, currentValue]]); + }, Immutable([])), + expected + ); + }); + }) +}