Skip to content

Commit

Permalink
add hotfix for composing class computed
Browse files Browse the repository at this point in the history
  • Loading branch information
Kelly Selden committed Sep 27, 2017
1 parent 1af377f commit 8c1b022
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 13 deletions.
24 changes: 20 additions & 4 deletions addon/create-class-computed.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,17 +97,27 @@ export default function(observerBools, macroGenerator) {
}

let mappedKeys = [];
let originalKeys = [];

function rewriteComputed(obj, key) {
let mappedWithResolvedOberverKeys = mappedKeys.map((macro, i) => {
function createComputed(keys, context, key) {
let resolvedOberverKeys = keys.map((macro, i) => {
let shouldObserve = observerBools[i];
if (shouldObserve) {
macro = getValue({ context: this, macro, key });
// succeeds with `raw`, fails with everything else
try {
macro = getValue({ context, macro, key });
} catch (err) {
macro = undefined;
}
}
return macro;
});

let cp = macroGenerator.apply(this, mappedWithResolvedOberverKeys);
return macroGenerator.apply(context, resolvedOberverKeys);
}

function rewriteComputed(obj, key) {
let cp = createComputed(mappedKeys, this, key);
defineProperty(this, 'computed', cp);
}

Expand All @@ -121,6 +131,7 @@ export default function(observerBools, macroGenerator) {

let mappedKey = resolveMappedLocation(key, i);

originalKeys.push(key);
mappedKeys.push(mappedKey);
if (shouldObserve) {
classProperties[`key${i}DidChange`] = observer(mappedKey, rewriteComputed);
Expand Down Expand Up @@ -150,6 +161,11 @@ export default function(observerBools, macroGenerator) {
return get(propertyInstance, 'computed');
}).readOnly();

// workaround for watching array and object rewriting properties
// in class computed scope while composing macros
// ex `first(filterBy('arr', 'prop'))`
cp._classComputed = createComputed(originalKeys);

return cp;
};
}
8 changes: 8 additions & 0 deletions addon/flatten-keys.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ function flattenKey(key, flattenedKeys) {
return;
}

// workaround for watching array and object rewriting properties
// in class computed scope while composing macros
// ex `first(filterBy('arr', 'prop'))`
let classComputed = key._classComputed;
if (classComputed) {
dependentKeys = classComputed._dependentKeys;
}

return _flattenKeys(dependentKeys, flattenedKeys);
}

Expand Down
16 changes: 15 additions & 1 deletion tests/acceptance/application-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,23 @@ test('double render failing test', function(assert) {
assert.equal(find('.computed').text(), 'test val 1');
});

click('button');
click('.button');

andThen(function() {
assert.equal(find('.computed').text(), 'test val 2');
});
});

test('class computed array macro inside a normal array macro, handles pushes', function(assert) {
visit('/');

andThen(function() {
assert.equal(find('.computed2').text(), '1');
});

click('.button2');

andThen(function() {
assert.equal(find('.computed2').text(), '3');
});
});
26 changes: 23 additions & 3 deletions tests/dummy/app/controllers/application.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,31 @@
import Controller from '@ember/controller';
import EmberObject, { set } from '@ember/object';
import EmberObject, { get, set } from '@ember/object';
import { A as emberA } from '@ember/array';
import { readOnly } from '@ember/object/computed';
import createClassComputed from 'ember-macro-helpers/create-class-computed';
import computed from 'ember-macro-helpers/computed';
import raw from 'ember-macro-helpers/raw';
import normalizeArrayKey from 'ember-macro-helpers/normalize-array-key';

const getBy = createClassComputed(
[false, true],
(obj, key) => readOnly(`${obj}.${key}`)
);

const filterBy = createClassComputed(
[false, true],
(arr, key, val) => computed(normalizeArrayKey(arr, [key]), val, (arr, val) => arr.filterBy(key, val))
);

export default Controller.extend({
array: emberA([
EmberObject.create({
testProp: 'test val 1'
testProp: 'test val 1',
testProp2: 1
}),
EmberObject.create({
testProp: 'test val 2'
testProp: 'test val 2',
testProp2: 2
})
]),
index: 0,
Expand All @@ -27,9 +36,20 @@ export default Controller.extend({
'testProp'
),

computed2: computed(
filterBy('array', 'testProp', raw('test val 1')),
array => get(array[array.length - 1], 'testProp2')
),

actions: {
update() {
set(this, 'index', 1);
},
update2() {
get(this, 'array').pushObject(EmberObject.create({
testProp: 'test val 1',
testProp2: 3
}));
}
}
});
4 changes: 3 additions & 1 deletion tests/dummy/app/templates/application.hbs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<div class="computed">{{computed}}</div>
<div class="computed2">{{computed2}}</div>

<button {{action "update"}}></button>
<button class="button" {{action "update"}}></button>
<button class="button2" {{action "update2"}}></button>
2 changes: 1 addition & 1 deletion tests/integration/create-class-computed-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module('Integration | create class computed', {
filterBy = createClassComputed(
[false, true],
function(array, key, value) {
if (!key) {
if (!key && this) {
PROPERTIES.set(this, array.split('.').reverse()[0]);
}
return computed(normalizeArrayKey(array, [key]), value, function(array, value) {
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/create-class-computed-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,13 @@ test('it rewrites when observer changes', function(assert) {
}
});

assert.equal(observerCallback.callCount, 2);
assert.equal(observerCallback.callCount, 3);

assert.equal(callback.callCount, 2);

subject.set('test5', 'test6');

assert.equal(observerCallback.callCount, 3);
assert.equal(observerCallback.callCount, 4);

subject.get('computed');

Expand All @@ -157,7 +157,7 @@ test('it rewrites when observer changes', function(assert) {

subject.get('computed');

assert.equal(observerCallback.callCount, 3);
assert.equal(observerCallback.callCount, 4);

assert.equal(callback.callCount, 4);
});
Expand Down

0 comments on commit 8c1b022

Please sign in to comment.