UNPKG

vue-async-everything

Version:

Vue Component Plugin for asynchronous data and computed properties.

428 lines (347 loc) 13.7 kB
import { createLocalVue } from '@vue/test-utils' import VueAsyncProperties from '../src/index.js' import AsyncVuex from '../src/vuex.js' const firstName = 'first' const secondName = 'second' function createVuex(options = {}, asyncGuard = null, asyncStateOptions = {}, asyncGettersOptions = {}) { const localVue = createLocalVue() localVue.use(VueAsyncProperties, { debounce: 5, transform: null, ...options }) localVue.use(AsyncVuex) return new AsyncVuex.Store({ state: { name: firstName, triggerMember: false, triggerCollectionMember: false, guardFlag: false, }, mutations: { setName(state, name) { state.name = name }, setTriggerMember(state, val) { state.triggerMember = val }, setTriggerCollectionMember(state, val) { state.triggerCollectionMember = val }, setGuardFlag(state, val) { state.guardFlag = val }, watchThisMutation(state, val) { state.name += val }, }, actions: { async watchThisAction({ commit }, val) { await delay(5) commit('watchThisMutation', val) } }, asyncGuard, asyncState: { delayName: { get(state, getters) { return delay(5).return(state.name) }, ...asyncStateOptions }, delayCollection: { get(state, getters) { return delay(5).return([1, 2, 3]) }, more(state, getters) { return delay(5).return([4, 5, 6]) }, ...asyncStateOptions } }, asyncGetters: { upperName: { watch: (state, getters) => state.name, get(state, getters) { return delay(5).return(state.name.toUpperCase()) }, ...asyncGettersOptions }, twiceCollection: { watch: (state, getters) => state.triggerCollectionMember, get() { return delay(5).return([2, 4, 6]) }, more() { return delay(5).return([8, 10, 12]) }, ...asyncGettersOptions } } }) } describe("vuex asyncState", function() { it("has the correct base functionality", async function() { const store = createVuex() expect(store.state.name).to.eql(firstName) expect(store.state.delayName).to.eql(null) expect(store.state.delayName$loading).to.eql(true) await Vue.nextTick() await delay(6) expect(store.state.delayName).to.eql(firstName) expect(store.state.delayName$loading).to.eql(false) // doesn't respond to changes store.commit('setName', secondName) expect(store.state.name).to.eql(secondName) expect(store.state.delayName).to.eql(firstName) expect(store.state.delayName$loading).to.eql(false) await Vue.nextTick() await delay(6) expect(store.state.delayName).to.eql(firstName) // but we can refresh it const dispatchPromise = store.dispatch('delayName$refresh') expect(store.state.delayName).to.eql(firstName) expect(store.state.delayName$loading).to.eql(true) await Vue.nextTick() await delay(6) await dispatchPromise expect(store.state.delayName).to.eql(secondName) expect(store.state.delayName$loading).to.eql(false) }) it("waits for a guard", async function() { const store = createVuex(undefined, (state, getters) => state.guardFlag) expect(store.state.name).to.eql(firstName) expect(store.state.delayName).to.eql(null) expect(store.state.delayName$loading).to.eql(false) await Vue.nextTick() await delay(6) expect(store.state.delayName).to.eql(null) expect(store.state.delayName$loading).to.eql(false) store.commit('setGuardFlag', true) expect(store.state.guardFlag).to.eql(true) await Vue.nextTick() expect(store.state.delayName).to.eql(null) // expect(store.state.delayName$loading).to.eql(true) await Vue.nextTick() await delay(6) expect(store.state.delayName).to.eql(firstName) expect(store.state.delayName$loading).to.eql(false) }) it("can load more", async function() { const store = createVuex() expect(store.state.delayCollection).to.eql(null) expect(store.state.delayCollection$loading).to.eql(true) await Vue.nextTick() await delay(6) expect(store.state.delayCollection).to.eql([1, 2, 3]) expect(store.state.delayCollection$loading).to.eql(false) const morePromise = store.dispatch('delayCollection$more') expect(store.state.delayCollection).to.eql([1, 2, 3]) expect(store.state.delayCollection$loading).to.eql(true) await Vue.nextTick() await delay(6) const lastResult = await morePromise expect(lastResult).to.eql([4, 5, 6]) expect(store.state.delayCollection).to.eql([1, 2, 3, 4, 5, 6]) expect(store.state.delayCollection$loading).to.eql(false) }) it("respects lazy", async function() { const store = createVuex(undefined, undefined, { lazy: true }) expect(store.state.name).to.eql(firstName) expect(store.state.delayName).to.eql(null) expect(store.state.delayName$loading).to.eql(false) await Vue.nextTick() await delay(6) expect(store.state.delayName).to.eql(null) expect(store.state.delayName$loading).to.eql(false) const dispatchPromise = store.dispatch('delayName$refresh') expect(store.state.delayName).to.eql(null) expect(store.state.delayName$loading).to.eql(true) await Vue.nextTick() await delay(6) await dispatchPromise expect(store.state.delayName).to.eql(firstName) expect(store.state.delayName$loading).to.eql(false) }) }) describe("vuex asyncGetters", function() { it("has the correct base functionality", async function() { const store = createVuex() expect(store.state.name).to.eql(firstName) expect(store.state.upperName).to.eql(null) expect(store.state.upperName$pending).to.eql(false) expect(store.state.upperName$loading).to.eql(false) await Vue.nextTick() expect(store.state.upperName).to.eql(null) expect(store.state.upperName$pending).to.eql(false) expect(store.state.upperName$loading).to.eql(false) store.commit('setName', secondName) expect(store.state.name).to.eql(secondName) await Vue.nextTick() // pending after change expect(store.state.upperName).to.eql(null) expect(store.state.upperName$pending).to.eql(true) expect(store.state.upperName$loading).to.eql(false) await Vue.nextTick() await delay(6) // loading after pending expect(store.state.upperName).to.eql(null) expect(store.state.upperName$pending).to.eql(false) expect(store.state.upperName$loading).to.eql(true) await Vue.nextTick() await delay(6) // done expect(store.state.upperName).to.eql(secondName.toUpperCase()) expect(store.state.upperName$pending).to.eql(false) expect(store.state.upperName$loading).to.eql(false) }) it("responds immediately to watchClosely", async function() { const store = createVuex(undefined, undefined, undefined, { watchClosely: (state) => state.triggerMember }) expect(store.state.name).to.eql(firstName) expect(store.state.upperName).to.eql(null) expect(store.state.upperName$pending).to.eql(false) expect(store.state.upperName$loading).to.eql(false) store.commit('setTriggerMember', true) expect(store.state.triggerMember).to.eql(true) await Vue.nextTick() expect(store.state.upperName).to.eql(null) expect(store.state.upperName$pending).to.eql(false) expect(store.state.upperName$loading).to.eql(true) await Vue.nextTick() await delay(6) expect(store.state.upperName).to.eql(firstName.toUpperCase()) expect(store.state.upperName$pending).to.eql(false) expect(store.state.upperName$loading).to.eql(false) }) it("responds to mutations and actions", async function() { const watchAppend = 'watchAppend' const mutationStore = createVuex(undefined, undefined, undefined, { watch: 'watchThisMutation' }) expect(mutationStore.state.name).to.eql(firstName) expect(mutationStore.state.upperName).to.eql(null) expect(mutationStore.state.upperName$pending).to.eql(false) expect(mutationStore.state.upperName$loading).to.eql(false) mutationStore.commit('setName', secondName) expect(mutationStore.state.name).to.eql(secondName) await Vue.nextTick() expect(mutationStore.state.upperName).to.eql(null) expect(mutationStore.state.upperName$pending).to.eql(false) expect(mutationStore.state.upperName$loading).to.eql(false) mutationStore.commit('watchThisMutation', watchAppend) expect(mutationStore.state.name).to.eql(secondName + watchAppend) await Vue.nextTick() expect(mutationStore.state.upperName).to.eql(null) expect(mutationStore.state.upperName$pending).to.eql(true) expect(mutationStore.state.upperName$loading).to.eql(false) await Vue.nextTick() await delay(6) expect(mutationStore.state.upperName).to.eql(null) expect(mutationStore.state.upperName$pending).to.eql(false) expect(mutationStore.state.upperName$loading).to.eql(true) await Vue.nextTick() await delay(6) expect(mutationStore.state.upperName).to.eql((secondName + watchAppend).toUpperCase()) expect(mutationStore.state.upperName$pending).to.eql(false) expect(mutationStore.state.upperName$loading).to.eql(false) const actionStore = createVuex(undefined, undefined, undefined, { watch: 'watchThisAction' }) expect(actionStore.state.name).to.eql(firstName) expect(actionStore.state.upperName).to.eql(null) expect(actionStore.state.upperName$pending).to.eql(false) expect(actionStore.state.upperName$loading).to.eql(false) actionStore.commit('setName', secondName) expect(actionStore.state.name).to.eql(secondName) await Vue.nextTick() expect(actionStore.state.upperName).to.eql(null) expect(actionStore.state.upperName$pending).to.eql(false) expect(actionStore.state.upperName$loading).to.eql(false) actionStore.dispatch('watchThisAction', watchAppend) expect(actionStore.state.name).to.eql(secondName) await Vue.nextTick() expect(actionStore.state.name).to.eql(secondName) expect(actionStore.state.upperName).to.eql(null) expect(actionStore.state.upperName$pending).to.eql(true) expect(actionStore.state.upperName$loading).to.eql(false) await Vue.nextTick() await delay(6) expect(actionStore.state.name).to.eql(secondName + watchAppend) expect(actionStore.state.upperName).to.eql(null) expect(actionStore.state.upperName$pending).to.eql(false) expect(actionStore.state.upperName$loading).to.eql(true) await Vue.nextTick() await delay(6) // since the givenFunction is called at the beginning of the action instead of after it, // this receives the state value at the beginning expect(actionStore.state.upperName).to.eql(secondName.toUpperCase()) expect(actionStore.state.upperName$pending).to.eql(false) expect(actionStore.state.upperName$loading).to.eql(false) }) it("waits for a guard", async function() { const store = createVuex(undefined, (state, getters) => state.guardFlag) expect(store.state.name).to.eql(firstName) expect(store.state.upperName).to.eql(null) expect(store.state.upperName$pending).to.eql(false) expect(store.state.upperName$loading).to.eql(false) await Vue.nextTick() await delay(6) expect(store.state.upperName).to.eql(null) expect(store.state.upperName$pending).to.eql(false) expect(store.state.upperName$loading).to.eql(false) store.commit('setName', secondName) expect(store.state.name).to.eql(secondName) await Vue.nextTick() // the guard isn't satisfied yet expect(store.state.upperName).to.eql(null) expect(store.state.upperName$pending).to.eql(false) expect(store.state.upperName$loading).to.eql(false) store.commit('setGuardFlag', true) await Vue.nextTick() expect(store.state.upperName).to.eql(null) expect(store.state.upperName$pending).to.eql(true) expect(store.state.upperName$loading).to.eql(false) await Vue.nextTick() await delay(6) expect(store.state.upperName).to.eql(null) expect(store.state.upperName$pending).to.eql(false) expect(store.state.upperName$loading).to.eql(true) await Vue.nextTick() await delay(6) expect(store.state.upperName).to.eql(secondName.toUpperCase()) expect(store.state.upperName$pending).to.eql(false) expect(store.state.upperName$loading).to.eql(false) }) it("can load more", async function() { const store = createVuex() store.commit('setTriggerCollectionMember', true) expect(store.state.triggerCollectionMember).to.eql(true) await Vue.nextTick() expect(store.state.twiceCollection).to.eql(null) expect(store.state.twiceCollection$pending).to.eql(true) expect(store.state.twiceCollection$loading).to.eql(false) await Vue.nextTick() await delay(6) expect(store.state.twiceCollection).to.eql(null) expect(store.state.twiceCollection$pending).to.eql(false) expect(store.state.twiceCollection$loading).to.eql(true) await Vue.nextTick() await delay(6) expect(store.state.twiceCollection).to.eql([2, 4, 6]) expect(store.state.twiceCollection$pending).to.eql(false) expect(store.state.twiceCollection$loading).to.eql(false) const morePromise = store.dispatch('twiceCollection$more') expect(store.state.twiceCollection).to.eql([2, 4, 6]) expect(store.state.twiceCollection$loading).to.eql(true) await Vue.nextTick() await delay(6) const lastResult = await morePromise expect(lastResult).to.eql([8, 10, 12]) expect(store.state.twiceCollection).to.eql([2, 4, 6, 8, 10, 12]) expect(store.state.twiceCollection$loading).to.eql(false) }) it("respects eager", async function() { const store = createVuex(undefined, undefined, undefined, { eager: true }) expect(store.state.name).to.eql(firstName) expect(store.state.upperName).to.eql(null) expect(store.state.upperName$pending).to.eql(false) expect(store.state.upperName$loading).to.eql(true) await Vue.nextTick() await delay(6) expect(store.state.upperName).to.eql(firstName.toUpperCase()) expect(store.state.upperName$pending).to.eql(false) expect(store.state.upperName$loading).to.eql(false) }) })