浏览代码

Add assertions of module assets

ktsn 8 年之前
父节点
当前提交
a7a775bb50
共有 2 个文件被更改,包括 132 次插入14 次删除
  1. 42 14
      src/module/module-collection.js
  2. 90 0
      test/unit/modules.spec.js

+ 42 - 14
src/module/module-collection.js

@@ -1,17 +1,10 @@
 import Module from './module'
 import Module from './module'
-import { forEachValue } from '../util'
+import { assert, forEachValue } from '../util'
 
 
 export default class ModuleCollection {
 export default class ModuleCollection {
   constructor (rawRootModule) {
   constructor (rawRootModule) {
     // register root module (Vuex.Store options)
     // register root module (Vuex.Store options)
-    this.root = new Module(rawRootModule, false)
-
-    // register all nested modules
-    if (rawRootModule.modules) {
-      forEachValue(rawRootModule.modules, (rawModule, key) => {
-        this.register([key], rawModule, false)
-      })
-    }
+    this.register([], rawRootModule, false)
   }
   }
 
 
   get (path) {
   get (path) {
@@ -29,13 +22,19 @@ export default class ModuleCollection {
   }
   }
 
 
   update (rawRootModule) {
   update (rawRootModule) {
-    update(this.root, rawRootModule)
+    update([], this.root, rawRootModule)
   }
   }
 
 
   register (path, rawModule, runtime = true) {
   register (path, rawModule, runtime = true) {
-    const parent = this.get(path.slice(0, -1))
+    assertRawModule(path, rawModule)
+
     const newModule = new Module(rawModule, runtime)
     const newModule = new Module(rawModule, runtime)
-    parent.addChild(path[path.length - 1], newModule)
+    if (path.length === 0) {
+      this.root = newModule
+    } else {
+      const parent = this.get(path.slice(0, -1))
+      parent.addChild(path[path.length - 1], newModule)
+    }
 
 
     // register nested modules
     // register nested modules
     if (rawModule.modules) {
     if (rawModule.modules) {
@@ -54,7 +53,9 @@ export default class ModuleCollection {
   }
   }
 }
 }
 
 
-function update (targetModule, newModule) {
+function update (path, targetModule, newModule) {
+  assertRawModule(path, newModule)
+
   // update target module
   // update target module
   targetModule.update(newModule)
   targetModule.update(newModule)
 
 
@@ -68,7 +69,34 @@ function update (targetModule, newModule) {
         )
         )
         return
         return
       }
       }
-      update(targetModule.getChild(key), newModule.modules[key])
+      update(
+        path.concat(key),
+        targetModule.getChild(key),
+        newModule.modules[key]
+      )
     }
     }
   }
   }
 }
 }
+
+function assertRawModule (path, rawModule) {
+  ['getters', 'actions', 'mutations'].forEach(key => {
+    if (!rawModule[key]) return
+
+    forEachValue(rawModule[key], (value, type) => {
+      assert(
+        typeof value === 'function',
+        makeAssertionMessage(path, key, type, value)
+      )
+    })
+  })
+}
+
+function makeAssertionMessage (path, key, type, value) {
+  let buf = `${key} should be function but "${key}.${type}"`
+  if (path.length > 0) {
+    buf += ` in module "${path.join('.')}"`
+  }
+  buf += ` is ${JSON.stringify(value)}.`
+
+  return buf
+}

+ 90 - 0
test/unit/modules.spec.js

@@ -580,4 +580,94 @@ describe('Modules', () => {
       expect(mutations[0].payload).toBe(2)
       expect(mutations[0].payload).toBe(2)
     })
     })
   })
   })
+
+  it('asserts a mutation should be a function', () => {
+    expect(() => {
+      new Vuex.Store({
+        mutations: {
+          test: null
+        }
+      })
+    }).toThrowError(
+      /mutations should be function but "mutations\.test" is null/
+    )
+
+    expect(() => {
+      new Vuex.Store({
+        modules: {
+          foo: {
+            modules: {
+              bar: {
+                mutations: {
+                  test: 123
+                }
+              }
+            }
+          }
+        }
+      })
+    }).toThrowError(
+      /mutations should be function but "mutations\.test" in module "foo\.bar" is 123/
+    )
+  })
+
+  it('asserts an action should be a function', () => {
+    expect(() => {
+      new Vuex.Store({
+        actions: {
+          test: 'test'
+        }
+      })
+    }).toThrowError(
+      /actions should be function but "actions\.test" is "test"/
+    )
+
+    expect(() => {
+      new Vuex.Store({
+        modules: {
+          foo: {
+            modules: {
+              bar: {
+                actions: {
+                  test: 'error'
+                }
+              }
+            }
+          }
+        }
+      })
+    }).toThrowError(
+      /actions should be function but "actions\.test" in module "foo\.bar" is "error"/
+    )
+  })
+
+  it('asserts a getter should be a function', () => {
+    expect(() => {
+      new Vuex.Store({
+        getters: {
+          test: undefined
+        }
+      })
+    }).toThrowError(
+      /getters should be function but "getters\.test" is undefined/
+    )
+
+    expect(() => {
+      new Vuex.Store({
+        modules: {
+          foo: {
+            modules: {
+              bar: {
+                getters: {
+                  test: true
+                }
+              }
+            }
+          }
+        }
+      })
+    }).toThrowError(
+      /getters should be function but "getters\.test" in module "foo\.bar" is true/
+    )
+  })
 })
 })