diff --git a/store.js b/store.js index 42f17c9bb8..abc2f1886f 100644 --- a/store.js +++ b/store.js @@ -52,26 +52,28 @@ assign(Store.prototype, { var cycles; var visited = blankObject(); - function visit(key) { + function visit(key, rootKey) { + if (visited[key]) return; + if (cycles[key]) { - throw new Error('Cyclical dependency detected'); + throw new Error('Cyclical dependency detected. key: ' + key + ' rootKey: ' + rootKey); } - if (visited[key]) return; - visited[key] = true; - var c = computed[key]; if (c) { cycles[key] = true; - c.deps.forEach(visit); + c.deps.forEach(function(dep) { + visit(dep, rootKey) + }); sorted.push(c); + visited[key] = true; } } for (var key in this._computed) { cycles = blankObject(); - visit(key); + visit(key, key); } }, diff --git a/test/runtime/samples/store-computed-compute-graph/_config.js b/test/runtime/samples/store-computed-compute-graph/_config.js new file mode 100644 index 0000000000..ba7ac02f8d --- /dev/null +++ b/test/runtime/samples/store-computed-compute-graph/_config.js @@ -0,0 +1,22 @@ +import { Store } from '../../../../store.js'; + +const store = new Store(); + +export default { + store, + + test(assert, component, target) { + store.compute('dep4', ['dep1', 'dep2', 'dep3'], (...args) => ['dep4'].concat(...args)); + store.compute('dep1', ['source'], (...args) => ['dep1'].concat(...args)); + store.compute('dep2', ['dep1'], (...args) => ['dep2'].concat(...args)); + store.compute('dep3', ['dep1', 'dep2'], (...args) => ['dep3'].concat(...args)); + store.set({source: 'source'}); + assert.equal(JSON.stringify(store.get().dep4), JSON.stringify([ + 'dep4', + 'dep1', 'source', + 'dep2', 'dep1', 'source', + 'dep3', 'dep1', 'source', + 'dep2', 'dep1', 'source' + ])); + } +}; diff --git a/test/runtime/samples/store-computed-compute-graph/main.html b/test/runtime/samples/store-computed-compute-graph/main.html new file mode 100644 index 0000000000..e69de29bb2