github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/themes/wind/static/libs/vue-1.0.24/test/unit/specs/misc_spec.js (about)

     1  // test cases for edge cases & bug fixes
     2  var Vue = require('src')
     3  var _ = Vue.util
     4  
     5  describe('Misc', function () {
     6    it('should handle directive.bind() altering its childNode structure', function () {
     7      var vm = new Vue({
     8        el: document.createElement('div'),
     9        template: '<div v-test>{{test}}</div>',
    10        data: {
    11          test: 'foo'
    12        },
    13        directives: {
    14          test: {
    15            bind: function () {
    16              this.el.insertBefore(document.createTextNode('bar '),
    17                this.el.firstChild)
    18            }
    19          }
    20        }
    21      })
    22      expect(vm.$el.textContent).toBe('bar foo')
    23    })
    24  
    25    it('attached/detached hooks for transcluded components', function () {
    26      var spy1 = jasmine.createSpy('attached')
    27      var spy2 = jasmine.createSpy('detached')
    28      var el = document.createElement('div')
    29      el.innerHTML = '<outer v-ref:outter><inner></inner></outer>'
    30      document.body.appendChild(el)
    31  
    32      var vm = new Vue({
    33        el: el,
    34        components: {
    35          outer: {
    36            template: '<slot></slot>'
    37          },
    38          inner: {
    39            template: 'foo',
    40            attached: spy1,
    41            detached: spy2
    42          }
    43        }
    44      })
    45      expect(spy1).toHaveBeenCalled()
    46      vm.$refs.outter.$remove()
    47      expect(spy2).toHaveBeenCalled()
    48    })
    49  
    50    it('v-for on component root node with replace:true', function () {
    51      var el = document.createElement('div')
    52      var vm = new Vue({
    53        el: el,
    54        template: '<test></test>',
    55        components: {
    56          test: {
    57            data: function () {
    58              return { list: [1, 2, 3] }
    59            },
    60            template: '<div v-for="n in list">{{n}}</div>',
    61            replace: true
    62          }
    63        }
    64      })
    65      expect(vm.$el.innerHTML).toBe('<div>1</div><div>2</div><div>3</div>')
    66    })
    67  
    68    // #922
    69    it('template v-for inside svg', function () {
    70      var el = document.createElement('div')
    71      new Vue({
    72        el: el,
    73        template: '<svg><template v-for="n in list"><text>{{n}}</text></template></svg>',
    74        data: {
    75          list: [1, 2, 3]
    76        }
    77      })
    78      // IE inlines svg namespace
    79      var xmlns = /\s?xmlns=".*svg"/
    80      expect(el.innerHTML.replace(xmlns, '')).toBe('<svg><text>1</text><text>2</text><text>3</text></svg>')
    81    })
    82  
    83    // #1005
    84    it('call lifecycle hooks for child components', function () {
    85      Vue.options.replace = true
    86      var el = document.createElement('div')
    87      var logs = []
    88      function log (n) {
    89        return function () {
    90          logs.push(n)
    91        }
    92      }
    93      document.body.appendChild(el)
    94      var vm = new Vue({
    95        el: el,
    96        attached: log(0),
    97        ready: log(1),
    98        detached: log(2),
    99        beforeDestroy: log(3),
   100        destroyed: log(4),
   101        template: '<div><test></test><test></test></div>',
   102        components: {
   103          test: {
   104            template: '<span>hi</span>',
   105            attached: log(5),
   106            ready: log(6),
   107            detached: log(7),
   108            beforeDestroy: log(8),
   109            destroyed: log(9)
   110          }
   111        }
   112      })
   113      expect(vm.$el.innerHTML).toBe('<span>hi</span><span>hi</span>')
   114      expect(logs.join()).toBe('0,5,6,5,6,1')
   115      logs = []
   116      vm.$destroy(true)
   117      expect(logs.join()).toBe('2,7,7,3,8,9,8,9,4')
   118      Vue.options.replace = false
   119    })
   120  
   121    // #1966
   122    it('call lifecycle hooks for child and grandchild components', function () {
   123      Vue.options.replace = true
   124      var el = document.createElement('div')
   125      var logs = []
   126      function log (n) {
   127        return function () {
   128          logs.push(n)
   129        }
   130      }
   131      document.body.appendChild(el)
   132      var vm = new Vue({
   133        el: el,
   134        attached: log(0),
   135        ready: log(1),
   136        detached: log(2),
   137        beforeDestroy: log(3),
   138        destroyed: log(4),
   139        template: '<div><test></test></div>',
   140        components: {
   141          test: {
   142            attached: log(5),
   143            ready: log(6),
   144            detached: log(7),
   145            beforeDestroy: log(8),
   146            destroyed: log(9),
   147            template: '<div><test-inner></test-inner></div>',
   148            components: {
   149              'test-inner': {
   150                attached: log(10),
   151                ready: log(11),
   152                detached: log(12),
   153                beforeDestroy: log(13),
   154                destroyed: log(14),
   155                template: '<span>hi</span>'
   156              }
   157            }
   158  
   159          }
   160        }
   161      })
   162      expect(vm.$el.innerHTML).toBe('<div><span>hi</span></div>')
   163      expect(logs.join()).toBe('0,5,10,11,6,1')
   164      logs = []
   165      vm.$destroy(true)
   166      expect(logs.join()).toBe('2,7,12,3,8,13,14,9,4')
   167      Vue.options.replace = false
   168    })
   169  
   170    // #1006
   171    it('destroyed hook for components inside v-if', function (done) {
   172      var spy = jasmine.createSpy('v-if destroyed hook')
   173      var vm = new Vue({
   174        el: document.createElement('div'),
   175        template: '<template v-if="ok"><test></test></template>',
   176        data: {
   177          ok: true
   178        },
   179        components: {
   180          test: {
   181            destroyed: spy
   182          }
   183        }
   184      })
   185      vm.ok = false
   186      Vue.nextTick(function () {
   187        expect(spy).toHaveBeenCalled()
   188        done()
   189      })
   190    })
   191  
   192    it('frozen model, root', function (done) {
   193      var vm = new Vue({
   194        el: document.createElement('div'),
   195        template: '{{msg}}',
   196        data: Object.freeze({
   197          msg: 'foo'
   198        })
   199      })
   200      expect(vm.$el.textContent).toBe('foo')
   201      try { vm.msg = 'bar' } catch (e) {}
   202      Vue.nextTick(function () {
   203        expect(vm.$el.textContent).toBe('foo')
   204        done()
   205      })
   206    })
   207  
   208    it('frozen model, non-root', function (done) {
   209      var vm = new Vue({
   210        el: document.createElement('div'),
   211        template: '{{msg}} {{frozen.msg}}',
   212        data: {
   213          msg: 'foo',
   214          frozen: Object.freeze({
   215            msg: 'frozen'
   216          })
   217        }
   218      })
   219      expect(vm.$el.textContent).toBe('foo frozen')
   220      vm.msg = 'bar'
   221      try {
   222        vm.frozen.msg = 'changed'
   223      } catch (error) {
   224        if (!(error instanceof TypeError)) {
   225          throw error
   226        }
   227      }
   228      Vue.nextTick(function () {
   229        expect(vm.$el.textContent).toBe('bar frozen')
   230        done()
   231      })
   232    })
   233  
   234    it('should not trigger deep/Array watchers when digesting', function (done) {
   235      var spy1 = jasmine.createSpy('deep')
   236      var spy2 = jasmine.createSpy('Array')
   237      var spy3 = jasmine.createSpy('test')
   238      var spy4 = jasmine.createSpy('deep-mutated')
   239      var vm = new Vue({
   240        el: document.createElement('div'),
   241        data: {
   242          obj: {},
   243          arr: [],
   244          obj2: {}
   245        },
   246        watch: {
   247          obj: {
   248            handler: spy1,
   249            deep: true
   250          },
   251          arr: spy2,
   252          // if the watcher is watching the added value,
   253          // it should still trigger properly
   254          test: {
   255            handler: spy3,
   256            deep: true
   257          },
   258          // if the object is in fact mutated, it should
   259          // still trigger.
   260          obj2: {
   261            handler: spy4,
   262            deep: true
   263          }
   264        }
   265      })
   266      var test = []
   267      var obj2 = vm.obj2
   268      vm.$set('test', test)
   269      _.set(obj2, 'test', 123)
   270      Vue.nextTick(function () {
   271        expect(spy1).not.toHaveBeenCalled()
   272        expect(spy2).not.toHaveBeenCalled()
   273        expect(spy3).toHaveBeenCalledWith(test, undefined)
   274        expect(spy4).toHaveBeenCalledWith(obj2, obj2)
   275        done()
   276      })
   277    })
   278  
   279    it('handle interpolated textarea', function (done) {
   280      var el = document.createElement('div')
   281      el.innerHTML = '<textarea>hello {{msg}}</textarea>'
   282      var vm = new Vue({
   283        el: el,
   284        data: {
   285          msg: 'test'
   286        }
   287      })
   288      expect(el.innerHTML).toBe('<textarea>hello test</textarea>')
   289      vm.msg = 'world'
   290      Vue.nextTick(function () {
   291        expect(el.innerHTML).toBe('<textarea>hello world</textarea>')
   292        done()
   293      })
   294    })
   295  
   296    it('nested object $set should trigger parent array notify', function (done) {
   297      var vm = new Vue({
   298        el: document.createElement('div'),
   299        template: '{{items | json}}{{items[0].a}}',
   300        data: {
   301          items: [{}]
   302        }
   303      })
   304      expect(vm.$el.textContent).toBe(JSON.stringify(vm.items, null, 2))
   305      _.set(vm.items[0], 'a', 123)
   306      Vue.nextTick(function () {
   307        expect(vm.$el.textContent).toBe(JSON.stringify(vm.items, null, 2) + '123')
   308        done()
   309      })
   310    })
   311  
   312    it('warn unkown custom element', function () {
   313      new Vue({
   314        el: document.createElement('div'),
   315        template: '<custom-stuff></custom-stuff>'
   316      })
   317      expect('Unknown custom element').toHaveBeenWarned()
   318    })
   319  
   320    it('prefer bound attributes over static attributes', function (done) {
   321      var el = document.createElement('div')
   322      var count = 0
   323      var expected = [
   324        'bound',
   325        'bound',
   326        'static',
   327        'bound',
   328        'bound'
   329      ]
   330      function check (title) {
   331        expect(title).toBe(expected[count])
   332        count++
   333        if (count === 4) {
   334          done()
   335        }
   336      }
   337  
   338      new Vue({
   339        el: el,
   340        template:
   341          '<div>' +
   342            '<comp v-bind:title="title"></comp>' +
   343            '<comp title="static" v-bind:title="title"></comp>' +
   344            '<comp title="static"></comp>' +
   345            '<comp :title="title"></comp>' +
   346            '<comp title="static" :title="title"></comp>' +
   347          '</div>',
   348        data: {
   349          title: 'bound'
   350        },
   351        components: {
   352          comp: {
   353            props: ['title'],
   354            created: function () {
   355              check(this.title)
   356            }
   357          }
   358        }
   359      })
   360    })
   361  
   362    it('deep watch for class, style and bind', function (done) {
   363      var el = document.createElement('div')
   364      var vm = new Vue({
   365        el: el,
   366        template: '<div :class="classes" :style="styles" v-bind="attrs"></div>',
   367        data: {
   368          classes: { a: true, b: false },
   369          styles: { color: 'red', fontSize: '14px' },
   370          attrs: { a: 1, b: 2 }
   371        }
   372      })
   373      var div = el.firstChild
   374      expect(div.className).toBe('a')
   375      expect(div.style.color).toBe('red')
   376      expect(div.style.fontSize).toBe('14px')
   377      expect(div.getAttribute('a')).toBe('1')
   378      expect(div.getAttribute('b')).toBe('2')
   379      vm.classes.b = true
   380      vm.styles.color = 'green'
   381      vm.attrs.a = 3
   382      Vue.nextTick(function () {
   383        expect(div.className).toBe('a b')
   384        expect(div.style.color).toBe('green')
   385        expect(div.style.fontSize).toBe('14px')
   386        expect(div.getAttribute('a')).toBe('3')
   387        expect(div.getAttribute('b')).toBe('2')
   388        done()
   389      })
   390    })
   391  
   392    it('IE9 class & :class merge during transclusion', function () {
   393      var vm = new Vue({
   394        el: document.createElement('div'),
   395        template: '<test class="outer"></test>',
   396        components: {
   397          test: {
   398            replace: true,
   399            template: '<div class="static-inner" :class="{\'inner\': true}"></div>'
   400          }
   401        }
   402      })
   403      expect(vm.$el.firstChild.className).toBe('static-inner outer inner')
   404    })
   405  
   406    it('SVG class interpolation', function () {
   407      var vm = new Vue({
   408        el: document.createElement('div'),
   409        template: '<icon class="abc" icon="def"></icon>',
   410        components: {
   411          icon: {
   412            props: ['class', 'icon'],
   413            replace: true,
   414            template: '<svg class="si-icon {{icon}} {{class}}"><use xlink:href=""></use></svg>'
   415          }
   416        }
   417      })
   418      expect(vm.$el.firstChild.getAttribute('class')).toBe('si-icon def abc')
   419    })
   420  
   421    // #1960
   422    it('class interpolation should preserve transition class', function () {
   423      var vm = new Vue({
   424        el: document.createElement('div'),
   425        template: '<div class="{{test}}" transition="test"></div>',
   426        data: {
   427          test: 'foo'
   428        }
   429      })
   430      expect(vm.$el.firstChild.className).toBe('foo test-transition')
   431    })
   432  
   433    it('transclude class merging should skip interpolated class', function () {
   434      var vm = new Vue({
   435        el: document.createElement('div'),
   436        template: '<test class="outer-{{test}}"></test>',
   437        data: {
   438          test: 'foo'
   439        },
   440        components: {
   441          test: {
   442            template: '<div class="inner"></div>',
   443            replace: true
   444          }
   445        }
   446      })
   447      expect(vm.$el.firstChild.className).toBe('outer-foo')
   448    })
   449  
   450    // #2163
   451    it('slot compilation order with v-if', function () {
   452      var vm = new Vue({
   453        el: document.createElement('div'),
   454        template:
   455          '<test>' +
   456            '<div slot="one">slot1</div>' +
   457            'default content' +
   458          '</test>',
   459        components: {
   460          test: {
   461            template:
   462              '<div>' +
   463                '<slot v-if="true"></slot> ' +
   464                '<slot name="one"></slot>' +
   465              '</div>',
   466            replace: true
   467          }
   468        }
   469      })
   470      expect(vm.$el.textContent).toBe('default content slot1')
   471    })
   472  
   473    // #2426
   474    it('class merge untrimmed', function () {
   475      expect(function () {
   476        new Vue({
   477          el: document.createElement('div'),
   478          template: '<test class="p1 p2 "></test>',
   479          components: {
   480            test: {
   481              template: '<div class="hi"></div>',
   482              replace: true
   483            }
   484          }
   485        })
   486      }).not.toThrow()
   487    })
   488  
   489    // #2445
   490    it('fragment attach hook should check if child is inDoc', function (done) {
   491      var el = document.createElement('div')
   492      document.body.appendChild(el)
   493      var spyParent = jasmine.createSpy('attached parent')
   494      var spyChild = jasmine.createSpy('attached child')
   495  
   496      new Vue({
   497        el: el,
   498        template: '<comp v-for="n in 1"></comp>',
   499        components: {
   500          comp: {
   501            template: '<div><child></child></div>',
   502            attached: function () {
   503              expect(_.inDoc(this.$el)).toBe(true)
   504              spyParent()
   505            },
   506            activate: function (next) {
   507              setTimeout(function () {
   508                next()
   509                check()
   510              }, 100)
   511            },
   512            components: {
   513              child: {
   514                template: 'foo',
   515                attached: spyChild
   516              }
   517            }
   518          }
   519        }
   520      })
   521  
   522      function check () {
   523        expect(spyParent).toHaveBeenCalled()
   524        expect(spyChild).toHaveBeenCalled()
   525        done()
   526      }
   527    })
   528  
   529    // #2500
   530    it('template parser tag match should include hyphen', function () {
   531      var vm = new Vue({
   532        el: document.createElement('div'),
   533        template: '<div>{{{ test }}}</div>',
   534        data: {
   535          test: '<image-field></image-field>'
   536        }
   537      })
   538      expect(vm.$el.querySelector('image-field').namespaceURI).not.toMatch(/svg/)
   539    })
   540  
   541    // #2657
   542    it('template v-for with v-if', function () {
   543      var vm = new Vue({
   544        el: document.createElement('div'),
   545        template: '<div><template v-for="n in 6" v-if="n % 2">{{ n }}</template></div>'
   546      })
   547      expect(vm.$el.textContent).toBe('135')
   548    })
   549  
   550    // #2821
   551    it('batcher should keep flushing until all queues are depleted', function (done) {
   552      var spy = jasmine.createSpy()
   553      var vm = new Vue({
   554        el: document.createElement('div'),
   555        template: '<test :prop="model"></test>',
   556        data: {
   557          model: 0,
   558          count: 0
   559        },
   560        watch: {
   561          count: function () {
   562            this.model++
   563          }
   564        },
   565        components: {
   566          test: {
   567            props: ['prop'],
   568            watch: {
   569              prop: spy
   570            }
   571          }
   572        }
   573      })
   574      vm.count++
   575      Vue.nextTick(function () {
   576        expect(spy).toHaveBeenCalled()
   577        done()
   578      })
   579    })
   580  })