Repository: rtfeldman/seamless-immutable
Pull request #37 (2015-05-06 15:54:59)

Fix index-as-string bugs
Because JavaScript.


Patch:
diff --git a/README.md b/README.md
index 7cdce7e..a592375 100644
--- a/README.md
+++ b/README.md
@@ -195,6 +195,10 @@ Returns a mutable copy of the object. For a deeply mutable copy, in which any in
 
 ### Releases
 
+#### 2.3.2
+
+Fixes a bug where indices passed into iterators for flatMap and asObject were strings instead of numbers.
+
 #### 2.3.1
 
 Fixes an IE and Firefox bug related to cloning Dates while preserving their prototypes.
diff --git a/bower.json b/bower.json
index e431e9f..dc0c589 100644
--- a/bower.json
+++ b/bower.json
@@ -1,7 +1,7 @@
 {
   "name": "seamless-immutable",
   "main": "seamless-immutable.js",
-  "version": "2.3.1",
+  "version": "2.3.2",
   "homepage": "https://github.com/rtfeldman/seamless-immutable",
   "authors": [
     "Richard Feldman <richard.t.feldman@gmail.com>"
diff --git a/package.json b/package.json
index 0b6c566..7ebf57e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "seamless-immutable",
-  "version": "2.3.1",
+  "version": "2.3.2",
   "description": "Immutable data structures for JavaScript which are backwards-compatible with normal JS Arrays and Objects.",
   "main": "seamless-immutable.development.js",
   "devDependencies": {
diff --git a/seamless-immutable.development.js b/seamless-immutable.development.js
index 852aed6..b39f3c3 100644
--- a/seamless-immutable.development.js
+++ b/seamless-immutable.development.js
@@ -121,7 +121,7 @@
     var result = [];
 
     for (var key in this) {
-      var iteratorResult = iterator(this[key], key, this);
+      var iteratorResult = iterator(this[key], parseInt(key), this);
 
       if (iteratorResult instanceof Array) {
         // Concatenate Array results into the return value we're building up.
@@ -195,7 +195,7 @@
     var result = {};
 
     for (var index in this) {
-      var pair  = iterator(this[index], index, this),
+      var pair  = iterator(this[index], parseInt(index), this),
           key   = pair[0],
           value = pair[1];
 
@@ -247,7 +247,7 @@
     // in a change from this object's value at that key, set anyChanges = true.
     function addToResult(currentObj, otherObj, key) {
       var immutableValue = Immutable(otherObj[key]);
-      var mergerResult = merger && merger(currentObj[key], immutableValue);
+      var mergerResult = merger && merger(currentObj[key], immutableValue, config);
 
       anyChanges = anyChanges ||
         mergerResult !== undefined ||
diff --git a/seamless-immutable.production.min.js b/seamless-immutable.production.min.js
index ccc9776..e9408a6 100644
--- a/seamless-immutable.production.min.js
+++ b/seamless-immutable.production.min.js
@@ -1,1 +1,1 @@
-!function(){"use strict";function a(a,b,c){Object.defineProperty(a,b,{enumerable:!1,configurable:!1,writable:!1,value:c})}function b(b){a(b,s,!0)}function c(a){return"object"==typeof a?null===a||a.hasOwnProperty(s):!0}function d(a){return!(null===a||"object"!=typeof a||a instanceof Array||a instanceof Date)}function e(a){var b=new Error(a);return b.__proto__=e,b}function f(a,c){b(a);return a}function g(b,c){var d=b[c];a(b,c,function(){return r(d.apply(b,arguments))})}function h(b){for(var c in w){var d=w[c];g(b,d)}a(b,"flatMap",i),a(b,"asObject",l),a(b,"asMutable",k);for(var e=0,h=b.length;h>e;e++)b[e]=r(b[e]);return f(b,v)}function i(a){if(0===arguments.length)return this;var b=[];for(var c in this){var d=a(this[c],c,this);d instanceof Array?b.push.apply(b,d):b.push(d)}return h(b)}function j(a){if(0===arguments.length)return this;a instanceof Array||(a=Array.prototype.slice.call(arguments));var b={};for(var c in this)-1===a.indexOf(c)&&(b[c]=this[c]);return q(b)}function k(a){var b,c,d=[];if(a&&a.deep)for(b=0,c=this.length;c>b;b++)d.push(m(this[b]));else for(b=0,c=this.length;c>b;b++)d.push(this[b]);return d}function l(a){"function"!=typeof a&&(a=function(a){return a});var b={};for(var c in this){var d=a(this[c],c,this),e=d[0],f=d[1];b[e]=f}return q(b)}function m(a){return a&&a.hasOwnProperty(s)?a.asMutable({deep:!0}):a}function n(a,b){for(var c in a)b[c]=a[c];return b}function o(a,b){function c(a,c,e){var h=r(c[e]),k=j&&j(a[e],h);f=f||void 0!==k||!a.hasOwnProperty(e)||h!==a[e]&&h===h,g[e]=k?k:i&&d(a[e])&&d(h)?a[e].merge(h,b):h}if(0===arguments.length)return this;if(null===a||"object"!=typeof a)throw new TypeError("Immutable#merge can only be invoked with objects or arrays, not "+JSON.stringify(a));var e,f=!1,g=n(this,{}),h=a instanceof Array,i=b&&b.deep,j=b&&b.merger;if(h)for(var k in a){var l=a[k];for(e in l)c(this,l,e)}else for(e in a)c(this,a,e);return f?q(g):this}function p(a){var b,c={};if(a&&a.deep)for(b in this)c[b]=m(this[b]);else for(b in this)c[b]=this[b];return c}function q(b){return a(b,"merge",o),a(b,"without",j),a(b,"asMutable",p),f(b,t)}function r(a){if(arguments.length>1)return h(Array.prototype.slice.call(arguments));if(c(a))return a;if(a instanceof Array)return h(a.slice());if(a instanceof Date)return f(new Date(a.getTime()));var b={};for(var d in a)b[d]=r(a[d]);return q(b)}var s="__immutable_invariants_hold",t=["setPrototypeOf"],u=["keys"],v=t.concat(["push","pop","sort","splice","shift","unshift","reverse"]),w=u.concat(["map","filter","slice","concat","reduce","reduceRight"]);e.prototype=Error.prototype,r.isImmutable=c,r.ImmutableError=e,Object.freeze(r),"object"==typeof module?module.exports=r:"object"==typeof exports?exports.Immutable=r:"object"==typeof window?window.Immutable=r:"object"==typeof global&&(global.Immutable=r)}();
\ No newline at end of file
+!function(){"use strict";function a(a,b,c){Object.defineProperty(a,b,{enumerable:!1,configurable:!1,writable:!1,value:c})}function b(b){a(b,s,!0)}function c(a){return"object"==typeof a?null===a||a.hasOwnProperty(s):!0}function d(a){return!(null===a||"object"!=typeof a||a instanceof Array||a instanceof Date)}function e(a){var b=new Error(a);return b.__proto__=e,b}function f(a,c){b(a);return a}function g(b,c){var d=b[c];a(b,c,function(){return r(d.apply(b,arguments))})}function h(b){for(var c in w){var d=w[c];g(b,d)}a(b,"flatMap",i),a(b,"asObject",l),a(b,"asMutable",k);for(var e=0,h=b.length;h>e;e++)b[e]=r(b[e]);return f(b,v)}function i(a){if(0===arguments.length)return this;var b=[];for(var c in this){var d=a(this[c],parseInt(c),this);d instanceof Array?b.push.apply(b,d):b.push(d)}return h(b)}function j(a){if(0===arguments.length)return this;a instanceof Array||(a=Array.prototype.slice.call(arguments));var b={};for(var c in this)-1===a.indexOf(c)&&(b[c]=this[c]);return q(b)}function k(a){var b,c,d=[];if(a&&a.deep)for(b=0,c=this.length;c>b;b++)d.push(m(this[b]));else for(b=0,c=this.length;c>b;b++)d.push(this[b]);return d}function l(a){"function"!=typeof a&&(a=function(a){return a});var b={};for(var c in this){var d=a(this[c],parseInt(c),this),e=d[0],f=d[1];b[e]=f}return q(b)}function m(a){return a&&a.hasOwnProperty(s)?a.asMutable({deep:!0}):a}function n(a,b){for(var c in a)b[c]=a[c];return b}function o(a,b){function c(a,c,e){var h=r(c[e]),k=j&&j(a[e],h,b);f=f||void 0!==k||!a.hasOwnProperty(e)||h!==a[e]&&h===h,g[e]=k?k:i&&d(a[e])&&d(h)?a[e].merge(h,b):h}if(0===arguments.length)return this;if(null===a||"object"!=typeof a)throw new TypeError("Immutable#merge can only be invoked with objects or arrays, not "+JSON.stringify(a));var e,f=!1,g=n(this,{}),h=a instanceof Array,i=b&&b.deep,j=b&&b.merger;if(h)for(var k in a){var l=a[k];for(e in l)c(this,l,e)}else for(e in a)c(this,a,e);return f?q(g):this}function p(a){var b,c={};if(a&&a.deep)for(b in this)c[b]=m(this[b]);else for(b in this)c[b]=this[b];return c}function q(b){return a(b,"merge",o),a(b,"without",j),a(b,"asMutable",p),f(b,t)}function r(a){if(arguments.length>1)return h(Array.prototype.slice.call(arguments));if(c(a))return a;if(a instanceof Array)return h(a.slice());if(a instanceof Date)return f(new Date(a.getTime()));var b={};for(var d in a)b[d]=r(a[d]);return q(b)}var s="__immutable_invariants_hold",t=["setPrototypeOf"],u=["keys"],v=t.concat(["push","pop","sort","splice","shift","unshift","reverse"]),w=u.concat(["map","filter","slice","concat","reduce","reduceRight"]);e.prototype=Error.prototype,r.isImmutable=c,r.ImmutableError=e,Object.freeze(r),"object"==typeof module?module.exports=r:"object"==typeof exports?exports.Immutable=r:"object"==typeof window?window.Immutable=r:"object"==typeof global&&(global.Immutable=r)}();
\ No newline at end of file
diff --git a/src/seamless-immutable.js b/src/seamless-immutable.js
index dbfa2df..1d070ac 100644
--- a/src/seamless-immutable.js
+++ b/src/seamless-immutable.js
@@ -121,7 +121,7 @@
     var result = [];
 
     for (var key in this) {
-      var iteratorResult = iterator(this[key], key, this);
+      var iteratorResult = iterator(this[key], parseInt(key), this);
 
       if (iteratorResult instanceof Array) {
         // Concatenate Array results into the return value we're building up.
@@ -195,7 +195,7 @@
     var result = {};
 
     for (var index in this) {
-      var pair  = iterator(this[index], index, this),
+      var pair  = iterator(this[index], parseInt(index), this),
           key   = pair[0],
           value = pair[1];
 


Test patch:
diff --git a/test/ImmutableArray/test-asObject.js b/test/ImmutableArray/test-asObject.js
index 406693a..5e4d21f 100644
--- a/test/ImmutableArray/test-asObject.js
+++ b/test/ImmutableArray/test-asObject.js
@@ -18,6 +18,8 @@ module.exports = function(config) {
         }));
 
         var result = array.asObject(function(value, index) {
+          assert.strictEqual((typeof index), "number");
+
           // Check that the index argument we receive works as expected.
           assert.deepEqual(value, array[index], "Expected array[" + index + "] to be " + value);
 
@@ -30,7 +32,6 @@ module.exports = function(config) {
 
     it("works without an iterator on arrays that are already organized properly", function() {
       check(100, [TestUtils.ComplexObjectSpecifier()], function(obj) {
-        var keys  = _.keys(obj);
         var array = Immutable(_.map(obj, function(value, key) {
           return [key, value];
         }));
diff --git a/test/ImmutableArray/test-flatMap.js b/test/ImmutableArray/test-flatMap.js
index 4742311..ecc65e6 100644
--- a/test/ImmutableArray/test-flatMap.js
+++ b/test/ImmutableArray/test-flatMap.js
@@ -30,6 +30,16 @@ module.exports = function(config) {
       });
     });
 
+    it("passes the expected index value", function() {
+      check(100, [JSC.array()], function(array) {
+        var iterator = function(value, index) { return index; };
+        var expected = _.map(array, iterator);
+        var actual   = Immutable(array).flatMap(iterator);
+
+        assert.deepEqual(actual, expected);
+      });
+    });
+
     it("works the same way as map followed by flatten when the iterator function returns arrays", function() {
       check(100, [JSC.array()], function(array) {
         var returnValues = array.map(function() { return [JSC.any()()]; });