Procházet zdrojové kódy

coverage improvements

Evan You před 10 roky
rodič
revize
366188fbde

+ 4 - 0
src/compiler/parser/index.js

@@ -68,7 +68,9 @@ export function parse (
       // check namespace.
       // inherit parent ns if there is one
       const ns = (currentParent && currentParent.ns) || platformGetTagNamespace(tag)
+
       // handle IE svg bug
+      /* istanbul ignore if */
       if (options.isIE && ns === 'svg') {
         attrs = guardIESVGBug(attrs)
       }
@@ -402,6 +404,8 @@ function isForbiddenTag (el): boolean {
 
 const ieNSBug = /^xmlns:NS\d+/
 const ieNSPrefix = /^NS\d+:/
+
+/* istanbul ignore next */
 function guardIESVGBug (attrs) {
   const res = []
   for (let i = 0; i < attrs.length; i++) {

+ 5 - 0
src/core/config.js

@@ -33,6 +33,11 @@ const config: Config = {
    */
   silent: false,
 
+  /**
+   * Error handler for watcher errors
+   */
+  watcherErrorHandler: null,
+
   /**
    * Check if a tag is reserved so that it cannot be registered as a
    * component. This is platform-dependent and may be overwritten.

+ 5 - 1
src/core/observer/watcher.js

@@ -1,5 +1,6 @@
 /* @flow */
 
+import config from '../config'
 import Dep from './dep'
 import { queueWatcher } from './scheduler'
 import {
@@ -14,6 +15,9 @@ import {
 let uid = 0
 let prevTarget
 
+/* istanbul ignore next */
+const defaultErrorHandler = e => nextTick(() => { throw e })
+
 /**
  * A watcher parses an expression, collects dependencies,
  * and fires callback when the expression value changes.
@@ -99,7 +103,7 @@ export default class Watcher {
           )
         }
         // throw the error on next tick so that it doesn't break the whole app
-        nextTick(() => { throw e })
+        ;(config.watcherErrorHandler || defaultErrorHandler)(e, this.vm)
       }
       // return old value when evaluation fails so the current UI is preserved
       value = this.value

+ 9 - 0
test/unit/features/global-api/extend.spec.js

@@ -113,4 +113,13 @@ describe('Global API: extend', () => {
     }).$mount()
     expect(b.$el.innerHTML).toBe('<div>A</div><div>B</div>')
   })
+
+  it('caching', () => {
+    const options = {
+      template: '<div></div>'
+    }
+    const A = Vue.extend(options)
+    const B = Vue.extend(options)
+    expect(A).toBe(B)
+  })
 })

+ 15 - 0
test/unit/features/transition/transition.spec.js

@@ -436,6 +436,21 @@ if (!isIE9) {
       }).then(done)
     })
 
+    it('transition on appear with v-show', done => {
+      const vm = new Vue({
+        template: '<div><div v-show="ok" class="test" transition="test" transition-on-appear>foo</div></div>',
+        data: { ok: true }
+      }).$mount(el)
+
+      waitForUpdate(() => {
+        expect(vm.$el.children[0].className).toBe('test test-enter')
+      }).thenWaitFor(nextFrame).then(() => {
+        expect(vm.$el.children[0].className).toBe('test test-enter-active')
+      }).thenWaitFor(timeout(duration + 10)).then(() => {
+        expect(vm.$el.children[0].className).toBe('test')
+      }).then(done)
+    })
+
     it('transition on SVG elements', done => {
       const vm = new Vue({
         template: '<svg><circle cx="0" cy="0" r="10" v-if="ok" class="test" transition></circle></svg>',

+ 21 - 0
test/unit/modules/observer/watcher.spec.js

@@ -197,4 +197,25 @@ describe('Watcher', () => {
     new Watcher(vm, 'd.e + c', spy)
     expect('Failed watching path:').toHaveBeenWarned()
   })
+
+  it('catch getter error', () => {
+    Vue.config.watcherErrorHandler = spy
+    const err = new Error()
+    const vm = new Vue({
+      render () { throw err }
+    }).$mount()
+    expect('Error during component render').toHaveBeenWarned()
+    expect(spy).toHaveBeenCalledWith(err, vm)
+  })
+
+  it('catch user watcher error', () => {
+    Vue.config.watcherErrorHandler = spy
+    new Watcher(vm, function () {
+      return this.a.b.c
+    }, () => {}, { user: true })
+    expect('Error when evaluating watcher').toHaveBeenWarned()
+    expect(spy).toHaveBeenCalled()
+    expect(spy.calls.argsFor(0)[0] instanceof TypeError).toBe(true)
+    expect(spy.calls.argsFor(0)[1]).toBe(vm)
+  })
 })