github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/public/libs/vue-1.0.24/test/unit/specs/directives/internal/component_spec.js (about)

     1  var _ = require('src/util')
     2  var Vue = require('src')
     3  
     4  describe('Component', function () {
     5    var el
     6    beforeEach(function () {
     7      el = document.createElement('div')
     8      document.body.appendChild(el)
     9    })
    10  
    11    afterEach(function () {
    12      document.body.removeChild(el)
    13    })
    14  
    15    it('static', function () {
    16      new Vue({
    17        el: el,
    18        template: '<test></test>',
    19        components: {
    20          test: {
    21            data: function () {
    22              return { a: 123 }
    23            },
    24            template: '{{a}}'
    25          }
    26        }
    27      })
    28      expect(el.innerHTML).toBe('<test>123</test>')
    29    })
    30  
    31    it('replace', function () {
    32      new Vue({
    33        el: el,
    34        template: '<test></test>',
    35        components: {
    36          test: {
    37            replace: true,
    38            data: function () {
    39              return { a: 123 }
    40            },
    41            template: '<p>{{a}}</p>'
    42          }
    43        }
    44      })
    45      expect(el.innerHTML).toBe('<p>123</p>')
    46    })
    47  
    48    it('"is" on table elements', function () {
    49      var vm = new Vue({
    50        el: el,
    51        template: '<table><tbody><tr is="test"></tr></tbody></table>',
    52        components: {
    53          test: {
    54            data: function () {
    55              return { a: 123 }
    56            },
    57            template: '<td>{{a}}</td>'
    58          }
    59        }
    60      })
    61      expect(el.innerHTML).toBe(vm.$options.template.replace(/<tr.*\/tr>/, '<tr><td>123</td></tr>'))
    62      expect(getWarnCount()).toBe(0)
    63    })
    64  
    65    it('inline-template', function () {
    66      new Vue({
    67        el: el,
    68        template: '<test inline-template>{{a}}</test>',
    69        data: {
    70          a: 'parent'
    71        },
    72        components: {
    73          test: {
    74            data: function () {
    75              return { a: 'child' }
    76            },
    77            template: 'child option template'
    78          }
    79        }
    80      })
    81      expect(el.innerHTML).toBe('<test>child</test>')
    82    })
    83  
    84    it('block replace', function () {
    85      new Vue({
    86        el: el,
    87        template: '<test></test>',
    88        components: {
    89          test: {
    90            replace: true,
    91            data: function () {
    92              return { a: 123, b: 234 }
    93            },
    94            template: '<p>{{a}}</p><p>{{b}}</p>'
    95          }
    96        }
    97      })
    98      expect(el.innerHTML).toBe('<p>123</p><p>234</p>')
    99    })
   100  
   101    it('dynamic', function (done) {
   102      var vm = new Vue({
   103        el: el,
   104        template: '<component :is="view" :view="view"></component>',
   105        data: {
   106          view: 'view-a'
   107        },
   108        components: {
   109          'view-a': {
   110            template: '<div>foo</div>',
   111            replace: true,
   112            data: function () {
   113              return { view: 'a' }
   114            }
   115          },
   116          'view-b': {
   117            template: '<div>bar</div>',
   118            replace: true,
   119            data: function () {
   120              return { view: 'b' }
   121            }
   122          }
   123        }
   124      })
   125      expect(el.innerHTML).toBe('<div view="view-a">foo</div>')
   126      vm.view = 'view-b'
   127      _.nextTick(function () {
   128        expect(el.innerHTML).toBe('<div view="view-b">bar</div>')
   129        vm.view = ''
   130        _.nextTick(function () {
   131          expect(el.innerHTML).toBe('')
   132          done()
   133        })
   134      })
   135    })
   136  
   137    it(':is using raw component constructor', function () {
   138      new Vue({
   139        el: el,
   140        template:
   141          '<component :is="$options.components.test"></component>' +
   142          '<component :is="$options.components.async"></component>',
   143        components: {
   144          test: {
   145            template: 'foo'
   146          },
   147          async: function (resolve) {
   148            resolve({
   149              template: 'bar'
   150            })
   151          }
   152        }
   153      })
   154      expect(el.textContent).toBe('foobar')
   155    })
   156  
   157    it('keep-alive', function (done) {
   158      var spyA = jasmine.createSpy()
   159      var spyB = jasmine.createSpy()
   160      var vm = new Vue({
   161        el: el,
   162        template: '<component :is="view" keep-alive></component>',
   163        data: {
   164          view: 'view-a'
   165        },
   166        components: {
   167          'view-a': {
   168            created: spyA,
   169            template: '<div>foo</div>',
   170            replace: true
   171          },
   172          'view-b': {
   173            created: spyB,
   174            template: '<div>bar</div>',
   175            replace: true
   176          }
   177        }
   178      })
   179      expect(el.innerHTML).toBe('<div>foo</div>')
   180      expect(spyA.calls.count()).toBe(1)
   181      expect(spyB.calls.count()).toBe(0)
   182      vm.view = 'view-b'
   183      _.nextTick(function () {
   184        expect(el.innerHTML).toBe('<div>bar</div>')
   185        expect(spyA.calls.count()).toBe(1)
   186        expect(spyB.calls.count()).toBe(1)
   187        vm.view = 'view-a'
   188        _.nextTick(function () {
   189          expect(el.innerHTML).toBe('<div>foo</div>')
   190          expect(spyA.calls.count()).toBe(1)
   191          expect(spyB.calls.count()).toBe(1)
   192          vm.view = 'view-b'
   193          _.nextTick(function () {
   194            expect(el.innerHTML).toBe('<div>bar</div>')
   195            expect(spyA.calls.count()).toBe(1)
   196            expect(spyB.calls.count()).toBe(1)
   197            done()
   198          })
   199        })
   200      })
   201    })
   202  
   203    it('should compile parent template directives & content in parent scope', function (done) {
   204      var vm = new Vue({
   205        el: el,
   206        data: {
   207          ok: false,
   208          message: 'hello'
   209        },
   210        template: '<test v-show="ok">{{message}}</test>',
   211        components: {
   212          test: {
   213            template: '<div><slot></slot> {{message}}</div>',
   214            replace: true,
   215            data: function () {
   216              return {
   217                message: 'world'
   218              }
   219            }
   220          }
   221        }
   222      })
   223      expect(el.firstChild.style.display).toBe('none')
   224      expect(el.firstChild.textContent).toBe('hello world')
   225      vm.ok = true
   226      vm.message = 'bye'
   227      _.nextTick(function () {
   228        expect(el.firstChild.style.display).toBe('')
   229        expect(el.firstChild.textContent).toBe('bye world')
   230        done()
   231      })
   232    })
   233  
   234    it('parent content + v-if', function (done) {
   235      var vm = new Vue({
   236        el: el,
   237        data: {
   238          ok: false,
   239          message: 'hello'
   240        },
   241        template: '<test v-if="ok">{{message}}</test>',
   242        components: {
   243          test: {
   244            template: '<slot></slot> {{message}}',
   245            data: function () {
   246              return {
   247                message: 'world'
   248              }
   249            }
   250          }
   251        }
   252      })
   253      expect(el.textContent).toBe('')
   254      expect(vm.$children.length).toBe(0)
   255      expect(vm._directives.length).toBe(1) // v-if
   256      vm.ok = true
   257      _.nextTick(function () {
   258        expect(vm.$children.length).toBe(1)
   259        expect(vm._directives.length).toBe(3) // v-if, component, v-text
   260        expect(el.textContent).toBe('hello world')
   261        done()
   262      })
   263    })
   264  
   265    it('props', function () {
   266      new Vue({
   267        el: el,
   268        data: {
   269          list: [{a: 1}, {a: 2}]
   270        },
   271        template: '<test :collection="list"></test>',
   272        components: {
   273          test: {
   274            template: '<ul><li v-for="item in collection">{{item.a}}</li></ul>',
   275            replace: true,
   276            props: ['collection']
   277          }
   278        }
   279      })
   280      expect(el.innerHTML).toBe('<ul><li>1</li><li>2</li></ul>')
   281    })
   282  
   283    it('activate hook for static component', function (done) {
   284      new Vue({
   285        el: el,
   286        template: '<view-a></view-a>',
   287        components: {
   288          'view-a': {
   289            template: 'foo',
   290            activate: function (ready) {
   291              setTimeout(function () {
   292                expect(el.textContent).toBe('')
   293                ready()
   294                expect(el.textContent).toBe('foo')
   295                done()
   296              }, 0)
   297            }
   298          }
   299        }
   300      })
   301    })
   302  
   303    it('multiple activate hooks', function (done) {
   304      var mixinSpy = jasmine.createSpy('mixin activate')
   305      new Vue({
   306        el: el,
   307        template: '<view-a></view-a>',
   308        components: {
   309          'view-a': {
   310            template: 'foo',
   311            mixins: [{
   312              activate: function (done) {
   313                expect(el.textContent).toBe('')
   314                mixinSpy()
   315                done()
   316              }
   317            }],
   318            activate: function (ready) {
   319              setTimeout(function () {
   320                expect(mixinSpy).toHaveBeenCalled()
   321                expect(el.textContent).toBe('')
   322                ready()
   323                expect(el.textContent).toBe('foo')
   324                done()
   325              }, 0)
   326            }
   327          }
   328        }
   329      })
   330    })
   331  
   332    it('activate hook for dynamic components', function (done) {
   333      var next
   334      var vm = new Vue({
   335        el: el,
   336        data: {
   337          view: 'view-a'
   338        },
   339        template: '<component :is="view"></component>',
   340        components: {
   341          'view-a': {
   342            template: 'foo',
   343            activate: function (ready) {
   344              next = ready
   345            }
   346          },
   347          'view-b': {
   348            template: 'bar',
   349            activate: function (ready) {
   350              next = ready
   351            }
   352          }
   353        }
   354      })
   355      expect(next).toBeTruthy()
   356      expect(el.textContent).toBe('')
   357      next()
   358      expect(el.textContent).toBe('foo')
   359      vm.view = 'view-b'
   360      _.nextTick(function () {
   361        expect(el.textContent).toBe('foo')
   362        // old vm is already removed, this is the new vm
   363        expect(vm.$children.length).toBe(1)
   364        next()
   365        expect(el.textContent).toBe('bar')
   366        // ensure switching before ready event correctly
   367        // cleans up the component being waited on.
   368        // see #1152
   369        vm.view = 'view-a'
   370        // store the ready callback for view-a
   371        var callback = next
   372        _.nextTick(function () {
   373          vm.view = 'view-b'
   374          _.nextTick(function () {
   375            expect(vm.$children.length).toBe(1)
   376            expect(vm.$children[0].$el.textContent).toBe('bar')
   377            // calling view-a's ready callback here should not throw
   378            // because it should've been cancelled (#1994)
   379            expect(callback).not.toThrow()
   380            done()
   381          })
   382        })
   383      })
   384    })
   385  
   386    it('activate hook + keep-alive', function (done) {
   387      var next
   388      var vm = new Vue({
   389        el: el,
   390        data: {
   391          view: 'view-a'
   392        },
   393        template: '<component :is="view" keep-alive></component>',
   394        components: {
   395          'view-a': {
   396            template: 'foo',
   397            activate: function (ready) {
   398              next = ready
   399            }
   400          },
   401          'view-b': {
   402            template: 'bar',
   403            activate: function (ready) {
   404              next = ready
   405            }
   406          }
   407        }
   408      })
   409      next()
   410      expect(el.textContent).toBe('foo')
   411      vm.view = 'view-b'
   412      _.nextTick(function () {
   413        expect(vm.$children.length).toBe(2)
   414        next()
   415        expect(el.textContent).toBe('bar')
   416        vm.view = 'view-a'
   417        _.nextTick(function () {
   418          // should switch without the need to emit
   419          // because of keep-alive
   420          expect(el.textContent).toBe('foo')
   421          done()
   422        })
   423      })
   424    })
   425  
   426    it('transition-mode: in-out', function (done) {
   427      var spy1 = jasmine.createSpy('enter')
   428      var spy2 = jasmine.createSpy('leave')
   429      var next
   430      var vm = new Vue({
   431        el: el,
   432        data: {
   433          view: 'view-a'
   434        },
   435        template: '<component :is="view" transition="test" transition-mode="in-out"></component>',
   436        components: {
   437          'view-a': { template: 'foo' },
   438          'view-b': { template: 'bar' }
   439        },
   440        transitions: {
   441          test: {
   442            enter: function (el, done) {
   443              spy1()
   444              next = done
   445            },
   446            leave: function (el, done) {
   447              spy2()
   448              _.nextTick(done)
   449            }
   450          }
   451        }
   452      })
   453      expect(el.textContent).toBe('foo')
   454      vm.view = 'view-b'
   455      _.nextTick(function () {
   456        expect(spy1).toHaveBeenCalled()
   457        expect(spy2).not.toHaveBeenCalled()
   458        expect(el.textContent).toBe('foobar')
   459        next()
   460        _.nextTick(function () {
   461          expect(spy2).toHaveBeenCalled()
   462          _.nextTick(function () {
   463            expect(el.textContent).toBe('bar')
   464            done()
   465          })
   466        })
   467      })
   468    })
   469  
   470    it('transition-mode: out-in', function (done) {
   471      var spy1 = jasmine.createSpy('enter')
   472      var spy2 = jasmine.createSpy('leave')
   473      var next
   474      var vm = new Vue({
   475        el: el,
   476        data: {
   477          view: 'view-a'
   478        },
   479        template: '<component :is="view" transition="test" transition-mode="out-in"></component>',
   480        components: {
   481          'view-a': { template: 'foo' },
   482          'view-b': { template: 'bar' }
   483        },
   484        transitions: {
   485          test: {
   486            enter: function (el, done) {
   487              spy2()
   488              _.nextTick(done)
   489            },
   490            leave: function (el, done) {
   491              spy1()
   492              next = done
   493            }
   494          }
   495        }
   496      })
   497      expect(el.textContent).toBe('foo')
   498      vm.view = 'view-b'
   499      _.nextTick(function () {
   500        expect(spy1).toHaveBeenCalled()
   501        expect(spy2).not.toHaveBeenCalled()
   502        expect(el.textContent).toBe('foo')
   503        next()
   504        expect(spy2).toHaveBeenCalled()
   505        expect(el.textContent).toBe('bar')
   506        done()
   507      })
   508    })
   509  
   510    it('teardown', function (done) {
   511      var vm = new Vue({
   512        el: el,
   513        template: '<component :is="view" keep-alive></component>',
   514        data: {
   515          view: 'test'
   516        },
   517        components: {
   518          test: {},
   519          test2: {}
   520        }
   521      })
   522      vm.view = 'test2'
   523      _.nextTick(function () {
   524        expect(vm.$children.length).toBe(2)
   525        var child = vm.$children[0]
   526        var child2 = vm.$children[1]
   527        vm._directives[0].unbind()
   528        expect(vm._directives[0].cache).toBeNull()
   529        expect(vm.$children.length).toBe(0)
   530        expect(child._isDestroyed).toBe(true)
   531        expect(child2._isDestroyed).toBe(true)
   532        done()
   533      })
   534    })
   535  
   536    it('already mounted warn', function () {
   537      new Vue({
   538        el: document.createElement('test'),
   539        components: {
   540          test: {}
   541        }
   542      })
   543      expect('cannot mount component "test" on already mounted element').toHaveBeenWarned()
   544    })
   545  
   546    it('not found component should not throw', function () {
   547      expect(function () {
   548        new Vue({
   549          el: el,
   550          template: '<div is="non-existent"></div>'
   551        })
   552      }).not.toThrow()
   553    })
   554  
   555    it('warn possible camelCase components', function () {
   556      new Vue({
   557        el: document.createElement('div'),
   558        template: '<HelloWorld></HelloWorld>',
   559        components: {
   560          'hello-world': {}
   561        }
   562      })
   563      expect('did you mean <hello-world>?').toHaveBeenWarned()
   564    })
   565  })