Evan You 11 лет назад
Родитель
Сommit
405b5fe36d
7 измененных файлов с 222 добавлено и 128 удалено
  1. 1 1
      gruntfile.js
  2. 0 1
      src/cache.js
  3. 8 19
      src/parse/template.js
  4. 8 5
      src/util.js
  5. 34 34
      test/unit/data_spec.js
  6. 68 68
      test/unit/observer_spec.js
  7. 103 0
      test/unit/template-parser.js

+ 1 - 1
gruntfile.js

@@ -14,7 +14,7 @@ module.exports = function (grunt) {
         src: 'src/**/*.js'
       },
       test: {
-        src: 'test/*/specs/*.js'
+        src: 'test/**/*.js'
       }
     },
 

+ 0 - 1
src/cache.js

@@ -92,7 +92,6 @@ p.shift = function () {
 p.get = function (key, returnEntry) {
   var entry = this._keymap[key]
   if (entry === undefined) return
-  console.log('cache hit!')
   if (entry === this.tail) {
     return returnEntry
       ? entry

+ 8 - 19
src/parse/template.js

@@ -67,22 +67,14 @@ function stringToFragment (templateString) {
       node = node.lastChild
     }
 
-    if (node.firstChild === node.lastChild) {
-      // one element
-      frag.appendChild(node.firstChild)
-      templateCache.put(templateString, frag)
-      return frag
-    } else {
-      // multiple nodes, return a fragment
-      /* jshint boss: true */
-      var child
-      while (child = node.firstChild) {
-        if (node.nodeType === 1) {
-          frag.appendChild(child)
-        }
+    var child
+    while (child = node.firstChild) {
+      if (node.nodeType === 1) {
+        frag.appendChild(child)
       }
     }
   }
+
   templateCache.put(templateString, frag)
   return frag
 }
@@ -101,12 +93,9 @@ function nodeToFragment (node) {
   if (tag === 'TEMPLATE' && node.content) {
     return node.content
   }
-  // script tag
-  if (tag === 'SCRIPT') {
-    return stringToFragment(node.textContent)
-  }
-  // non-script node. not recommended...
-  return toFragment(node.outerHTML)
+  return tag === 'SCRIPT'
+    ? stringToFragment(node.textContent)
+    : stringToFragment(node.outerHTML)
 }
 
 /**

+ 8 - 5
src/util.js

@@ -1,9 +1,4 @@
 var config = require('./config')
-var slice = [].slice
-var defer =
-  win.requestAnimationFrame ||
-  win.webkitRequestAnimationFrame ||
-  win.setTimeout
 
 /**
  * Defer a task to the start of the next event loop
@@ -11,6 +6,12 @@ var defer =
  * @param {Function} fn
  */
 
+var defer = typeof window === 'undefined'
+  ? setTimeout
+  : (window.requestAnimationFrame ||
+    window.webkitRequestAnimationFrame ||
+    setTimeout)
+
 exports.nextTick = function (fn) {
   return defer(fn, 0)
 }
@@ -22,6 +23,8 @@ exports.nextTick = function (fn) {
  * @param {Number} [i] - start index
  */
 
+var slice = [].slice
+
 exports.toArray = function (list, i) {
   return slice.call(list, i || 0)
 }

+ 34 - 34
test/unit/data_spec.js

@@ -22,13 +22,13 @@ describe('Scope', function () {
     })
 
     it('should copy over data properties', function () {
-      expect(vm.$scope.a).toEqual(vm.$data.a)
-      expect(vm.$scope.b).toEqual(vm.$data.b)
+      expect(vm.$scope.a).toBe(vm.$data.a)
+      expect(vm.$scope.b).toBe(vm.$data.b)
     })
 
     it('should proxy these properties', function () {
-      expect(vm.a).toEqual(vm.$scope.a)
-      expect(vm.b).toEqual(vm.$scope.b)
+      expect(vm.a).toBe(vm.$scope.a)
+      expect(vm.b).toBe(vm.$scope.b)
     })
 
     it('should trigger set events', function () {
@@ -37,12 +37,12 @@ describe('Scope', function () {
 
       // set on scope
       vm.$scope.a = 2
-      expect(spy.callCount).toEqual(1)
+      expect(spy.callCount).toBe(1)
       expect(spy).toHaveBeenCalledWith('a', 2, u)
 
       // set on vm
       vm.b.c = 3
-      expect(spy.callCount).toEqual(2)
+      expect(spy.callCount).toBe(2)
       expect(spy).toHaveBeenCalledWith('b.c', 3, u)
     })
 
@@ -54,12 +54,12 @@ describe('Scope', function () {
 
       // add on scope
       vm.$scope.$add('c', 123)
-      expect(spy.callCount).toEqual(1)
+      expect(spy.callCount).toBe(1)
       expect(spy).toHaveBeenCalledWith('c', 123, u)
 
       // delete on scope
       vm.$scope.$delete('c')
-      expect(spy.callCount).toEqual(2)
+      expect(spy.callCount).toBe(2)
       expect(spy).toHaveBeenCalledWith('c', u, u)
 
       // vm $add/$delete are tested in the api suite
@@ -82,37 +82,37 @@ describe('Scope', function () {
     })
 
     it('should retain data reference', function () {
-      expect(vm.$data).toEqual(data)
+      expect(vm.$data).toBe(data)
     })
 
     it('should sync set', function () {
       // vm -> data
       vm.a = 2
-      expect(data.a).toEqual(2)
+      expect(data.a).toBe(2)
       // data -> vm
       data.b = {d:3}
-      expect(vm.$scope.b).toEqual(data.b)
-      expect(vm.b).toEqual(data.b)
+      expect(vm.$scope.b).toBe(data.b)
+      expect(vm.b).toBe(data.b)
     })
 
     it('should sync add', function () {
       // vm -> data
       vm.$scope.$add('c', 123)
-      expect(data.c).toEqual(123)
+      expect(data.c).toBe(123)
       // data -> vm
       data.$add('d', 456)
-      expect(vm.$scope.d).toEqual(456)
-      expect(vm.d).toEqual(456)
+      expect(vm.$scope.d).toBe(456)
+      expect(vm.d).toBe(456)
     })
 
     it('should sync delete', function () {
       // vm -> data
       vm.$scope.$delete('d')
-      expect(data.hasOwnProperty('d')).toBeFalsy()
+      expect(data.hasOwnProperty('d')).toBe(false)
       // data -> vm
       data.$delete('c')
-      expect(vm.$scope.hasOwnProperty('c')).toBeFalsy()
-      expect(vm.hasOwnProperty('c')).toBeFalsy()
+      expect(vm.$scope.hasOwnProperty('c')).toBe(false)
+      expect(vm.hasOwnProperty('c')).toBe(false)
     })
 
   })
@@ -136,8 +136,8 @@ describe('Scope', function () {
     })
 
     it('child should inherit parent data on scope', function () {
-      expect(child.$scope.b).toEqual(parent.b) // object
-      expect(child.$scope.c).toEqual(parent.c) // primitive value
+      expect(child.$scope.b).toBe(parent.b) // object
+      expect(child.$scope.c).toBe(parent.c) // primitive value
     })
 
     it('child should not ineherit data on instance', function () {
@@ -146,14 +146,14 @@ describe('Scope', function () {
     })
 
     it('child should shadow parent property with same key', function () {
-      expect(parent.a).toEqual('parent a')
-      expect(child.$scope.a).toEqual('child a')
-      expect(child.a).toEqual('child a')
+      expect(parent.a).toBe('parent a')
+      expect(child.$scope.a).toBe('child a')
+      expect(child.a).toBe('child a')
     })
 
     it('setting scope properties on child should affect parent', function () {
       child.$scope.c = 'modified by child'
-      expect(parent.c).toEqual('modified by child')
+      expect(parent.c).toBe('modified by child')
     })
 
     it('events on parent should propagate down to child', function () {
@@ -162,27 +162,27 @@ describe('Scope', function () {
       var spy = jasmine.createSpy('inheritance')
       child._observer.on('set', spy)
       parent.c = 'c changed'
-      expect(spy.callCount).toEqual(1)
+      expect(spy.callCount).toBe(1)
       expect(spy).toHaveBeenCalledWith('c', 'c changed', u)
 
       spy = jasmine.createSpy('inheritance')
       child._observer.on('add', spy)
       parent.$scope.$add('e', 123)
-      expect(spy.callCount).toEqual(1)
+      expect(spy.callCount).toBe(1)
       expect(spy).toHaveBeenCalledWith('e', 123, u)
 
       spy = jasmine.createSpy('inheritance')
       child._observer.on('delete', spy)
       parent.$scope.$delete('e')
-      expect(spy.callCount).toEqual(1)
+      expect(spy.callCount).toBe(1)
       expect(spy).toHaveBeenCalledWith('e', u, u)
 
       spy = jasmine.createSpy('inheritance')
       child._observer.on('mutate', spy)
       parent.arr.reverse()
-      expect(spy.mostRecentCall.args[0]).toEqual('arr')
-      expect(spy.mostRecentCall.args[1]).toEqual(parent.arr)
-      expect(spy.mostRecentCall.args[2].method).toEqual('reverse')
+      expect(spy.mostRecentCall.args[0]).toBe('arr')
+      expect(spy.mostRecentCall.args[1]).toBe(parent.arr)
+      expect(spy.mostRecentCall.args[2].method).toBe('reverse')
 
     })
 
@@ -192,7 +192,7 @@ describe('Scope', function () {
       var spy = jasmine.createSpy('inheritance')
       child._observer.on('set', spy)
       parent.a = 'a changed'
-      expect(spy.callCount).toEqual(0)
+      expect(spy.callCount).toBe(0)
     })
 
   })
@@ -220,12 +220,12 @@ describe('Scope', function () {
       child.a = 3
 
       // make sure data sync is working
-      expect(parent.arr[0].a).toEqual(3)
+      expect(parent.arr[0].a).toBe(3)
 
-      expect(parentSpy.callCount).toEqual(1)
+      expect(parentSpy.callCount).toBe(1)
       expect(parentSpy).toHaveBeenCalledWith('arr.0.a', 3, u)
 
-      expect(childSpy.callCount).toEqual(2)
+      expect(childSpy.callCount).toBe(2)
       expect(childSpy).toHaveBeenCalledWith('a', 3, u)
       expect(childSpy).toHaveBeenCalledWith('arr.0.a', 3, u)
     })

+ 68 - 68
test/unit/observer_spec.js

@@ -30,12 +30,12 @@ describe('Observer', function () {
 
     var t = obj.a
     expect(spy).toHaveBeenCalledWith('a', u, u)
-    expect(spy.callCount).toEqual(1)
+    expect(spy.callCount).toBe(1)
 
     t = obj.b.c
     expect(spy).toHaveBeenCalledWith('b', u, u)
     expect(spy).toHaveBeenCalledWith('b.c', u, u)
-    expect(spy.callCount).toEqual(3)
+    expect(spy.callCount).toBe(3)
 
     Observer.emitGet = false
   })
@@ -52,21 +52,21 @@ describe('Observer', function () {
 
     obj.a = 3
     expect(spy).toHaveBeenCalledWith('a', 3, u)
-    expect(spy.callCount).toEqual(1)
+    expect(spy.callCount).toBe(1)
 
     obj.b.c = 4
     expect(spy).toHaveBeenCalledWith('b.c', 4, u)
-    expect(spy.callCount).toEqual(2)
+    expect(spy.callCount).toBe(2)
 
     // swap set
     var newB = { c: 5 }
     obj.b = newB
     expect(spy).toHaveBeenCalledWith('b', newB, u)
-    expect(spy.callCount).toEqual(3)
+    expect(spy.callCount).toBe(3)
 
     // same value set should not emit events
     obj.a = 3
-    expect(spy.callCount).toEqual(3)
+    expect(spy.callCount).toBe(3)
   })
 
   it('array get', function () {
@@ -82,7 +82,7 @@ describe('Observer', function () {
     var t = obj.arr[0].a
     expect(spy).toHaveBeenCalledWith('arr', u, u)
     expect(spy).toHaveBeenCalledWith('arr.0.a', u, u)
-    expect(spy.callCount).toEqual(2)
+    expect(spy.callCount).toBe(2)
 
     Observer.emitGet = false
   })
@@ -108,15 +108,15 @@ describe('Observer', function () {
     var ob = Observer.create(arr)
     ob.on('mutate', spy)
     arr.push({a:3})
-    expect(spy.mostRecentCall.args[0]).toEqual('')
-    expect(spy.mostRecentCall.args[1]).toEqual(arr)
+    expect(spy.mostRecentCall.args[0]).toBe('')
+    expect(spy.mostRecentCall.args[1]).toBe(arr)
     var mutation = spy.mostRecentCall.args[2]
     expect(mutation).toBeDefined()
-    expect(mutation.method).toEqual('push')
-    expect(mutation.index).toEqual(2)
-    expect(mutation.removed.length).toEqual(0)
-    expect(mutation.inserted.length).toEqual(1)
-    expect(mutation.inserted[0]).toEqual(arr[2])
+    expect(mutation.method).toBe('push')
+    expect(mutation.index).toBe(2)
+    expect(mutation.removed.length).toBe(0)
+    expect(mutation.inserted.length).toBe(1)
+    expect(mutation.inserted[0]).toBe(arr[2])
     // test index update after mutation
     ob.on('set', spy)
     arr[2].a = 4
@@ -129,15 +129,15 @@ describe('Observer', function () {
     var ob = Observer.create(arr)
     ob.on('mutate', spy)
     arr.pop()
-    expect(spy.mostRecentCall.args[0]).toEqual('')
-    expect(spy.mostRecentCall.args[1]).toEqual(arr)
+    expect(spy.mostRecentCall.args[0]).toBe('')
+    expect(spy.mostRecentCall.args[1]).toBe(arr)
     var mutation = spy.mostRecentCall.args[2]
     expect(mutation).toBeDefined()
-    expect(mutation.method).toEqual('pop')
-    expect(mutation.index).toEqual(1)
-    expect(mutation.inserted.length).toEqual(0)
-    expect(mutation.removed.length).toEqual(1)
-    expect(mutation.removed[0]).toEqual(popped)
+    expect(mutation.method).toBe('pop')
+    expect(mutation.index).toBe(1)
+    expect(mutation.inserted.length).toBe(0)
+    expect(mutation.removed.length).toBe(1)
+    expect(mutation.removed[0]).toBe(popped)
   })
 
   it('array shift', function () {
@@ -146,15 +146,15 @@ describe('Observer', function () {
     var ob = Observer.create(arr)
     ob.on('mutate', spy)
     arr.shift()
-    expect(spy.mostRecentCall.args[0]).toEqual('')
-    expect(spy.mostRecentCall.args[1]).toEqual(arr)
+    expect(spy.mostRecentCall.args[0]).toBe('')
+    expect(spy.mostRecentCall.args[1]).toBe(arr)
     var mutation = spy.mostRecentCall.args[2]
     expect(mutation).toBeDefined()
-    expect(mutation.method).toEqual('shift')
-    expect(mutation.index).toEqual(0)
-    expect(mutation.inserted.length).toEqual(0)
-    expect(mutation.removed.length).toEqual(1)
-    expect(mutation.removed[0]).toEqual(shifted)
+    expect(mutation.method).toBe('shift')
+    expect(mutation.index).toBe(0)
+    expect(mutation.inserted.length).toBe(0)
+    expect(mutation.removed.length).toBe(1)
+    expect(mutation.removed[0]).toBe(shifted)
     // test index update after mutation
     ob.on('set', spy)
     arr[0].a = 4
@@ -167,15 +167,15 @@ describe('Observer', function () {
     var ob = Observer.create(arr)
     ob.on('mutate', spy)
     arr.unshift(unshifted)
-    expect(spy.mostRecentCall.args[0]).toEqual('')
-    expect(spy.mostRecentCall.args[1]).toEqual(arr)
+    expect(spy.mostRecentCall.args[0]).toBe('')
+    expect(spy.mostRecentCall.args[1]).toBe(arr)
     var mutation = spy.mostRecentCall.args[2]
     expect(mutation).toBeDefined()
-    expect(mutation.method).toEqual('unshift')
-    expect(mutation.index).toEqual(0)
-    expect(mutation.removed.length).toEqual(0)
-    expect(mutation.inserted.length).toEqual(1)
-    expect(mutation.inserted[0]).toEqual(unshifted)
+    expect(mutation.method).toBe('unshift')
+    expect(mutation.index).toBe(0)
+    expect(mutation.removed.length).toBe(0)
+    expect(mutation.inserted.length).toBe(1)
+    expect(mutation.inserted[0]).toBe(unshifted)
     // test index update after mutation
     ob.on('set', spy)
     arr[1].a = 4
@@ -189,16 +189,16 @@ describe('Observer', function () {
     var ob = Observer.create(arr)
     ob.on('mutate', spy)
     arr.splice(1, 1, inserted)
-    expect(spy.mostRecentCall.args[0]).toEqual('')
-    expect(spy.mostRecentCall.args[1]).toEqual(arr)
+    expect(spy.mostRecentCall.args[0]).toBe('')
+    expect(spy.mostRecentCall.args[1]).toBe(arr)
     var mutation = spy.mostRecentCall.args[2]
     expect(mutation).toBeDefined()
-    expect(mutation.method).toEqual('splice')
-    expect(mutation.index).toEqual(1)
-    expect(mutation.removed.length).toEqual(1)
-    expect(mutation.inserted.length).toEqual(1)
-    expect(mutation.removed[0]).toEqual(removed)
-    expect(mutation.inserted[0]).toEqual(inserted)
+    expect(mutation.method).toBe('splice')
+    expect(mutation.index).toBe(1)
+    expect(mutation.removed.length).toBe(1)
+    expect(mutation.inserted.length).toBe(1)
+    expect(mutation.removed[0]).toBe(removed)
+    expect(mutation.inserted[0]).toBe(inserted)
     // test index update after mutation
     ob.on('set', spy)
     arr[1].a = 4
@@ -212,14 +212,14 @@ describe('Observer', function () {
     arr.sort(function (a, b) {
       return a.a < b.a ? 1 : -1
     })
-    expect(spy.mostRecentCall.args[0]).toEqual('')
-    expect(spy.mostRecentCall.args[1]).toEqual(arr)
+    expect(spy.mostRecentCall.args[0]).toBe('')
+    expect(spy.mostRecentCall.args[1]).toBe(arr)
     var mutation = spy.mostRecentCall.args[2]
     expect(mutation).toBeDefined()
-    expect(mutation.method).toEqual('sort')
+    expect(mutation.method).toBe('sort')
     expect(mutation.index).toBeUndefined()
-    expect(mutation.removed.length).toEqual(0)
-    expect(mutation.inserted.length).toEqual(0)
+    expect(mutation.removed.length).toBe(0)
+    expect(mutation.inserted.length).toBe(0)
     // test index update after mutation
     ob.on('set', spy)
     arr[1].a = 4
@@ -231,14 +231,14 @@ describe('Observer', function () {
     var ob = Observer.create(arr)
     ob.on('mutate', spy)
     arr.reverse()
-    expect(spy.mostRecentCall.args[0]).toEqual('')
-    expect(spy.mostRecentCall.args[1]).toEqual(arr)
+    expect(spy.mostRecentCall.args[0]).toBe('')
+    expect(spy.mostRecentCall.args[1]).toBe(arr)
     var mutation = spy.mostRecentCall.args[2]
     expect(mutation).toBeDefined()
-    expect(mutation.method).toEqual('reverse')
+    expect(mutation.method).toBe('reverse')
     expect(mutation.index).toBeUndefined()
-    expect(mutation.removed.length).toEqual(0)
-    expect(mutation.inserted.length).toEqual(0)
+    expect(mutation.removed.length).toBe(0)
+    expect(mutation.inserted.length).toBe(0)
     // test index update after mutation
     ob.on('set', spy)
     arr[1].a = 4
@@ -278,16 +278,16 @@ describe('Observer', function () {
     var removed = arr[1]
     arr.$set(1, inserted)
 
-    expect(spy.mostRecentCall.args[0]).toEqual('')
-    expect(spy.mostRecentCall.args[1]).toEqual(arr)
+    expect(spy.mostRecentCall.args[0]).toBe('')
+    expect(spy.mostRecentCall.args[1]).toBe(arr)
     var mutation = spy.mostRecentCall.args[2]
     expect(mutation).toBeDefined()
-    expect(mutation.method).toEqual('splice')
-    expect(mutation.index).toEqual(1)
-    expect(mutation.removed.length).toEqual(1)
-    expect(mutation.inserted.length).toEqual(1)
-    expect(mutation.removed[0]).toEqual(removed)
-    expect(mutation.inserted[0]).toEqual(inserted)
+    expect(mutation.method).toBe('splice')
+    expect(mutation.index).toBe(1)
+    expect(mutation.removed.length).toBe(1)
+    expect(mutation.inserted.length).toBe(1)
+    expect(mutation.removed[0]).toBe(removed)
+    expect(mutation.inserted[0]).toBe(inserted)
 
     ob.on('set', spy)
     arr[1].a = 4
@@ -300,15 +300,15 @@ describe('Observer', function () {
     ob.on('mutate', spy)
     var removed = arr.$remove(0)
 
-    expect(spy.mostRecentCall.args[0]).toEqual('')
-    expect(spy.mostRecentCall.args[1]).toEqual(arr)
+    expect(spy.mostRecentCall.args[0]).toBe('')
+    expect(spy.mostRecentCall.args[1]).toBe(arr)
     var mutation = spy.mostRecentCall.args[2]
     expect(mutation).toBeDefined()
-    expect(mutation.method).toEqual('splice')
-    expect(mutation.index).toEqual(0)
-    expect(mutation.removed.length).toEqual(1)
-    expect(mutation.inserted.length).toEqual(0)
-    expect(mutation.removed[0]).toEqual(removed)
+    expect(mutation.method).toBe('splice')
+    expect(mutation.index).toBe(0)
+    expect(mutation.removed.length).toBe(1)
+    expect(mutation.inserted.length).toBe(0)
+    expect(mutation.removed[0]).toBe(removed)
 
     ob.on('set', spy)
     arr[0].a = 3

+ 103 - 0
test/unit/template-parser.js

@@ -0,0 +1,103 @@
+var templateParser = require('../../src/parse/template')
+var parse = templateParser.parse
+var testString = '<div>hello</div><p class="test">world</p>'
+
+describe('Template Parser', function () {
+  
+  it('should return same if argument is already a fragment', function () {
+    var frag = document.createDocumentFragment()
+    var res = parse(frag)
+    expect(res).toBe(frag)
+  })
+
+  // only test template node if it works in the browser being tested.
+  var templateNode = document.createElement('template')
+  if (templateNode.content) {
+    it('should return content if argument is a valid template node', function () {
+      var res = parse(templateNode)
+      expect(res).toBe(templateNode.content)
+    })
+  }
+
+  it('should parse if argument is a template string', function () {
+    var res = parse(testString)
+    expect(res instanceof DocumentFragment).toBeTruthy()
+    expect(res.childNodes.length).toBe(2)
+    expect(res.querySelector('.test').textContent).toBe('world')
+  })
+
+  it('should parse textContent if argument is a script node', function () {
+    var node = document.createElement('script')
+    node.textContent = testString
+    var res = parse(node)
+    expect(res instanceof DocumentFragment).toBeTruthy()
+    expect(res.childNodes.length).toBe(2)
+    expect(res.querySelector('.test').textContent).toBe('world')
+  })
+
+  it('should parse outerHTML if argument is a normal node', function () {
+    var node = document.createElement('div')
+    node.innerHTML = testString
+    var res = parse(node)
+    expect(res instanceof DocumentFragment).toBeTruthy()
+    expect(res.childNodes.length).toBe(1)
+    expect(res.querySelector('div .test').textContent).toBe('world')
+  })
+
+  it('should retrieve and parse if argument is an id selector', function () {
+    var node = document.createElement('script')
+    node.setAttribute('id', 'template-test')
+    node.setAttribute('type', 'x/template')
+    node.textContent = testString
+    document.head.appendChild(node)
+    var res = parse('#template-test')
+    expect(res instanceof DocumentFragment).toBeTruthy()
+    expect(res.childNodes.length).toBe(2)
+    expect(res.querySelector('.test').textContent).toBe('world')
+    document.head.removeChild(node)
+  })
+
+  it('should work for table elements', function () {
+    var res = parse('<td>hello</td>')
+    expect(res instanceof DocumentFragment).toBeTruthy()
+    expect(res.childNodes.length).toBe(1)
+    expect(res.firstChild.tagName).toBe('TD')
+    expect(res.firstChild.textContent).toBe('hello')
+  })
+
+  it('should work for option elements', function () {
+    var res = parse('<option>hello</option>')
+    expect(res instanceof DocumentFragment).toBeTruthy()
+    expect(res.childNodes.length).toBe(1)
+    expect(res.firstChild.tagName).toBe('OPTION')
+    expect(res.firstChild.textContent).toBe('hello')
+  })
+
+  it('should work for svg elements', function () {
+    var res = parse('<circle></circle>')
+    expect(res instanceof DocumentFragment).toBeTruthy()
+    expect(res.childNodes.length).toBe(1)
+    // SVG tagNames should be lowercase because they are XML nodes not HTML
+    expect(res.firstChild.tagName).toBe('circle')
+    expect(res.firstChild.namespaceURI).toBe('http://www.w3.org/2000/svg')
+  })
+
+  it('should cache template strings', function () {
+    var res1 = parse(testString)
+    var res2 = parse(testString)
+    expect(res1).toBe(res2)
+  })
+
+  it('should cache id selectors', function () {
+    var node = document.createElement('script')
+    node.setAttribute('id', 'template-test')
+    node.setAttribute('type', 'x/template')
+    node.textContent = '<div>never seen before content</div>'
+    document.head.appendChild(node)
+    var res1 = parse('#template-test')
+    var res2 = parse('#template-test')
+    expect(res1).toBe(res2)
+    document.head.removeChild(node)
+  })
+
+})