From 82490070b5501c8cfec62f1a3761855f8df16e26 Mon Sep 17 00:00:00 2001 From: kazuya kawaguchi Date: Thu, 24 Aug 2023 17:37:33 +0900 Subject: [PATCH] fix: regression local composer extending --- packages/vue-i18n-routing/scripts/vitest.ts | 7 ++- .../src/__test__/compatibles.test.ts | 16 ++--- .../src/composables/__test__/head.test.ts | 4 +- .../src/composables/__test__/routing.test.ts | 16 ++--- .../src/extends/__test__/i18n.test.ts | 61 +++++++++++++++++-- packages/vue-i18n-routing/src/extends/i18n.ts | 2 +- 6 files changed, 79 insertions(+), 27 deletions(-) diff --git a/packages/vue-i18n-routing/scripts/vitest.ts b/packages/vue-i18n-routing/scripts/vitest.ts index 08f0321..c2ad738 100644 --- a/packages/vue-i18n-routing/scripts/vitest.ts +++ b/packages/vue-i18n-routing/scripts/vitest.ts @@ -6,13 +6,14 @@ import type { InjectionKey, Ref } from 'vue-demi' type InstanceType = V extends { new (...arg: any[]): infer X } ? X : never type VM = InstanceType & { unmount(): void } +type Plugins = [...any] -export function mount(Comp: V, plugins: any[] = []) { +export function mount(Comp: V, plugins: Plugins[] = []) { const el = document.createElement('div') const app = createApp(Comp as any) for (const plugin of plugins) { - app.use(plugin) + app.use(plugin[0], plugin[1]) } // @ts-ignore @@ -22,7 +23,7 @@ export function mount(Comp: V, plugins: any[] = []) { return comp } -export function useSetup(setup: () => V, plugins: any[] = []) { +export function useSetup(setup: () => V, plugins: Plugins[] = []) { const Comp = defineComponent({ setup, render() { diff --git a/packages/vue-i18n-routing/src/__test__/compatibles.test.ts b/packages/vue-i18n-routing/src/__test__/compatibles.test.ts index 170a594..6cd8284 100644 --- a/packages/vue-i18n-routing/src/__test__/compatibles.test.ts +++ b/packages/vue-i18n-routing/src/__test__/compatibles.test.ts @@ -30,7 +30,7 @@ describe('getRouteBaseName', () => { history: createMemoryHistory() }) await router.push('/en') - const vm = useSetup(() => {}, [router, i18n]) as any // FIXME: + const vm = useSetup(() => {}, [[router], [i18n]]) as any // FIXME: const name = vm.getRouteBaseName() assert.equal(name, 'home') }) @@ -54,7 +54,7 @@ describe('getRouteBaseName', () => { history: createMemoryHistory() }) await router.push('/en') - const vm = useSetup(() => {}, [router, i18n]) as any // FIXME: + const vm = useSetup(() => {}, [[router], [i18n]]) as any // FIXME: const name = vm.getRouteBaseName() assert.equal(name, 'home') }) @@ -81,7 +81,7 @@ describe('localePath', () => { history: createMemoryHistory() }) await router.push('/en') - const vm = useSetup(() => {}, [router, i18n]) as any // FIXME: + const vm = useSetup(() => {}, [[router], [i18n]]) as any // FIXME: // path assert.equal(vm.localePath('/'), '/en') @@ -136,7 +136,7 @@ describe('localePath', () => { history: createMemoryHistory() }) await router.push('/') - const vm = useSetup(() => {}, [router, i18n]) as any // FIXME: + const vm = useSetup(() => {}, [[router], [i18n]]) as any // FIXME: // path assert.equal(vm.localePath('/'), '/') @@ -189,7 +189,7 @@ describe('localeRoute', () => { history: createMemoryHistory() }) await router.push('/en') - const vm = useSetup(() => {}, [router, i18n]) as any // FIXME: + const vm = useSetup(() => {}, [[router], [i18n]]) as any // FIXME: // path assert.include(vm.localeRoute('/'), { @@ -286,7 +286,7 @@ describe('localeLocation', () => { history: createMemoryHistory() }) await router.push('/en') - const vm = useSetup(() => {}, [router, i18n]) as any // FIXME: + const vm = useSetup(() => {}, [[router], [i18n]]) as any // FIXME: // path assert.include(vm.localeLocation('/'), { @@ -408,7 +408,7 @@ describe('switchLocalePath', () => { history: createMemoryHistory() }) await router.push('/en/about') - const vm = useSetup(() => {}, [router, i18n]) as any // FIXME: + const vm = useSetup(() => {}, [[router], [i18n]]) as any // FIXME: await router.push('/ja') assert.equal(vm.switchLocalePath('ja'), '/ja') @@ -482,7 +482,7 @@ describe('localeHead', () => { history: createMemoryHistory() }) await router.push('/en/about') - const vm = useSetup(() => {}, [router, i18n]) as any // FIXME: + const vm = useSetup(() => {}, [[router], [i18n]]) as any // FIXME: let head = vm.localeHead({ addDirAttribute: true, addSeoAttributes: true }) expect(head).toMatchSnapshot('en') diff --git a/packages/vue-i18n-routing/src/composables/__test__/head.test.ts b/packages/vue-i18n-routing/src/composables/__test__/head.test.ts index c11d78e..2093b26 100644 --- a/packages/vue-i18n-routing/src/composables/__test__/head.test.ts +++ b/packages/vue-i18n-routing/src/composables/__test__/head.test.ts @@ -44,7 +44,7 @@ describe('useLocaleHead', () => { i18n, head } - }, [router, i18n]) + }, [[router], [i18n]]) await router.push('/ja') expect(vm.head).toMatchSnapshot(vm.i18n.locale.value) @@ -87,7 +87,7 @@ describe('useLocaleHead', () => { i18n, head } - }, [router, i18n]) + }, [[router], [i18n]]) await router.push('/ja') for (const m of vm.head.meta || []) { diff --git a/packages/vue-i18n-routing/src/composables/__test__/routing.test.ts b/packages/vue-i18n-routing/src/composables/__test__/routing.test.ts index 9f2a8aa..485785f 100644 --- a/packages/vue-i18n-routing/src/composables/__test__/routing.test.ts +++ b/packages/vue-i18n-routing/src/composables/__test__/routing.test.ts @@ -33,7 +33,7 @@ describe('useRouteBaseName', () => { const getRouteBaseName = useRouteBaseName() const name = getRouteBaseName(route) assert.equal(name, 'home') - }, [router, i18n]) + }, [[router], [i18n]]) }) }) @@ -59,7 +59,7 @@ describe('useRouteBaseName', () => { const getRouteBaseName = useRouteBaseName() const name = getRouteBaseName({} as Route) assert.equal(name, null) - }, [router, i18n]) + }, [[router], [i18n]]) }) }) @@ -87,7 +87,7 @@ describe('useRouteBaseName', () => { const getRouteBaseName = useRouteBaseName({ route, routesNameSeparator: '---' }) const name = getRouteBaseName() assert.equal(name, 'home') - }, [router, i18n]) + }, [[router], [i18n]]) }) }) }) @@ -122,7 +122,7 @@ describe('useLocalePath', () => { assert.equal(localePath('not-found'), '/en') // object assert.equal(localePath({ name: 'about' }, 'ja'), '/ja/about') - }, [router, i18n]) + }, [[router], [i18n]]) }) }) }) @@ -155,7 +155,7 @@ describe('useLocalePath', () => { assert.equal(localePath('not-found'), '/') // object assert.equal(localePath({ name: 'about' }, 'ja'), '/about') - }, [router, i18n]) + }, [[router], [i18n]]) }) }) }) @@ -229,7 +229,7 @@ describe('useLocaleRoute', () => { name: 'about___ja', href: '/ja/about' }) - }, [router, i18n]) + }, [[router], [i18n]]) }) }) @@ -302,7 +302,7 @@ describe('useLocaleLocation', () => { name: 'about___ja', href: '/ja/about' }) - }, [router, i18n]) + }, [[router], [i18n]]) }) }) @@ -333,7 +333,7 @@ describe('useSwitchLocalePath', () => { return { switchLocalePath: change } - }, [router, i18n]) + }, [[router], [i18n]]) await router.push('/ja') assert.equal(vm.switchLocalePath('ja'), '/ja') diff --git a/packages/vue-i18n-routing/src/extends/__test__/i18n.test.ts b/packages/vue-i18n-routing/src/extends/__test__/i18n.test.ts index d4887d6..571bc97 100644 --- a/packages/vue-i18n-routing/src/extends/__test__/i18n.test.ts +++ b/packages/vue-i18n-routing/src/extends/__test__/i18n.test.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { createI18n } from '@intlify/vue-i18n-bridge' +import { createI18n, useI18n } from '@intlify/vue-i18n-bridge' import { vi, describe, it, assert, expect } from 'vitest' import { ref, nextTick } from 'vue-demi' @@ -19,7 +19,7 @@ describe('extendI18n', () => { localeCodes: ['en', 'ja'] }) - const vm = useSetup(() => {}, [i18n]) + const vm = useSetup(() => {}, [[i18n]]) const composer = i18n.global as unknown as Composer assert.deepEqual(composer.locales.value, [{ code: 'en' }, { code: 'ja' }]) assert.deepEqual(composer.localeCodes.value, ['en', 'ja']) @@ -36,7 +36,7 @@ describe('extendI18n', () => { localeCodes: ['en', 'ja'] }) - const vm = useSetup(() => {}, [i18n]) + const vm = useSetup(() => {}, [[i18n]]) const vueI18n = i18n.global as unknown as VueI18n assert.deepEqual(vueI18n.locales, [{ code: 'en' }, { code: 'ja' }]) assert.deepEqual(vueI18n.localeCodes, ['en', 'ja']) @@ -69,7 +69,7 @@ describe('extendI18n', () => { } } }) - const vm = useSetup(() => {}, [i18n]) + const vm = useSetup(() => {}, [[i18n]]) const $i18n = (vm as any).$i18n const composer = i18n.global as unknown as Composer @@ -119,7 +119,7 @@ describe('extendI18n', () => { } } }) - const vm = useSetup(() => {}, [i18n]) + const vm = useSetup(() => {}, [[i18n]]) const $i18n = (vm as any).$i18n const vueI18n = i18n.global as unknown as VueI18n @@ -134,6 +134,57 @@ describe('extendI18n', () => { }) }) }) + + describe('__composerExtend include in plugin options', () => { + test('should be extended', async () => { + const extendFn = vi.fn() + const disposeFn = vi.fn() + + const i18n = createI18n({ legacy: false, globalInjection: true, locale: 'en' }) + extendI18n(i18n, { + locales: [{ code: 'en' }, { code: 'ja' }], + localeCodes: ['en', 'ja'], + hooks: { + onExtendComposer(composer: Composer) { + ;(composer as any).fn = extendFn + }, + onExtendExportedGlobal(g) { + return { + fn: { + get() { + return (g as any).fn + } + } + } + } + } + }) + const pluginOptions = { + __composerExtend: (c: Composer) => { + ;(c as any).fn = (i18n.global as any).fn + return disposeFn + } + } + const vm = useSetup(() => { + const i18n = useI18n({ + useScope: 'local' + }) + ;(i18n as any).fn() + return {} + }, [[i18n, pluginOptions]]) + const $i18n = (vm as any).$i18n + const composer = i18n.global as any + + $i18n.fn() + composer.fn() + + await nextTick() + expect(extendFn).toHaveBeenCalledTimes(3) + + vm.unmount() + expect(disposeFn).toBeCalledTimes(1) + }) + }) }) /* eslint-enable @typescript-eslint/no-explicit-any */ diff --git a/packages/vue-i18n-routing/src/extends/i18n.ts b/packages/vue-i18n-routing/src/extends/i18n.ts index ac5a2d6..80eace6 100644 --- a/packages/vue-i18n-routing/src/extends/i18n.ts +++ b/packages/vue-i18n-routing/src/extends/i18n.ts @@ -110,7 +110,7 @@ export function extendI18n( localComposer.baseUrl = computed(() => globalComposer.baseUrl.value) let orgComposerDispose: Disposer | undefined if (isFunction(orgComposerExtend)) { - orgComposerDispose = Reflect.apply(orgComposerExtend, pluginOptions, [globalComposer]) + orgComposerDispose = Reflect.apply(orgComposerExtend, pluginOptions, [localComposer]) } return () => { orgComposerDispose && orgComposerDispose()