123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958 |
- import 'babel-polyfill'
- import Vue from 'vue'
- import Vuex, { mapState, mapMutations, mapGetters, mapActions } from '../../dist/vuex.js'
- Vue.use(Vuex)
- const TEST = 'TEST'
- const TEST2 = 'TEST2'
- describe('Vuex', () => {
- it('committing mutations', () => {
- const store = new Vuex.Store({
- state: {
- a: 1
- },
- mutations: {
- [TEST] (state, n) {
- state.a += n
- }
- }
- })
- store.commit(TEST, 2)
- expect(store.state.a).toBe(3)
- })
- it('dispatching actions, sync', () => {
- const store = new Vuex.Store({
- state: {
- a: 1
- },
- mutations: {
- [TEST] (state, n) {
- state.a += n
- }
- },
- actions: {
- [TEST] ({ commit }, n) {
- commit(TEST, n)
- }
- }
- })
- store.dispatch(TEST, 2)
- expect(store.state.a).toBe(3)
- })
- it('dispatching actions, with returned Promise', done => {
- const store = new Vuex.Store({
- state: {
- a: 1
- },
- mutations: {
- [TEST] (state, n) {
- state.a += n
- }
- },
- actions: {
- [TEST] ({ commit }, n) {
- return new Promise(resolve => {
- setTimeout(() => {
- commit(TEST, n)
- resolve()
- }, 0)
- })
- }
- }
- })
- expect(store.state.a).toBe(1)
- store.dispatch(TEST, 2).then(() => {
- expect(store.state.a).toBe(3)
- done()
- })
- })
- it('composing actions with async/await', done => {
- const store = new Vuex.Store({
- state: {
- a: 1
- },
- mutations: {
- [TEST] (state, n) {
- state.a += n
- }
- },
- actions: {
- [TEST] ({ commit }, n) {
- return new Promise(resolve => {
- setTimeout(() => {
- commit(TEST, n)
- resolve()
- }, 0)
- })
- },
- two: async ({ commit, dispatch }, n) => {
- await dispatch(TEST, 1)
- expect(store.state.a).toBe(2)
- commit(TEST, n)
- }
- }
- })
- expect(store.state.a).toBe(1)
- store.dispatch('two', 3).then(() => {
- expect(store.state.a).toBe(5)
- done()
- })
- })
- it('detecting action Promise errors', done => {
- const store = new Vuex.Store({
- actions: {
- [TEST] () {
- return new Promise((resolve, reject) => {
- reject('no')
- })
- }
- }
- })
- const spy = jasmine.createSpy()
- store._devtoolHook = {
- emit: spy
- }
- const thenSpy = jasmine.createSpy()
- store.dispatch(TEST)
- .then(thenSpy)
- .catch(err => {
- expect(thenSpy).not.toHaveBeenCalled()
- expect(err).toBe('no')
- expect(spy).toHaveBeenCalledWith('vuex:error', 'no')
- done()
- })
- })
- it('getters', () => {
- const store = new Vuex.Store({
- state: {
- a: 1
- },
- getters: {
- hasAny: state => state.a > 1
- },
- mutations: {
- [TEST] (state, n) {
- state.a += n
- }
- },
- actions: {
- check ({ getters }, value) {
- // check for exposing getters into actions
- expect(getters.hasAny).toBe(value)
- }
- }
- })
- expect(store.getters.hasAny).toBe(false)
- store.dispatch('check', false)
- store.commit(TEST, 1)
- expect(store.getters.hasAny).toBe(true)
- store.dispatch('check', true)
- })
- it('dynamic module registration', () => {
- const store = new Vuex.Store({
- strict: true,
- modules: {
- foo: {
- state: { bar: 1 },
- mutations: { inc: state => state.bar++ },
- actions: { incFoo: ({ commit }) => commit('inc') },
- getters: { bar: state => state.bar }
- }
- }
- })
- expect(() => {
- store.registerModule('hi', {
- state: { a: 1 },
- mutations: { inc: state => state.a++ },
- actions: { inc: ({ commit }) => commit('inc') },
- getters: { a: state => state.a }
- })
- }).not.toThrow()
- expect(store._mutations.inc.length).toBe(2)
- expect(store.state.hi.a).toBe(1)
- expect(store.getters.a).toBe(1)
- // assert initial modules work as expected after dynamic registration
- expect(store.state.foo.bar).toBe(1)
- expect(store.getters.bar).toBe(1)
- // test dispatching actions defined in dynamic module
- store.dispatch('inc')
- expect(store.state.hi.a).toBe(2)
- expect(store.getters.a).toBe(2)
- expect(store.state.foo.bar).toBe(2)
- expect(store.getters.bar).toBe(2)
- // unregister
- store.unregisterModule('hi')
- expect(store.state.hi).toBeUndefined()
- expect(store.getters.a).toBeUndefined()
- expect(store._mutations.inc.length).toBe(1)
- expect(store._actions.inc).toBeUndefined()
- // assert initial modules still work as expected after unregister
- store.dispatch('incFoo')
- expect(store.state.foo.bar).toBe(3)
- expect(store.getters.bar).toBe(3)
- })
- it('store injection', () => {
- const store = new Vuex.Store()
- const vm = new Vue({
- store
- })
- const child = new Vue({ parent: vm })
- expect(child.$store).toBe(store)
- })
- it('helper: mapState (array)', () => {
- const store = new Vuex.Store({
- state: {
- a: 1
- }
- })
- const vm = new Vue({
- store,
- computed: mapState(['a'])
- })
- expect(vm.a).toBe(1)
- store.state.a++
- expect(vm.a).toBe(2)
- })
- it('helper: mapState (object)', () => {
- const store = new Vuex.Store({
- state: {
- a: 1
- },
- getters: {
- b: () => 2
- }
- })
- const vm = new Vue({
- store,
- computed: mapState({
- a: (state, getters) => {
- return state.a + getters.b
- }
- })
- })
- expect(vm.a).toBe(3)
- store.state.a++
- expect(vm.a).toBe(4)
- })
- it('helper: mapMutations (array)', () => {
- const store = new Vuex.Store({
- state: { count: 0 },
- mutations: {
- inc: state => state.count++,
- dec: state => state.count--
- }
- })
- const vm = new Vue({
- store,
- methods: mapMutations(['inc', 'dec'])
- })
- vm.inc()
- expect(store.state.count).toBe(1)
- vm.dec()
- expect(store.state.count).toBe(0)
- })
- it('helper: mapMutations (object)', () => {
- const store = new Vuex.Store({
- state: { count: 0 },
- mutations: {
- inc: state => state.count++,
- dec: state => state.count--
- }
- })
- const vm = new Vue({
- store,
- methods: mapMutations({
- plus: 'inc',
- minus: 'dec'
- })
- })
- vm.plus()
- expect(store.state.count).toBe(1)
- vm.minus()
- expect(store.state.count).toBe(0)
- })
- it('helper: mapGetters (array)', () => {
- const store = new Vuex.Store({
- state: { count: 0 },
- mutations: {
- inc: state => state.count++,
- dec: state => state.count--
- },
- getters: {
- hasAny: ({ count }) => count > 0,
- negative: ({ count }) => count < 0
- }
- })
- const vm = new Vue({
- store,
- computed: mapGetters(['hasAny', 'negative'])
- })
- expect(vm.hasAny).toBe(false)
- expect(vm.negative).toBe(false)
- store.commit('inc')
- expect(vm.hasAny).toBe(true)
- expect(vm.negative).toBe(false)
- store.commit('dec')
- store.commit('dec')
- expect(vm.hasAny).toBe(false)
- expect(vm.negative).toBe(true)
- })
- it('helper: mapGetters (object)', () => {
- const store = new Vuex.Store({
- state: { count: 0 },
- mutations: {
- inc: state => state.count++,
- dec: state => state.count--
- },
- getters: {
- hasAny: ({ count }) => count > 0,
- negative: ({ count }) => count < 0
- }
- })
- const vm = new Vue({
- store,
- computed: mapGetters({
- a: 'hasAny',
- b: 'negative'
- })
- })
- expect(vm.a).toBe(false)
- expect(vm.b).toBe(false)
- store.commit('inc')
- expect(vm.a).toBe(true)
- expect(vm.b).toBe(false)
- store.commit('dec')
- store.commit('dec')
- expect(vm.a).toBe(false)
- expect(vm.b).toBe(true)
- })
- it('helper: mapActions (array)', () => {
- const a = jasmine.createSpy()
- const b = jasmine.createSpy()
- const store = new Vuex.Store({
- actions: {
- a,
- b
- }
- })
- const vm = new Vue({
- store,
- methods: mapActions(['a', 'b'])
- })
- vm.a()
- expect(a).toHaveBeenCalled()
- expect(b).not.toHaveBeenCalled()
- vm.b()
- expect(b).toHaveBeenCalled()
- })
- it('helper: mapActions (object)', () => {
- const a = jasmine.createSpy()
- const b = jasmine.createSpy()
- const store = new Vuex.Store({
- actions: {
- a,
- b
- }
- })
- const vm = new Vue({
- store,
- methods: mapActions({
- foo: 'a',
- bar: 'b'
- })
- })
- vm.foo()
- expect(a).toHaveBeenCalled()
- expect(b).not.toHaveBeenCalled()
- vm.bar()
- expect(b).toHaveBeenCalled()
- })
- it('module: mutation', function () {
- const mutations = {
- [TEST] (state, n) {
- state.a += n
- }
- }
- const store = new Vuex.Store({
- state: {
- a: 1
- },
- mutations,
- modules: {
- nested: {
- state: { a: 2 },
- mutations,
- modules: {
- one: {
- state: { a: 3 },
- mutations
- },
- nested: {
- modules: {
- two: {
- state: { a: 4 },
- mutations
- },
- three: {
- state: { a: 5 },
- mutations
- }
- }
- }
- }
- },
- four: {
- state: { a: 6 },
- mutations
- }
- }
- })
- store.commit(TEST, 1)
- expect(store.state.a).toBe(2)
- expect(store.state.nested.a).toBe(3)
- expect(store.state.nested.one.a).toBe(4)
- expect(store.state.nested.nested.two.a).toBe(5)
- expect(store.state.nested.nested.three.a).toBe(6)
- expect(store.state.four.a).toBe(7)
- })
- it('module: action', function () {
- let calls = 0
- const makeAction = n => {
- return {
- [TEST] ({ state, rootState }) {
- calls++
- expect(state.a).toBe(n)
- expect(rootState).toBe(store.state)
- }
- }
- }
- const store = new Vuex.Store({
- state: {
- a: 1
- },
- actions: makeAction(1),
- modules: {
- nested: {
- state: { a: 2 },
- actions: makeAction(2),
- modules: {
- one: {
- state: { a: 3 },
- actions: makeAction(3)
- },
- nested: {
- modules: {
- two: {
- state: { a: 4 },
- actions: makeAction(4)
- },
- three: {
- state: { a: 5 },
- actions: makeAction(5)
- }
- }
- }
- }
- },
- four: {
- state: { a: 6 },
- actions: makeAction(6)
- }
- }
- })
- store.dispatch(TEST)
- expect(calls).toBe(6)
- })
- it('module: getters', function () {
- const makeGetter = n => ({
- [`getter${n}`]: (state, getters, rootState) => {
- expect(getters.constant).toBe(0)
- expect(rootState).toBe(store.state)
- return state.a
- }
- })
- const store = new Vuex.Store({
- state: {
- a: 1
- },
- getters: {
- constant: () => 0,
- ...makeGetter(1)
- },
- modules: {
- nested: {
- state: { a: 2 },
- getters: makeGetter(2),
- modules: {
- one: {
- state: { a: 3 },
- getters: makeGetter(3)
- },
- nested: {
- modules: {
- two: {
- state: { a: 4 },
- getters: makeGetter(4)
- },
- three: {
- state: { a: 5 },
- getters: makeGetter(5)
- }
- }
- }
- }
- },
- four: {
- state: { a: 6 },
- getters: makeGetter(6)
- }
- }
- })
- ;[1, 2, 3, 4, 5, 6].forEach(n => {
- expect(store.getters[`getter${n}`]).toBe(n)
- })
- })
- it('dispatching multiple actions in different modules', done => {
- const store = new Vuex.Store({
- modules: {
- a: {
- actions: {
- [TEST] () {
- return 1
- }
- }
- },
- b: {
- actions: {
- [TEST] () {
- return new Promise(r => r(2))
- }
- }
- }
- }
- })
- store.dispatch(TEST).then(res => {
- expect(res[0]).toBe(1)
- expect(res[1]).toBe(2)
- done()
- })
- })
- it('plugins', function () {
- let initState
- const mutations = []
- const store = new Vuex.Store({
- state: {
- a: 1
- },
- mutations: {
- [TEST] (state, n) {
- state.a += n
- }
- },
- plugins: [
- store => {
- initState = store.state
- store.subscribe((mut, state) => {
- expect(state).toBe(store.state)
- mutations.push(mut)
- })
- }
- ]
- })
- expect(initState).toBe(store.state)
- store.commit(TEST, 2)
- expect(mutations.length).toBe(1)
- expect(mutations[0].type).toBe(TEST)
- expect(mutations[0].payload).toBe(2)
- })
- it('plugins should ignore silent mutations', function () {
- let initState
- const mutations = []
- const store = new Vuex.Store({
- state: {
- a: 1
- },
- mutations: {
- [TEST] (state, { n }) {
- state.a += n
- }
- },
- plugins: [
- store => {
- initState = store.state
- store.subscribe((mut, state) => {
- expect(state).toBe(store.state)
- mutations.push(mut)
- })
- }
- ]
- })
- expect(initState).toBe(store.state)
- store.commit(TEST, { n: 1 })
- store.commit({
- type: TEST,
- n: 2
- })
- store.commit(TEST, { n: 3 }, { silent: true })
- store.commit({
- type: TEST,
- n: 4
- }, {
- silent: true
- })
- expect(mutations.length).toBe(2)
- expect(mutations[0].type).toBe(TEST)
- expect(mutations[1].type).toBe(TEST)
- expect(mutations[0].payload.n).toBe(1) // normal dispatch
- expect(mutations[1].n).toBe(2) // object dispatch
- })
- it('strict mode: warn mutations outside of handlers', function () {
- const store = new Vuex.Store({
- state: {
- a: 1
- },
- strict: true
- })
- Vue.config.silent = true
- expect(() => { store.state.a++ }).toThrow()
- Vue.config.silent = false
- })
- it('hot reload: mutations', function () {
- const mutations = {
- [TEST] (state, n) {
- state.a += n
- }
- }
- const store = new Vuex.Store({
- state: {
- a: 1
- },
- mutations,
- modules: {
- nested: {
- state: { a: 2 },
- mutations,
- modules: {
- one: {
- state: { a: 3 },
- mutations
- },
- nested: {
- modules: {
- two: {
- state: { a: 4 },
- mutations
- },
- three: {
- state: { a: 5 },
- mutations
- }
- }
- }
- }
- },
- four: {
- state: { a: 6 },
- mutations
- }
- }
- })
- store.commit(TEST, 1)
- expect(store.state.a).toBe(2)
- expect(store.state.nested.a).toBe(3)
- expect(store.state.nested.one.a).toBe(4)
- expect(store.state.nested.nested.two.a).toBe(5)
- expect(store.state.nested.nested.three.a).toBe(6)
- expect(store.state.four.a).toBe(7)
- // hot reload only root mutations
- store.hotUpdate({
- mutations: {
- [TEST] (state, n) {
- state.a = n
- }
- }
- })
- store.commit(TEST, 1)
- expect(store.state.a).toBe(1) // only root mutation updated
- expect(store.state.nested.a).toBe(4)
- expect(store.state.nested.one.a).toBe(5)
- expect(store.state.nested.nested.two.a).toBe(6)
- expect(store.state.nested.nested.three.a).toBe(7)
- expect(store.state.four.a).toBe(8)
- // hot reload modules
- store.hotUpdate({
- modules: {
- nested: {
- state: { a: 234 },
- mutations,
- modules: {
- one: {
- state: { a: 345 },
- mutations
- },
- nested: {
- modules: {
- two: {
- state: { a: 456 },
- mutations
- },
- three: {
- state: { a: 567 },
- mutations
- }
- }
- }
- }
- },
- four: {
- state: { a: 678 },
- mutations
- }
- }
- })
- store.commit(TEST, 2)
- expect(store.state.a).toBe(2)
- expect(store.state.nested.a).toBe(6) // should not reload initial state
- expect(store.state.nested.one.a).toBe(7) // should not reload initial state
- expect(store.state.nested.nested.two.a).toBe(8) // should not reload initial state
- expect(store.state.nested.nested.three.a).toBe(9) // should not reload initial state
- expect(store.state.four.a).toBe(10) // should not reload initial state
- // hot reload all
- store.hotUpdate({
- mutations: {
- [TEST] (state, n) {
- state.a -= n
- }
- },
- modules: {
- nested: {
- state: { a: 234 },
- mutations: {
- [TEST] (state, n) {
- state.a += n
- }
- },
- modules: {
- one: {
- state: { a: 345 },
- mutations: {
- [TEST] (state, n) {
- state.a += n
- }
- }
- },
- nested: {
- modules: {
- two: {
- state: { a: 456 },
- mutations: {
- [TEST] (state, n) {
- state.a += n
- }
- }
- },
- three: {
- state: { a: 567 },
- mutations: {
- [TEST] (state, n) {
- state.a -= n
- }
- }
- }
- }
- }
- }
- },
- four: {
- state: { a: 678 },
- mutations: {
- [TEST] (state, n) {
- state.a -= n
- }
- }
- }
- }
- })
- store.commit(TEST, 3)
- expect(store.state.a).toBe(-1)
- expect(store.state.nested.a).toBe(9)
- expect(store.state.nested.one.a).toBe(10)
- expect(store.state.nested.nested.two.a).toBe(11)
- expect(store.state.nested.nested.three.a).toBe(6)
- expect(store.state.four.a).toBe(7)
- })
- it('hot reload: actions', () => {
- const store = new Vuex.Store({
- state: {
- list: []
- },
- mutations: {
- [TEST] (state, n) {
- state.list.push(n)
- }
- },
- actions: {
- [TEST] ({ commit }) {
- commit(TEST, 1)
- }
- },
- modules: {
- a: {
- actions: {
- [TEST] ({ commit }) {
- commit(TEST, 2)
- }
- }
- }
- }
- })
- store.dispatch(TEST)
- expect(store.state.list.join()).toBe('1,2')
- // update root
- store.hotUpdate({
- actions: {
- [TEST] ({ commit }) {
- commit(TEST, 3)
- }
- }
- })
- store.dispatch(TEST)
- expect(store.state.list.join()).toBe('1,2,3,2')
- // update modules
- store.hotUpdate({
- actions: {
- [TEST] ({ commit }) {
- commit(TEST, 4)
- }
- },
- modules: {
- a: {
- actions: {
- [TEST] ({ commit }) {
- commit(TEST, 5)
- }
- }
- }
- }
- })
- store.dispatch(TEST)
- expect(store.state.list.join()).toBe('1,2,3,2,4,5')
- })
- it('hot reload: getters', done => {
- const store = new Vuex.Store({
- state: {
- count: 0
- },
- mutations: {
- inc: state => state.count++
- },
- getters: {
- count: state => state.count
- },
- actions: {
- check ({ getters }, value) {
- expect(getters.count).toBe(value)
- }
- }
- })
- const spy = jasmine.createSpy()
- const vm = new Vue({
- computed: {
- a: () => store.getters.count
- },
- watch: {
- a: spy
- }
- })
- expect(vm.a).toBe(0)
- store.dispatch('check', 0)
- store.commit('inc')
- expect(vm.a).toBe(1)
- store.dispatch('check', 1)
- // update getters
- store.hotUpdate({
- getters: {
- count: state => state.count * 10
- }
- })
- expect(vm.a).toBe(10)
- store.dispatch('check', 10)
- Vue.nextTick(() => {
- expect(spy).toHaveBeenCalled()
- done()
- })
- })
- it('watch: with resetting vm', done => {
- const store = new Vuex.Store({
- state: {
- count: 0
- },
- mutations: {
- [TEST]: state => state.count++
- }
- })
- const spy = jasmine.createSpy()
- store.watch(state => state.count, spy)
- // reset store vm
- store.registerModule('test', {})
- Vue.nextTick(() => {
- store.commit(TEST)
- expect(store.state.count).toBe(1)
- Vue.nextTick(() => {
- expect(spy).toHaveBeenCalled()
- done()
- })
- })
- })
- })
|