From: Eduardo San Martin Morote Date: Fri, 7 Apr 2023 12:36:01 +0000 (+0200) Subject: fix(testing): override computed in setup stores X-Git-Tag: @pinia/nuxt@0.4.8~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f9534c926469027f8ccc75c43ce1ea329b58aa0d;p=thirdparty%2Fvuejs%2Fpinia.git fix(testing): override computed in setup stores Fix #2109 --- diff --git a/packages/testing/src/testing.spec.ts b/packages/testing/src/testing.spec.ts index 6a3f2af2..307cc901 100644 --- a/packages/testing/src/testing.spec.ts +++ b/packages/testing/src/testing.spec.ts @@ -226,6 +226,40 @@ describe('Testing', () => { expect(store.double).toBe(6) }) + it('allows overriding computed properties in setup stores', () => { + const useStore = defineStore('computed', () => { + const n = ref(0) + const double = computed(() => n.value * 2) + const doublePlusOne = computed(() => double.value + 1) + return { n, double, doublePlusOne } + }) + const pinia = createTestingPinia() + const store = useStore(pinia) + + // console.log('is same', d === toRaw(store).double._computed) + + store.n++ + expect(store.double).toBe(2) + // once the getter is overridden, it stays + store.double = 3 + expect(store.double).toBe(3) + expect(store.doublePlusOne).toBe(4) + store.n++ + expect(store.double).toBe(3) + expect(store.doublePlusOne).toBe(4) + // it can be set to undefined again to reset + // @ts-expect-error + store.double = undefined + expect(store.n).toBe(2) + expect(store.double).toBe(4) + expect(store.doublePlusOne).toBe(5) + // it works again + store.n++ + expect(store.n).toBe(3) + expect(store.double).toBe(6) + expect(store.doublePlusOne).toBe(7) + }) + it('actions are stubbed even when replaced by other plugins', () => { const spy = vi.fn() mount(Counter, { diff --git a/packages/testing/src/testing.ts b/packages/testing/src/testing.ts index bdb4e47f..b709bb6b 100644 --- a/packages/testing/src/testing.ts +++ b/packages/testing/src/testing.ts @@ -7,6 +7,7 @@ import { isVue2, set, toRaw, + triggerRef, } from 'vue-demi' import type { ComputedRef, WritableComputedRef } from 'vue-demi' import { @@ -205,17 +206,35 @@ function isComputed( function WritableComputed({ store }: PiniaPluginContext) { const rawStore = toRaw(store) for (const key in rawStore) { - const value = rawStore[key] - if (isComputed(value)) { + const originalComputed = rawStore[key] + if (isComputed(originalComputed)) { + const originalFn = originalComputed.effect.fn rawStore[key] = customRef((track, trigger) => { - let internalValue: any + // override the computed with a new one + const overriddenFn = () => + // @ts-expect-error: internal value + originalComputed._value + // originalComputed.effect.fn = overriddenFn return { get: () => { track() - return internalValue !== undefined ? internalValue : value.value + return originalComputed.value }, set: (newValue) => { - internalValue = newValue + // reset the computed to its original value by setting it to its initial state + if (newValue === undefined) { + originalComputed.effect.fn = originalFn + // @ts-expect-error: private api to remove the current cached value + delete originalComputed._value + // @ts-expect-error: private api to force the recomputation + originalComputed._dirty = true + } else { + originalComputed.effect.fn = overriddenFn + // @ts-expect-error: private api + originalComputed._value = newValue + } + // this allows to trigger the original computed in setup stores + triggerRef(originalComputed) trigger() }, }