[FIX] reactivity: only show key in subscription if observed by callback

Previously, the getSubscriptions debugging utility returned all observed
keys for a given target, instead of only the keys observed by the
callback it received as argument. This commit fixes that issues.
This commit is contained in:
Samuel Degueldre
2023-02-09 09:54:16 +01:00
committed by Géry Debongnie
parent 33174b301b
commit fed9cc467f
3 changed files with 77 additions and 4 deletions
+9 -4
View File
@@ -162,10 +162,15 @@ export function getSubscriptions(callback: Callback) {
const targets = callbacksToTargets.get(callback) || []; const targets = callbacksToTargets.get(callback) || [];
return [...targets].map((target) => { return [...targets].map((target) => {
const keysToCallbacks = targetToKeysToCallbacks.get(target); const keysToCallbacks = targetToKeysToCallbacks.get(target);
return { let keys = [];
target, if (keysToCallbacks) {
keys: keysToCallbacks ? [...keysToCallbacks.keys()] : [], for (const [key, cbs] of keysToCallbacks) {
}; if (cbs.has(callback)) {
keys.push(key);
}
}
}
return { target, keys };
}); });
} }
// Maps reactive objects to the underlying target // Maps reactive objects to the underlying target
@@ -140,3 +140,39 @@ exports[`reactivity in lifecycle state changes in willUnmount do not trigger rer
} }
}" }"
`; `;
exports[`subscriptions subscriptions returns the keys and targets observed by the component 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(ctx['state'].a);
}
}"
`;
exports[`subscriptions subscriptions returns the keys observed by the component 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
return function template(ctx, node, key = \\"\\") {
const b2 = text(ctx['state'].a);
const b3 = comp1({state: ctx['state']}, key + \`__1\`, node, this, null);
return multi([b2, b3]);
}
}"
`;
exports[`subscriptions subscriptions returns the keys observed by the component 2`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
return function template(ctx, node, key = \\"\\") {
return text(ctx['props'].state.b);
}
}"
`;
+32
View File
@@ -7,6 +7,7 @@ import {
onWillUnmount, onWillUnmount,
useState, useState,
xml, xml,
toRaw,
} from "../../src"; } from "../../src";
import { makeTestFixture, nextTick, snapshotEverything, useLogLifecycle } from "../helpers"; import { makeTestFixture, nextTick, snapshotEverything, useLogLifecycle } from "../helpers";
@@ -232,3 +233,34 @@ describe("reactivity in lifecycle", () => {
expect(fixture.innerHTML).toBe("34"); expect(fixture.innerHTML).toBe("34");
}); });
}); });
describe("subscriptions", () => {
test("subscriptions returns the keys and targets observed by the component", async () => {
class Comp extends Component {
static template = xml`<t t-esc="state.a"/>`;
state = useState({ a: 1, b: 2 });
}
const comp = await mount(Comp, fixture);
expect(fixture.innerHTML).toBe("1");
expect(comp.__owl__.subscriptions).toEqual([{ keys: ["a"], target: toRaw(comp.state) }]);
});
test("subscriptions returns the keys observed by the component", async () => {
class Child extends Component {
static template = xml`<t t-esc="props.state.b"/>`;
setup() {
child = this;
}
}
let child: Child;
class Parent extends Component {
static template = xml`<t t-esc="state.a"/><Child state="state"/>`;
static components = { Child };
state = useState({ a: 1, b: 2 });
}
const parent = await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("12");
expect(parent.__owl__.subscriptions).toEqual([{ keys: ["a"], target: toRaw(parent.state) }]);
expect(child!.__owl__.subscriptions).toEqual([{ keys: ["b"], target: toRaw(parent.state) }]);
});
});