From ad45bd67ba40b86954e5649f04ef5c42258bf6d4 Mon Sep 17 00:00:00 2001 From: Robert Jackson Date: Thu, 28 Jun 2018 12:07:22 -0400 Subject: [PATCH 1/2] Add failing tests for `A().invoke()` not returning an `A`. --- .../ember-runtime/tests/array/invoke-test.js | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/packages/ember-runtime/tests/array/invoke-test.js b/packages/ember-runtime/tests/array/invoke-test.js index c23364c70e9..bd5033d16ce 100644 --- a/packages/ember-runtime/tests/array/invoke-test.js +++ b/packages/ember-runtime/tests/array/invoke-test.js @@ -1,4 +1,4 @@ -import EmberObject from '../../lib/system/object'; +import { Object as EmberObject, NativeArray } from '../../index'; import { AbstractTestCase } from 'internal-test-helpers'; import { runArrayTests } from '../helpers/array'; @@ -28,6 +28,33 @@ class InvokeTests extends AbstractTestCase { obj.invoke('foo', 2); this.assert.equal(cnt, 6, 'should have invoked 3 times, passing param'); } + + '@test invoke should return an array containing the results of each invoked method'(assert) { + let obj = this.newObject([ + { + foo() { + return 'one'; + }, + }, + {}, // intentionally not including `foo` method + { + foo() { + return 'two'; + }, + }, + ]); + + let result = obj.invoke('foo'); + assert.deepEqual(result, ['one', undefined, 'two']); + } + + '@test invoke should return an extended array (aka Ember.A)'(assert) { + let obj = this.newObject([{ foo() {} }, { foo() {} }]); + + let result = obj.invoke('foo'); + + assert.ok(NativeArray.detect(result), 'NativeArray has been applied'); + } } runArrayTests('invoke', InvokeTests); From 7542bc4586a9b6badfd01e233aea5290329c9d04 Mon Sep 17 00:00:00 2001 From: Robert Jackson Date: Thu, 28 Jun 2018 12:08:07 -0400 Subject: [PATCH 2/2] [BUGFIX] Ensure `ArrayMixin#invoke` returns an Ember.A. This is a partial revert of bee179dd, moving back to a manual `forEach` so that we can control the return value a bit more. When prototype extensions are disabled, we cannot rely on `this.map` to return an extended array. --- packages/ember-runtime/lib/mixins/array.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/ember-runtime/lib/mixins/array.js b/packages/ember-runtime/lib/mixins/array.js index d2c25bafbdc..1482bfbec9a 100644 --- a/packages/ember-runtime/lib/mixins/array.js +++ b/packages/ember-runtime/lib/mixins/array.js @@ -951,7 +951,11 @@ const ArrayMixin = Mixin.create(Enumerable, { @public */ invoke(methodName, ...args) { - return this.map(item => tryInvoke(item, methodName, args)); + let ret = A(); + + this.forEach(item => ret.push(tryInvoke(item, methodName, args))); + + return ret; }, /**