From: Eduardo San Martin Morote Date: Thu, 31 Mar 2022 17:41:14 +0000 (+0200) Subject: feat(testing): allow overriding computed in tests X-Git-Tag: @pinia/testing@0.0.11~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f4db8264bd61467fa85f2407aedf23756af4b67c;p=thirdparty%2Fvuejs%2Fpinia.git feat(testing): allow overriding computed in tests Close #945 --- 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() + }, + } + }) + } + } +}