2
0
Эх сурвалжийг харах

fix functional tests for batcher

Evan You 12 жил өмнө
parent
commit
7fc537ad5a

+ 5 - 3
examples/todomvc/js/benchmark.js

@@ -43,9 +43,11 @@ function runBenchmark () {
         function toggle () {
             addTime = now() - last
             var checkboxes = document.querySelectorAll('.toggle')
-            for (var i = 0; i < checkboxes.length; i++) {
-                checkboxes[i].click()
-            }
+            //for (var j = 0; j < 5; j++) {
+                for (var i = 0; i < checkboxes.length; i++) {
+                    checkboxes[i].click()
+                }
+            //}
             last = now()
             setTimeout(remove, 0)
         }

+ 5 - 3
src/batcher.js

@@ -24,9 +24,11 @@ exports.queue = function (binding, method) {
 
 function flush () {
     for (var i = 0; i < queue.length; i++) {
-        var task = queue[i]
-        task.binding['_' + task.method]()
-        has[task.binding.id] = false
+        var task = queue[i],
+            b = task.binding
+        if (b.unbound) continue
+        b['_' + task.method]()
+        has[b.id] = false
     }
     reset()
 }

+ 6 - 0
src/binding.js

@@ -19,6 +19,7 @@ function Binding (compiler, key, isExp, isFn) {
     this.instances = []
     this.subs = []
     this.deps = []
+    this.unbound = false
 }
 
 var BindingProto = Binding.prototype
@@ -70,6 +71,11 @@ BindingProto.pub = function () {
  *  Unbind the binding, remove itself from all of its dependencies
  */
 BindingProto.unbind = function () {
+    // Indicate this has been unbound.
+    // It's possible this binding will be in
+    // the batcher's flush queue when its owner
+    // compiler has already been destroyed.
+    this.unbound = true
     var i = this.instances.length
     while (i--) {
         this.instances[i].unbind()

+ 7 - 8
src/directives/model.js

@@ -40,15 +40,14 @@ module.exports = {
                 try {
                     cursorPos = el.selectionStart
                 } catch (e) {}
-                // `input` event has weird updating issue with
-                // International (e.g. Chinese) input methods,
-                // have to use a Timeout to hack around it...
-                setTimeout(function () {
-                    self.vm.$set(self.key, el[attr])
+                self.vm.$set(self.key, el[attr])
+                // since updates are async
+                // we need to reset cursor position async too
+                utils.nextTick(function () {
                     if (cursorPos !== undefined) {
                         el.setSelectionRange(cursorPos, cursorPos)
                     }
-                }, 0)
+                })
             }
             : function () {
                 // no filters, don't let it trigger update()
@@ -63,9 +62,9 @@ module.exports = {
         if (isIE9) {
             self.onCut = function () {
                 // cut event fires before the value actually changes
-                setTimeout(function () {
+                utils.nextTick(function () {
                     self.set()
-                }, 0)
+                })
             }
             self.onDel = function (e) {
                 if (e.keyCode === 46 || e.keyCode === 8) {

+ 10 - 11
test/functional/specs/extend.js

@@ -1,24 +1,23 @@
 casper.test.begin('Encapsulation & Inheritance', 8, function (test) {
     
     casper
-    .start('./fixtures/extend.html', function () {
-
+    .start('./fixtures/extend.html')
+    .then(function () {
         test.assertSelectorHasText('.dir', 'directive works')
         test.assertSelectorHasText('.filter', 'filter works')
         test.assertSelectorHasText('.partial', 'partial works')
         test.assertSelectorHasText('.vm', 'component works')
         test.assertSelectorHasText('.vm-w-model', 'component with model works')
-
         test.assertSelectorHasText('#log', 'T created T ready T created C created T ready C ready', 'hook inheritance works')
         test.assertSelectorHasText('.cvm', 'component works', 'Child should have access to Parent options')
-
-        this.evaluate(function () {
-            test.vmData = {
-                selfMsg: 'replacing $data ',
-                msg: 'also works'
-            }
-        })
-
+    })
+    .thenEvaluate(function () {
+        test.vmData = {
+            selfMsg: 'replacing $data ',
+            msg: 'also works'
+        }
+    })
+    .then(function () {
         test.assertSelectorHasText('.vm-w-model', 'replacing $data also works')
     })
     .run(function () {

+ 6 - 4
test/functional/specs/forms.js

@@ -1,15 +1,16 @@
 casper.test.begin('Forms', 10, function (test) {
     
     casper
-    .start('./fixtures/forms.html', function () {
-
+    .start('./fixtures/forms.html')
+    .then(function () {
         // test initial value binding
         test.assertField('text', 'some text')
         test.assertField('checkbox', true)
         test.assertField('radio', 'b')
         test.assertField('select', 'b')
         test.assertField('textarea', 'more text')
-
+    })
+    .then(function () {
         this.fill('#forms', {
             'text': 'changed text',
             'checkbox': false,
@@ -17,7 +18,8 @@ casper.test.begin('Forms', 10, function (test) {
             'select': 'a',
             'textarea': 'more changed text'
         })
-
+    })
+    .then(function () {
         test.assertSelectorHasText('.text', 'changed text')
         test.assertSelectorHasText('.checkbox', 'false')
         test.assertSelectorHasText('.radio', 'a')

+ 25 - 21
test/functional/specs/nested-props.js

@@ -1,50 +1,54 @@
 casper.test.begin('Nested Properties', 20, function (test) {
     
     casper
-    .start('./fixtures/nested-props.html', function () {
-
+    .start('./fixtures/nested-props.html')
+    .then(function () {
         test.assertSelectorHasText('h1 span', '')
         test.assertSelectorHasText('h2 span', '555')
         test.assertSelectorHasText('h3 span', 'Yoyoyo555')
-
-        this.click('.one')
+    })
+    .thenClick('.one', function () {
         test.assertSelectorHasText('h1 span', 'one')
         test.assertSelectorHasText('h2 span', '1')
         test.assertSelectorHasText('h3 span', 'Yoyoyoone1')
-
-        this.click('.two')
+    })
+    .thenClick('.two', function () {
         test.assertSelectorHasText('h1 span', 'two')
         test.assertSelectorHasText('h2 span', '2')
         test.assertSelectorHasText('h3 span', 'Yoyoyotwo2')
-
-        this.click('.three')
+    })
+    .thenClick('.three', function () {
         test.assertSelectorHasText('h1 span', 'three')
         test.assertSelectorHasText('h2 span', '3')
         test.assertSelectorHasText('h3 span', 'Yoyoyothree3')
-
+    })
+    .then(function () {
         this.fill('#form', {
             msg: 'Oh yeah '
         })
+    })
+    .then(function () {
         test.assertSelectorHasText('h3 span', 'Oh yeah three3')
-
-        // hidden data variables
-        // i.e. nested under an object, not explicitly
-        // bound in the template, but is depended upon
-        // by an expression or a computed property
+    })
+    // hidden data variables
+    // i.e. nested under an object, not explicitly
+    // bound in the template, but is depended upon
+    // by an expression or a computed property
+    .then(function () {
         test.assertSelectorHasText('.hidden', '3')
-        this.click('.four')
+    })
+    .thenClick('.four', function () {
         test.assertSelectorHasText('.hidden', '4')
-
-        // set a nested object to {}
-        this.click('.empty1')
+    })
+    // set a nested object to {}
+    .thenClick('.empty1', function () {
         test.assertSelectorHasText('h1 span', '')
         test.assertSelectorHasText('h3 span', 'Oh yeah 3')
-
-        this.click('.empty2')
+    })
+    .thenClick('.empty2', function () {
         test.assertSelectorHasText('h1 span', '')
         test.assertSelectorHasText('h2 span', '')
         test.assertSelectorHasText('h3 span', 'Oh yeah ')
-
     })
     .run(function () {
         test.done()

+ 17 - 7
test/functional/specs/nested-repeat.js

@@ -1,10 +1,9 @@
 casper.test.begin('Nested Repeat', 12, function (test) {
     
     casper
-    .start('./fixtures/nested-repeat.html', function () {
-
+    .start('./fixtures/nested-repeat.html')
+    .then(function () {
         var i, j
-
         for (i = 0; i < 2; i++) {
             for (j = 0; j < 2; j++) {
                 test.assertSelectorHasText(
@@ -13,10 +12,13 @@ casper.test.begin('Nested Repeat', 12, function (test) {
                 )
             }
         }
-
+    })
+    .then(function () {
         this.click('#b0')
         this.click('#b1')
-
+    })
+    .then(function () {
+        var i, j
         for (i = 0; i < 2; i++) {
             for (j = 0; j < 2; j++) {
                 test.assertSelectorHasText(
@@ -25,17 +27,25 @@ casper.test.begin('Nested Repeat', 12, function (test) {
                 )
             }
         }
-
+    })
+    .then(function () {
+        var i, j
         for (i = 0; i < 2; i++) {
             for (j = 0; j < 2; j++) {
                 this.click('#b' + i + '-' + j)
+            }
+        }
+    })
+    .then(function () {
+        var i, j
+        for (i = 0; i < 2; i++) {
+            for (j = 0; j < 2; j++) {
                 test.assertSelectorHasText(
                     '.list-' + i + ' .list-' + j,
                     i + '.' + j + ' : hi<-hi'
                 )
             }
         }
-
     })
     .run(function () {
         test.done()

+ 2 - 1
test/functional/specs/nested-vms.js

@@ -1,7 +1,8 @@
 casper.test.begin('Nested Viewmodels', 7, function (test) {
     
     casper
-    .start('./fixtures/nested-vms.html', function () {
+    .start('./fixtures/nested-vms.html')
+    .then(function () {
 
         test.assertSelectorHasText('.ancestor', 'Andy Johnson')
         test.assertSelectorHasText('.jack', 'Jack, son of Andy')

+ 24 - 20
test/functional/specs/repeated-items.js

@@ -1,7 +1,8 @@
 casper.test.begin('Repeated Items', 41, function (test) {
     
     casper
-    .start('./fixtures/repeated-items.html', function () {
+    .start('./fixtures/repeated-items.html')
+    .then(function () {
 
         // initial values
         test.assertSelectorHasText('.count', '3')
@@ -9,58 +10,60 @@ casper.test.begin('Repeated Items', 41, function (test) {
         test.assertSelectorHasText('.item:nth-child(2)', '1 B')
         test.assertSelectorHasText('.item:nth-child(3)', '2 C')
 
-        this.click('.push')
+    })
+    .thenClick('.push', function () {
         test.assertSelectorHasText('.count', '4')
         test.assertSelectorHasText('.item:nth-child(4)', '3 0')
-
-        this.click('.shift')
+    })
+    .thenClick('.shift', function () {
         test.assertSelectorHasText('.count', '3')
         test.assertSelectorHasText('.item:nth-child(1)', '0 B')
         test.assertSelectorHasText('.item:nth-child(2)', '1 C')
         test.assertSelectorHasText('.item:nth-child(3)', '2 0')
-
-        this.click('.pop')
+    })
+    .thenClick('.pop', function () {
         test.assertSelectorHasText('.count', '2')
         test.assertSelectorHasText('.item:nth-child(1)', '0 B')
         test.assertSelectorHasText('.item:nth-child(2)', '1 C')
-
-        this.click('.unshift')
+    })
+    .thenClick('.unshift', function () {
         test.assertSelectorHasText('.count', '3')
         test.assertSelectorHasText('.item:nth-child(1)', '0 1')
         test.assertSelectorHasText('.item:nth-child(2)', '1 B')
         test.assertSelectorHasText('.item:nth-child(3)', '2 C')
-
-        this.click('.splice')
+    })
+    .thenClick('.splice', function () {
         test.assertSelectorHasText('.count', '4')
         test.assertSelectorHasText('.item:nth-child(1)', '0 1')
         test.assertSelectorHasText('.item:nth-child(2)', '1 2')
         test.assertSelectorHasText('.item:nth-child(3)', '2 3')
         test.assertSelectorHasText('.item:nth-child(4)', '3 C')
-
-        this.click('.remove')
+    })
+    .thenClick('.remove', function () {
         test.assertSelectorHasText('.count', '3')
         test.assertSelectorHasText('.item:nth-child(1)', '0 1')
         test.assertSelectorHasText('.item:nth-child(2)', '1 2')
         test.assertSelectorHasText('.item:nth-child(3)', '2 3')
-
-        this.click('.replace')
+    })
+    .thenClick('.replace', function () {
         test.assertSelectorHasText('.count', '3')
         test.assertSelectorHasText('.item:nth-child(1)', '0 1')
         test.assertSelectorHasText('.item:nth-child(2)', '1 2')
         test.assertSelectorHasText('.item:nth-child(3)', '2 4')
-
-        this.click('.reverse')
+    })
+    .thenClick('.reverse', function () {
         test.assertSelectorHasText('.count', '3')
         test.assertSelectorHasText('.item:nth-child(1)', '0 4')
         test.assertSelectorHasText('.item:nth-child(2)', '1 2')
         test.assertSelectorHasText('.item:nth-child(3)', '2 1')
-
-        this.click('.sort')
+    })
+    .thenClick('.sort', function () {
         test.assertSelectorHasText('.count', '3')
         test.assertSelectorHasText('.item:nth-child(1)', '0 1')
         test.assertSelectorHasText('.item:nth-child(2)', '1 2')
         test.assertSelectorHasText('.item:nth-child(3)', '2 4')
-
+    })
+    .then(function () {
         // make sure things work on empty array
         this.click('.pop')
         this.click('.pop')
@@ -72,10 +75,11 @@ casper.test.begin('Repeated Items', 41, function (test) {
         this.click('.sort')
         this.click('.reverse')
         this.click('.splice')
+    })
+    .then(function () {
         test.assertSelectorHasText('.count', '2')
         test.assertSelectorHasText('.item:nth-child(1)', '0 6')
         test.assertSelectorHasText('.item:nth-child(2)', '1 7')
-
     })
     .run(function () {
         test.done()

+ 12 - 9
test/functional/specs/repeated-vms.js

@@ -1,24 +1,27 @@
 casper.test.begin('Repeated ViewModels', 7, function (test) {
     
     casper
-    .start('./fixtures/repeated-vms.html', function () {
+    .start('./fixtures/repeated-vms.html')
+    .then(function () {
 
         test.assertSelectorHasText('.item:nth-child(1)', 'msg a init')
         test.assertSelectorHasText('.item:nth-child(2)', 'msg b init')
         test.assertSelectorHasText('.item:nth-child(3)', 'msg c init')
 
-        // click everything to test event handlers (delegated)
-        this.click('.item:nth-child(1)')
+    })
+    // click everything to test event handlers (delegated)
+    .thenClick('.item:nth-child(1)', function () {
         test.assertSelectorHasText('.item:nth-child(1)', 'msg a init click')
-        this.click('.item:nth-child(2)')
+    })
+    .thenClick('.item:nth-child(2)', function () {
         test.assertSelectorHasText('.item:nth-child(2)', 'msg b init click')
-        this.click('.item:nth-child(3)')
+    })
+    .thenClick('.item:nth-child(3)', function () {
         test.assertSelectorHasText('.item:nth-child(3)', 'msg c init click')
-
-        // more clicks
-        this.click('.item:nth-child(1)')
+    })
+    // more clicks
+    .thenClick('.item:nth-child(1)', function () {
         test.assertSelectorHasText('.item:nth-child(1)', 'msg a init click click')
-
     })
     .run(function () {
         test.done()

+ 6 - 1
test/functional/specs/share-data.js

@@ -1,16 +1,21 @@
 casper.test.begin('Sharing Data between VMs', 7, function (test) {
     
     casper
-    .start('./fixtures/share-data.html', function () {
+    .start('./fixtures/share-data.html')
+    .then(function () {
 
         test.assertSelectorHasText('#a', 'hello')
         test.assertSelectorHasText('#b', 'hello')
         test.assertField('input', 'hello')
         test.assertSelectorHasText('#d pre', '{"msg":"hello"}')
 
+    })
+    .then(function () {
         this.fill('#c', {
             input: 'durrr'
         })
+    })
+    .then(function () {
 
         test.assertSelectorHasText('#a', 'durrr')
         test.assertSelectorHasText('#b', 'durrr')

+ 8 - 9
test/functional/specs/simple-dir.js

@@ -1,18 +1,17 @@
 casper.test.begin('Simple Directive', 3, function (test) {
     
     casper
-    .start('./fixtures/simple-dir.html', function () {
-
+    .start('./fixtures/simple-dir.html')
+    .then(function () {
         test.assertSelectorHasText('.one', 'bind', 'object definition bind')
         test.assertSelectorHasText('.two', 'bind', 'function definition bind')
-
-        this.evaluate(function () {
-            /* global a */
-            a.$destroy()
-        })
-
+    })
+    .thenEvaluate(function () {
+        /* global a */
+        a.$destroy()
+    })
+    .then(function () {
         test.assertSelectorHasText('.one', 'unbind', 'object definition unbind')
-
     })
     .run(function () {
         test.done()

+ 2 - 2
test/functional/specs/template.js

@@ -1,13 +1,13 @@
 casper.test.begin('Template', 4, function (test) {
     
     casper
-    .start('./fixtures/template.html', function () {
+    .start('./fixtures/template.html')
+    .then(function () {
         test.assertSelectorHasText('#usa', 'Hi dude', 'global partial')
         test.assertSelectorHasText('#japan', 'こんにちは', 'local partial')
         test.assertSelectorHasText('#china', '你好', 'direct option')
         test.assertSelectorHasText('#hawaii', 'Aloha', 'extend option')
     })
-
     .run(function () {
         test.done()
     })

+ 62 - 26
test/functional/specs/todomvc.js

@@ -3,16 +3,22 @@
 casper.test.begin('todomvc', 69, function (test) {
     
     casper
-    .start('../../examples/todomvc/index.html', function () {
+    .start('../../examples/todomvc/index.html')
+    .then(function () {
 
         test.assertNotVisible('#main', '#main should be hidden')
         test.assertNotVisible('#footer', '#footer should be hidden')
         test.assertElementCount('#filters .selected', 1, 'should have one filter selected')
         test.assertSelectorHasText('#filters .selected', 'All', 'default filter should be "All"')
 
-        // let's add a new item -----------------------------------------------
+    })
+
+    // let's add a new item -----------------------------------------------
 
+    .then(function () {
         createNewItem('test')
+    })
+    .then(function () {
 
         test.assertElementCount('.todo', 1, 'new item should be created')
         test.assertNotVisible('.todo .edit', 'new item edit box should be hidden')
@@ -30,17 +36,22 @@ casper.test.begin('todomvc', 69, function (test) {
             return __utils__.findOne('#new-todo').value
         }, '', 'new todo input should be reset')
 
-        // add another item ---------------------------------------------------
+    })
+
+    // add another item ---------------------------------------------------
 
+    .then(function () {
         createNewItem('test2')
-
+    })
+    .then(function () {
         test.assertElementCount('.todo', 2, 'should have 2 items now')
         test.assertSelectorHasText('.todo label', 'test2', 'new item should have correct label text')
         test.assertSelectorHasText('#todo-count strong', '2', 'remaining count should be 2')
+    })
 
-        // mark one item as completed -----------------------------------------
+    // mark one item as completed -----------------------------------------
 
-        this.click('.todo .toggle')
+    .thenClick('.todo .toggle', function () {
         test.assertElementCount('.todo.completed', 1, 'should have 1 item completed')
         test.assertEval(function () {
             return __utils__.findOne('.todo').classList.contains('completed')
@@ -49,52 +60,67 @@ casper.test.begin('todomvc', 69, function (test) {
         test.assertSelectorHasText('#todo-count strong', '1', 'remaining count should be 1')
         test.assertVisible('#clear-completed', '#clear-completed should now be visible')
         test.assertSelectorHasText('#clear-completed', 'Remove Completed (1)')
+    })
 
-        // add yet another item -----------------------------------------------
+    // add yet another item -----------------------------------------------
 
+    .then(function () {
         createNewItem('test3')
-
+    })
+    .then(function () {
         test.assertElementCount('.todo', 3, 'should have 3 items now')
         test.assertSelectorHasText('.todo label', 'test3', 'new item should have correct label text')
         test.assertSelectorHasText('#todo-count strong', '2', 'remaining count should be 2')
+    })
 
-        // add moreeee, now we assume they all work properly ------------------
+    // add moreeee, now we assume they all work properly ------------------
 
+    .then(function () {
         createNewItem('test4')
         createNewItem('test5')
-
+    })
+    .then(function () {
         test.assertElementCount('.todo', 5, 'should have 5 items now')
         test.assertSelectorHasText('#todo-count strong', '4', 'remaining count should be 4')
+    })
 
-        // check more as completed --------------------------------------------
+    // check more as completed --------------------------------------------
+    .then(function () {
         this.click('.todo:nth-child(1) .toggle')
         this.click('.todo:nth-child(2) .toggle')
+    })
+    .then(function () {
         test.assertElementCount('.todo.completed', 3, 'should have 3 item completed')
         test.assertSelectorHasText('#clear-completed', 'Remove Completed (3)')
         test.assertSelectorHasText('#todo-count strong', '2', 'remaining count should be 2')
+    })
+
+    // remove a completed item --------------------------------------------
 
-        // remove a completed item --------------------------------------------
-        this.click('.todo:nth-child(1) .destroy')
+    .thenClick('.todo:nth-child(1) .destroy', function () {
         test.assertElementCount('.todo', 4, 'should have 4 items now')
         test.assertElementCount('.todo.completed', 2, 'should have 2 item completed')
         test.assertSelectorHasText('#clear-completed', 'Remove Completed (2)')
         test.assertSelectorHasText('#todo-count strong', '2', 'remaining count should be 2')
+    })
+
+    // remove a incompleted item ------------------------------------------
 
-        // remove a incompleted item ------------------------------------------
-        this.click('.todo:nth-child(2) .destroy')
+    .thenClick('.todo:nth-child(2) .destroy', function () {
         test.assertElementCount('.todo', 3, 'should have 3 items now')
         test.assertElementCount('.todo.completed', 2, 'should have 2 item completed')
         test.assertSelectorHasText('#clear-completed', 'Remove Completed (2)')
         test.assertSelectorHasText('#todo-count strong', '1', 'remaining count should be 1')
+    })
+
+    // remove all completed ------------------------------------------------
 
-        // remove all completed ------------------------------------------------
-        this.click('#clear-completed')
+    .thenClick('#clear-completed', function () {
         test.assertElementCount('.todo', 1, 'should have 1 item now')
         test.assertSelectorHasText('.todo label', 'test', 'the remaining one should be the first one')
         test.assertElementCount('.todo.completed', 0, 'should have no completed items now')
         test.assertSelectorHasText('#todo-count strong', '1', 'remaining count should be 1')
         test.assertNotVisible('#clear-completed', '#clear-completed should be hidden')
-
     })
 
     // prepare to test filters ------------------------------------------------
@@ -115,6 +141,8 @@ casper.test.begin('todomvc', 69, function (test) {
     // mostly make sure v-repeat works well with v-if
     .then(function () {
         createNewItem('test')
+    })
+    .then(function () {
         test.assertElementCount('.todo', 2, 'should be able to create new item when fitler active')
     })
 
@@ -141,31 +169,33 @@ casper.test.begin('todomvc', 69, function (test) {
     })
 
     // toggling todos when filter is active -----------------------------------
-    .then(function () {
-        this.click('.todo .toggle')
+    .thenClick('.todo .toggle', function () {
         test.assertElementCount('.todo', 1, 'should have only 1 item left')
     })
     .thenClick('#filters li:nth-child(2) a', function () {
         test.assertElementCount('.todo', 3, 'should have only 3 items now')
-        this.click('.todo .toggle')
+    })
+    .thenClick('.todo .toggle', function () {
         test.assertElementCount('.todo', 2, 'should have only 2 items now')
     })
 
     // test editing triggered by blur ------------------------------------------
-    .thenClick('#filters li:nth-child(1) a', function () {
+    .thenClick('#filters li:nth-child(1) a')
+    .then(function () {
         doubleClick('.todo:nth-child(1) label')
-        test.assertElementCount('.todo.editing', 1, 'should have one item being edited')
     })
     .then(function () {
-
+        test.assertElementCount('.todo.editing', 1, 'should have one item being edited')
         test.assertEval(function () {
             var input = document.querySelector('.todo:nth-child(1) .edit')
             return input === document.activeElement
         }, 'edit input should be focused')
-
+    })
+    .then(function () {
         resetField()
         this.sendKeys('.todo:nth-child(1) .edit', 'edited!') // doneEdit triggered by blur
-
+    })
+    .then(function () {
         test.assertElementCount('.todo.editing', 0, 'item should no longer be edited')
         test.assertSelectorHasText('.todo:nth-child(1) label', 'edited!', 'item should have updated text')
     })
@@ -178,6 +208,8 @@ casper.test.begin('todomvc', 69, function (test) {
         resetField()
         this.sendKeys('.todo:nth-child(1) .edit', 'edited again!', { keepFocus: true })
         keyUp(13) // Enter
+    })
+    .then(function () {
         test.assertElementCount('.todo.editing', 0, 'item should no longer be edited')
         test.assertSelectorHasText('.todo:nth-child(1) label', 'edited again!', 'item should have updated text')
     })
@@ -190,6 +222,8 @@ casper.test.begin('todomvc', 69, function (test) {
         resetField()
         this.sendKeys('.todo:nth-child(1) .edit', 'cancel test', { keepFocus: true })
         keyUp(27) // ESC
+    })
+    .then(function () {
         test.assertElementCount('.todo.editing', 0, 'item should no longer be edited')
         test.assertSelectorHasText('.todo label', 'edited again!', 'item should not have updated text')
     })
@@ -201,6 +235,8 @@ casper.test.begin('todomvc', 69, function (test) {
     .then(function () {
         resetField()
         this.sendKeys('.todo:nth-child(1) .edit', ' ')
+    })
+    .then(function () {
         test.assertElementCount('.todo', 3, 'item should have been deleted')
     })
 

+ 5 - 4
test/functional/specs/validation.js

@@ -7,10 +7,11 @@ casper.test.begin('Validation', 4, function (test) {
     })
     .then(function () {
         test.assertElementCount('.valid', 1)
-
-        this.evaluate(function () {
-            document.querySelector('input').setSelectionRange(4,4)
-        })
+    })
+    .thenEvaluate(function () {
+        document.querySelector('input').setSelectionRange(4,4)
+    })
+    .then(function () {
         this.sendKeys('input', 'hoho')
     })
     .then(function () {

+ 1 - 1
test/unit/specs/batcher.js

@@ -52,7 +52,7 @@ describe('Batcher', function () {
 
     })
 
-    it('should queue dependency bidnings triggered during flush', function () {
+    it('should queue dependency bidnings triggered during flush', function (done) {
         
         updateCount = 0
         var b1 = mockBinding(1),