From f4db8264bd61467fa85f2407aedf23756af4b67c Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Thu, 31 Mar 2022 19:41:14 +0200 Subject: [PATCH] feat(testing): allow overriding computed in tests Close #945 --- packages/testing/src/testing.spec.ts | 25 ++++++++++++++++ packages/testing/src/testing.ts | 44 +++++++++++++++++++++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/packages/testing/src/testing.spec.ts b/packages/testing/src/testing.spec.ts index d828ae6c..b46ec82e 100644 --- a/packages/testing/src/testing.spec.ts +++ b/packages/testing/src/testing.spec.ts @@ -199,4 +199,29 @@ describe('Testing', () => { b: { n: 0 }, }) }) + + it('allows overriding computed properties', () => { + const useStore = defineStore('lol', { + state: () => ({ n: 0 }), + getters: { + double: (state) => state.n * 2, + }, + }) + const pinia = createTestingPinia() + const store = useStore(pinia) + + store.n++ + expect(store.double).toBe(2) + // once the getter is overridden, it stays + store.double = 3 + expect(store.double).toBe(3) + store.n++ + expect(store.double).toBe(3) + // it can be set to undefined again to reset + // @ts-expect-error + store.double = undefined + expect(store.double).toBe(4) + store.n++ + expect(store.double).toBe(6) + }) }) diff --git a/packages/testing/src/testing.ts b/packages/testing/src/testing.ts index 0eb594cd..adc86d55 100644 --- a/packages/testing/src/testing.ts +++ b/packages/testing/src/testing.ts @@ -1,4 +1,14 @@ -import { App, createApp, isReactive, isRef, isVue2, set } from 'vue-demi' +import { + App, + createApp, + customRef, + isReactive, + isRef, + isVue2, + set, + toRaw, +} from 'vue-demi' +import type { ComputedRef, WritableComputedRef } from 'vue-demi' import { Pinia, PiniaPlugin, @@ -6,6 +16,7 @@ import { createPinia, StateTree, _DeepPartial, + PiniaPluginContext, } from 'pinia' export interface TestingOptions { @@ -94,6 +105,9 @@ export function createTestingPinia({ } }) + // allow computed to be manually overridden + pinia._p.push(WritableComputed) + plugins.forEach((plugin) => pinia.use(plugin)) const createSpy = @@ -175,3 +189,31 @@ function isPlainObject( typeof o.toJSON !== 'function' ) } + +function isComputed( + v: ComputedRef | WritableComputedRef | unknown +): v is ComputedRef | WritableComputedRef { + return !!v && isRef(v) && 'effect' in v +} + +function WritableComputed({ store }: PiniaPluginContext) { + const rawStore = toRaw(store) + for (const key in rawStore) { + const value = rawStore[key] + if (isComputed(value)) { + rawStore[key] = customRef((track, trigger) => { + let internalValue: any + return { + get: () => { + track() + return internalValue !== undefined ? internalValue : value.value + }, + set: (newValue) => { + internalValue = newValue + trigger() + }, + } + }) + } + } +} -- 2.47.2