Răsfoiți Sursa

Tests

- unit tests for Observer:
  - unobserve()
  - ensurePath()
  - ensurePaths()
  - Multiple observers
- unit test for sd-model:
  - should only lock update if it has no filters
- functional test for sd-model in validation.js:
  - should remember and restore selection position
    when it has filters
- functional test for Observer.ensurePaths():
  - should allow setting a nested scope object to {}
Evan You 12 ani în urmă
părinte
comite
7888d05dc1

+ 5 - 1
test/functional/fixtures/nested-props.html

@@ -17,7 +17,8 @@
             <form id="form"><input name="msg" sd-model="msg"></form>
             <p class="hidden">{{sum}}</p>
             <button class="four" sd-on="click:four">four</button>
-            <button class="five" sd-on="click:setEmpty">empty</button>
+            <button class="empty1" sd-on="click:setEmpty">empty a.b</button>
+            <button class="empty2" sd-on="click:setEmpty2">empty a</button>
         </div>
         <script>
             Seed.config({debug: true})
@@ -66,6 +67,9 @@
                     },
                     setEmpty: function () {
                         this.a.b = {}
+                    },
+                    setEmpty2: function () {
+                        this.a = {}
                     }
                 }
             })

+ 1 - 1
test/functional/fixtures/validation.html

@@ -13,7 +13,7 @@
     </head>
     <body>
         <div id="test">
-            email: <input type="text" sd-model="a | email" sd-class="valid:validation.email">
+            email: <input type="text" sd-model="a | email" sd-class="valid:validation.email" name="email">
         </div>
         <script>
             var RE = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/

+ 11 - 1
test/functional/specs/nested-props.js

@@ -1,4 +1,4 @@
-casper.test.begin('Nested Properties', 15, function (test) {
+casper.test.begin('Nested Properties', 20, function (test) {
     
     casper
     .start('./fixtures/nested-props.html', function () {
@@ -35,6 +35,16 @@ casper.test.begin('Nested Properties', 15, function (test) {
         this.click('.four')
         test.assertSelectorHasText('.hidden', '4')
 
+        // set a nested object to {}
+        this.click('.empty1')
+        test.assertSelectorHasText('h1 span', '')
+        test.assertSelectorHasText('h3 span', 'Oh yeah 3')
+
+        this.click('.empty2')
+        test.assertSelectorHasText('h1 span', '')
+        test.assertSelectorHasText('h2 span', '')
+        test.assertSelectorHasText('h3 span', 'Oh yeah ')
+
     })
     .run(function () {
         test.done()

+ 9 - 1
test/functional/specs/validation.js

@@ -1,10 +1,18 @@
-casper.test.begin('Validation', 2, function (test) {
+casper.test.begin('Validation', 4, function (test) {
     
     casper
     .start('./fixtures/validation.html', function () {
         test.assertElementCount('.valid', 0)
         this.sendKeys('input', '@hello.com')
         test.assertElementCount('.valid', 1)
+
+        this.evaluate(function () {
+            document.querySelector('input').setSelectionRange(4,4)
+        })
+
+        this.sendKeys('input', 'hoho')
+        test.assertElementCount('.valid', 1)
+        test.assertField('email', 'hihihoho@hello.com')
     })
     .run(function () {
         test.done()

+ 15 - 0
test/unit/specs/directives.js

@@ -359,6 +359,7 @@ describe('UNIT: Directives', function () {
                 var triggered = false
                 dir.key = 'foo'
                 dir.vm = { $set: function (key, val) {
+                    assert.ok(dir.lock, 'the directive should be locked if it has no filters')
                     assert.strictEqual(key, 'foo')
                     assert.strictEqual(val, 'bar')
                     triggered = true
@@ -378,6 +379,20 @@ describe('UNIT: Directives', function () {
                 assert.ok(removed)
             })
 
+            it('should not lock during vm.$set if it has filters', function () {
+                var triggered = false
+                var dir = mockDirective('model', 'input', 'text')
+                dir.filters = []
+                dir.bind()
+                dir.vm = {$set:function () {
+                    assert.notOk(dir.lock)
+                    triggered = true
+                }}
+                dir.el.value = 'foo'
+                dir.el.dispatchEvent(mockHTMLEvent('input'))
+                assert.ok(triggered)
+            })
+
             after(function () {
                 document.body.removeChild(dir.el)
             })

+ 98 - 0
test/unit/specs/observer.js

@@ -302,6 +302,104 @@ describe('UNIT: Observer', function () {
 
     })
 
+    describe('Multiple observers', function () {
+
+        var ob1 = new Emitter(),
+            ob2 = new Emitter(),
+            obj = {a:1}
+        ob1.proxies = {}
+        ob2.proxies = {}
+        Observer.observe(obj, 'test', ob1)
+        Observer.observe(obj, 'test', ob2)
+
+        var ob1Called = false,
+            ob2Called = false
+
+        ob1.on('set', function () {
+            ob1Called = true
+        })
+        ob2.on('set', function () {
+            ob2Called = true
+        })
+
+        it('should trigger events for multiple observers observing the same object', function () {
+            obj.a = 2
+            assert.ok(ob1Called)
+            assert.ok(ob2Called)
+        })
+
+    })
+
+    describe('.unobserve()', function () {
+        
+        var ob1 = new Emitter(),
+            ob2 = new Emitter(),
+            obj = {a:1}
+        ob1.proxies = {}
+        ob2.proxies = {}
+        Observer.observe(obj, 'test', ob1)
+        Observer.observe(obj, 'test', ob2)
+        Observer.unobserve(obj, 'test', ob1)
+
+        var ob1Called = false
+        ob1.on('set', function () {
+            ob1Called = true
+        })
+        var ob2Called = false
+        ob2.on('set', function () {
+            ob2Called = true
+        })
+
+        it('should set observer proxies path to null', function () {
+            assert.strictEqual(ob1.proxies['test.'], null)
+        })
+
+        it('should turn off corresponding event listeners', function () {
+            var callbacks = obj.__observer__._callbacks
+            for (var e in callbacks) {
+                assert.strictEqual(callbacks[e].length, 1)
+            }
+        })
+
+        it('should no longer emit events', function () {
+            obj.a = 2
+            assert.notOk(ob1Called)
+            assert.ok(ob2Called)
+        })
+
+    })
+
+    describe('.ensurePath()', function () {
+        
+        it('should ensure a path can be accessed without error', function () {
+            var obj = {},
+                path = 'a.b.c'
+            Observer.ensurePath(obj, path)
+            assert.strictEqual(obj.a.b.c, undefined)
+        })
+
+    })
+
+    describe('.ensurePaths()', function () {
+        
+        it('should ensure path for all paths that start with the given key', function () {
+            var key = 'a',
+                obj = {},
+                paths = {
+                    'a.b.c': 1,
+                    'a.d': 2,
+                    'e.f': 3,
+                    'g': 4
+                }
+            Observer.ensurePaths(key, obj, paths)
+            assert.strictEqual(obj.b.c, undefined)
+            assert.strictEqual(obj.d, undefined)
+            assert.notOk('f' in obj)
+            assert.strictEqual(Object.keys(obj).length, 2)
+        })
+
+    })
+
     function setTestFactory (opts) {
         return function () {
             var ob = new Emitter(),