Skip to content

Commit

Permalink
[BUGFIX beta] [fixes #11736] ensure array computed macro’s have corre…
Browse files Browse the repository at this point in the history
…ct this
  • Loading branch information
stefanpenner committed Jul 14, 2015
1 parent a32ee08 commit 965f490
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 5 deletions.
18 changes: 13 additions & 5 deletions packages/ember-runtime/lib/computed/reduce_computed_macros.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import { isArray } from 'ember-runtime/utils';

function reduceMacro(dependentKey, callback, initialValue) {
return computed(`${dependentKey}.[]`, function() {
return get(this, dependentKey).reduce(callback, initialValue);
return get(this, dependentKey).reduce((previousValue, currentValue, index, array) => {
return callback.call(this, previousValue, currentValue, index, array);
}, initialValue);
}).readOnly();
}

Expand All @@ -30,7 +32,7 @@ function arrayMacro(dependentKey, callback) {
return computed(dependentKey, function() {
var value = get(this, propertyName);
if (isArray(value)) {
return Ember.A(callback(value));
return Ember.A(callback.call(this, value));
} else {
return Ember.A();
}
Expand Down Expand Up @@ -173,7 +175,9 @@ export function min(dependentKey) {
@public
*/
export function map(dependentKey, callback) {
return arrayMacro(dependentKey, value => value.map(callback));
return arrayMacro(dependentKey, function(value) {
return value.map(callback, this);
});
}

/**
Expand Down Expand Up @@ -251,7 +255,9 @@ export function mapBy(dependentKey, propertyKey) {
@public
*/
export function filter(dependentKey, callback) {
return arrayMacro(dependentKey, value => value.filter(callback));
return arrayMacro(dependentKey, function(value) {
return value.filter(callback, this);
});
}

/**
Expand Down Expand Up @@ -538,7 +544,9 @@ export function sort(itemsKey, sortDefinition) {
}

function customSort(itemsKey, comparator) {
return arrayMacro(itemsKey, value => value.slice().sort(comparator));
return arrayMacro(itemsKey, function(value) {
return value.slice().sort((x, y) => comparator.call(this, x, y));
});
}

// This one needs to dynamically set up and tear down observers on the itemsKey
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,22 @@ QUnit.test('it maps simple unshifted properties', function() {
deepEqual(obj.get('mapped'), ['A', 'B'], 'properties unshifted in sequence are mapped correctly');
});

QUnit.test('it has the correct `this`', function() {
obj = EmberObject.extend({
mapped: map('array', function(item) {
equal(this, obj, 'should have correct context');
return this.upperCase(item);
}),
upperCase(string) {
return string.toUpperCase();
}
}).create({
array: ['a', 'b', 'c']
});

deepEqual(obj.get('mapped'), ['A', 'B', 'C'], 'properties unshifted in sequence are mapped correctly');
});

QUnit.test('it passes the index to the callback', function() {
var array = ['a', 'b', 'c'];

Expand Down Expand Up @@ -227,6 +243,22 @@ QUnit.test('it passes the index to the callback', function() {
deepEqual(get(obj, 'filtered'), ['b'], 'index is passed to callback correctly');
});

QUnit.test('it has the correct `this`', function() {
obj = EmberObject.extend({
filtered: filter('array', function(item, index) {
equal(this, obj);
return this.isOne(index);
}),
isOne(value) {
return value === 1;
}
}).create({
array: ['a', 'b', 'c']
});

deepEqual(get(obj, 'filtered'), ['b'], 'index is passed to callback correctly');
});

QUnit.test('it passes the array to the callback', function() {
obj = EmberObject.extend({
filtered: filter('array', (item, index, array) => index === get(array, 'length') - 2)
Expand Down Expand Up @@ -1096,6 +1128,27 @@ QUnit.module('sort - sort function', {
}
});

QUnit.test('sort has correct `this`', function() {
var obj = EmberObject.extend({
sortedItems: sort('items.@each.fname', function(a, b) {
equal(this, obj, 'expected the object to be `this`');
return this.sortByLastName(a, b);
}),
sortByLastName(a, b) {
return sortByFnameAsc(a, b);
}
}).create({
items: Ember.A([
{ fname: 'Jaime', lname: 'Lannister', age: 34 },
{ fname: 'Cersei', lname: 'Lannister', age: 34 },
{ fname: 'Robb', lname: 'Stark', age: 16 },
{ fname: 'Bran', lname: 'Stark', age: 8 }
])
});

obj.get('sortedItems');
});

QUnit.test('sort (with function) is readOnly', function() {
QUnit.throws(function() {
obj.set('sortedItems', 1);
Expand Down Expand Up @@ -1157,6 +1210,7 @@ QUnit.test('sorts correctly as only one property changes', function() {
deepEqual(obj.get('sortedItems').mapBy('name'), ['A', 'B', 'C', 'D'], 'final');
});


QUnit.module('sort - concurrency', {
setup() {
obj = EmberObject.extend({
Expand Down

0 comments on commit 965f490

Please sign in to comment.