From fed9cc467f74c5e488380b5bd6b52b8e62e757ca Mon Sep 17 00:00:00 2001 From: Samuel Degueldre Date: Thu, 9 Feb 2023 09:54:16 +0100 Subject: [PATCH] [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. --- src/runtime/reactivity.ts | 13 ++++--- .../__snapshots__/reactivity.test.ts.snap | 36 +++++++++++++++++++ tests/components/reactivity.test.ts | 32 +++++++++++++++++ 3 files changed, 77 insertions(+), 4 deletions(-) diff --git a/src/runtime/reactivity.ts b/src/runtime/reactivity.ts index 7d61f97f..f5e75d2a 100644 --- a/src/runtime/reactivity.ts +++ b/src/runtime/reactivity.ts @@ -162,10 +162,15 @@ export function getSubscriptions(callback: Callback) { const targets = callbacksToTargets.get(callback) || []; return [...targets].map((target) => { const keysToCallbacks = targetToKeysToCallbacks.get(target); - return { - target, - keys: keysToCallbacks ? [...keysToCallbacks.keys()] : [], - }; + let keys = []; + if (keysToCallbacks) { + for (const [key, cbs] of keysToCallbacks) { + if (cbs.has(callback)) { + keys.push(key); + } + } + } + return { target, keys }; }); } // Maps reactive objects to the underlying target diff --git a/tests/components/__snapshots__/reactivity.test.ts.snap b/tests/components/__snapshots__/reactivity.test.ts.snap index 9f8a4962..7b35b2e9 100644 --- a/tests/components/__snapshots__/reactivity.test.ts.snap +++ b/tests/components/__snapshots__/reactivity.test.ts.snap @@ -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); + } +}" +`; diff --git a/tests/components/reactivity.test.ts b/tests/components/reactivity.test.ts index c336aa0a..da1a960c 100644 --- a/tests/components/reactivity.test.ts +++ b/tests/components/reactivity.test.ts @@ -7,6 +7,7 @@ import { onWillUnmount, useState, xml, + toRaw, } from "../../src"; import { makeTestFixture, nextTick, snapshotEverything, useLogLifecycle } from "../helpers"; @@ -232,3 +233,34 @@ describe("reactivity in lifecycle", () => { 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``; + 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``; + setup() { + child = this; + } + } + let child: Child; + class Parent extends Component { + static template = xml``; + 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) }]); + }); +});