-
Notifications
You must be signed in to change notification settings - Fork 125
UPDATE for Vue3 ( = vuex 4.x, vue-router 4.x) #100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
783c9e1
update: update vuex & vue-router, resolve migration problem
Spice-Z 155e3e5
update: vue3
Spice-Z 74bcfcd
fix: ref value
Spice-Z 7972050
update: update test except for vue app's content or non exist properties
Spice-Z 8f7c3a7
update: use useStore and fix component definition :wq
Spice-Z 86962d9
fix: comment out meaningless test
Spice-Z 49fe1ff
update: set unsync test
Spice-Z a2106f9
update: dependency
Spice-Z 292bb92
fix: use correct watch option
Spice-Z 3722f77
fix: change to use createMemoryHistory in test
Spice-Z 137bdbe
fix: remove manual types
Spice-Z e6b4d6d
test: add time travel test to increase coverage
kiaking File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,54 +1,64 @@ | ||
import Vue from 'vue' | ||
import Vuex, { mapState } from 'vuex' | ||
import VueRouter from 'vue-router' | ||
import { createApp, defineComponent, h, computed, nextTick } from 'vue' | ||
import { createStore, useStore } from 'vuex' | ||
import { createRouter, createMemoryHistory, RouterView } from 'vue-router' | ||
import { sync } from '@/index' | ||
|
||
Vue.use(Vuex) | ||
Vue.use(VueRouter) | ||
async function run(originalModuleName: string, done: Function): Promise<void> { | ||
const moduleName = originalModuleName || 'route' | ||
|
||
function run(originalModuleName: string, done: Function): void { | ||
const moduleName: string = originalModuleName || 'route' | ||
|
||
const store = new Vuex.Store({ | ||
state: { msg: 'foo' } | ||
const store = createStore({ | ||
state() { | ||
return { msg: 'foo' } | ||
} | ||
}) | ||
|
||
const Home = Vue.extend({ | ||
computed: mapState(moduleName, { | ||
path: (state: any) => state.fullPath, | ||
foo: (state: any) => state.params.foo, | ||
bar: (state: any) => state.params.bar | ||
}), | ||
render(h) { | ||
return h('div', [this.path, ' ', this.foo, ' ', this.bar]) | ||
const Home = defineComponent({ | ||
setup() { | ||
const store = useStore() | ||
const path = computed(() => store.state[moduleName].fullPath) | ||
const foo = computed(() => store.state[moduleName].params.foo) | ||
const bar = computed(() => store.state[moduleName].params.bar) | ||
return () => h('div', [path.value, ' ', foo.value, ' ', bar.value]) | ||
} | ||
}) | ||
|
||
const router = new VueRouter({ | ||
mode: 'abstract', | ||
routes: [{ path: '/:foo/:bar', component: Home }] | ||
const router = createRouter({ | ||
history: createMemoryHistory(), | ||
routes: [ | ||
{ | ||
path: '/', | ||
component: { | ||
template: 'root' | ||
} | ||
}, | ||
{ path: '/:foo/:bar', component: Home } | ||
] | ||
}) | ||
|
||
sync(store, router, { | ||
moduleName: originalModuleName | ||
}) | ||
originalModuleName | ||
? sync(store, router, { moduleName: originalModuleName }) | ||
: sync(store, router) | ||
|
||
router.push('/a/b') | ||
await router.isReady() | ||
expect((store.state as any)[moduleName].fullPath).toBe('/a/b') | ||
expect((store.state as any)[moduleName].params).toEqual({ | ||
foo: 'a', | ||
bar: 'b' | ||
}) | ||
|
||
const app = new Vue({ | ||
store, | ||
router, | ||
render: (h) => h('router-view') | ||
}).$mount() | ||
const rootEl = document.createElement('div') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't it be easier and safer to use vue test utils? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, I will try to use vue test utils! |
||
document.body.appendChild(rootEl) | ||
|
||
expect(app.$el.textContent).toBe('/a/b a b') | ||
const app = createApp({ | ||
render: () => h(RouterView) | ||
}) | ||
app.use(store) | ||
app.use(router) | ||
app.mount(rootEl) | ||
|
||
router.push('/c/d?n=1#hello') | ||
expect(rootEl.textContent).toBe('/a/b a b') | ||
await router.push('/c/d?n=1#hello') | ||
expect((store.state as any)[moduleName].fullPath).toBe('/c/d?n=1#hello') | ||
expect((store.state as any)[moduleName].params).toEqual({ | ||
foo: 'c', | ||
|
@@ -57,49 +67,120 @@ function run(originalModuleName: string, done: Function): void { | |
expect((store.state as any)[moduleName].query).toEqual({ n: '1' }) | ||
expect((store.state as any)[moduleName].hash).toEqual('#hello') | ||
|
||
Vue.nextTick(() => { | ||
expect(app.$el.textContent).toBe('/c/d?n=1#hello c d') | ||
nextTick(() => { | ||
expect(rootEl.textContent).toBe('/c/d?n=1#hello c d') | ||
done() | ||
}) | ||
} | ||
|
||
test('default usage', (done) => { | ||
run('', done) | ||
test('default usage', async (done) => { | ||
await run('', done) | ||
}) | ||
|
||
test('with custom moduleName', (done) => { | ||
run('moduleName', done) | ||
test('with custom moduleName', async (done) => { | ||
await run('moduleName', done) | ||
}) | ||
|
||
test('unsync', (done) => { | ||
const store = new Vuex.Store({}) | ||
test('unsync', async (done) => { | ||
const store = createStore({ | ||
state() { | ||
return { msg: 'foo' } | ||
} | ||
}) | ||
|
||
spyOn(store, 'watch').and.callThrough() | ||
|
||
const router = new VueRouter() | ||
const router = createRouter({ | ||
history: createMemoryHistory(), | ||
routes: [ | ||
{ | ||
path: '/', | ||
component: { | ||
template: 'root' | ||
} | ||
} | ||
] | ||
}) | ||
|
||
const moduleName = 'testDesync' | ||
const unsync = sync(store, router, { | ||
moduleName: moduleName | ||
}) | ||
|
||
expect(unsync).toBeInstanceOf(Function) | ||
|
||
// Test module registered, store watched, router hooked | ||
expect((store as any).state[moduleName]).toBeDefined() | ||
expect((store as any).watch).toHaveBeenCalled() | ||
expect((store as any)._watcherVM).toBeDefined() | ||
expect((store as any)._watcherVM._watchers).toBeDefined() | ||
expect((store as any)._watcherVM._watchers.length).toBe(1) | ||
expect((router as any).afterHooks).toBeDefined() | ||
expect((router as any).afterHooks.length).toBe(1) | ||
|
||
// Now unsync vuex-router-sync | ||
unsync() | ||
|
||
// Ensure router unhooked, store-unwatched, module unregistered | ||
expect((router as any).afterHooks.length).toBe(0) | ||
expect((store as any)._watcherVm).toBeUndefined() | ||
// Ensure module unregistered, no store change | ||
router.push('/') | ||
await router.isReady() | ||
expect((store as any).state[moduleName]).toBeUndefined() | ||
|
||
expect((store as any).state).toEqual({ msg: 'foo' }) | ||
done() | ||
}) | ||
|
||
test('time traveling', async () => { | ||
const store = createStore({ | ||
state() { | ||
return { msg: 'foo' } | ||
} | ||
}) | ||
|
||
const router = createRouter({ | ||
history: createMemoryHistory(), | ||
routes: [ | ||
{ | ||
path: '/', | ||
component: { | ||
template: 'root' | ||
} | ||
}, | ||
{ | ||
path: '/a', | ||
component: { | ||
template: 'a' | ||
} | ||
} | ||
] | ||
}) | ||
|
||
sync(store, router) | ||
|
||
const state1 = clone(store.state) | ||
|
||
// time travel before any route change so that we can test `currentPath` | ||
// being `undefined` | ||
store.replaceState(state1) | ||
|
||
expect((store.state as any).route.path).toBe('/') | ||
|
||
// change route, save new state to time travel later on | ||
await router.push('/a') | ||
|
||
expect((store.state as any).route.path).toBe('/a') | ||
|
||
const state2 = clone(store.state) | ||
|
||
// change route again so that we're on different route than `state2` | ||
await router.push('/') | ||
|
||
expect((store.state as any).route.path).toBe('/') | ||
|
||
// time travel to check we go back to the old route | ||
store.replaceState(state2) | ||
|
||
expect((store.state as any).route.path).toBe('/a') | ||
|
||
// final push to the route to fire `afterEach` hook on router | ||
await router.push('/a') | ||
|
||
expect((store.state as any).route.path).toBe('/a') | ||
}) | ||
|
||
function clone(state: any) { | ||
return JSON.parse(JSON.stringify(state)) | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want to update other dependencies, but that should be other PR to keep it simple...