text: import Vue from 'vue'
  import injectStyles from './inject-styles'
  import { isIE9 } from 'core/util/env'
  import { nextFrame } from 'web/runtime/transition-util'
  
  if (!isIE9) {
    describe('Transition mode', () => {
      const duration = injectStyles()
      const components = {
        one: { template: '<div>one</div>' },
        two: { template: '<div>two</div>' }
      }
  
      let el
      beforeEach(() => {
        el = document.createElement('div')
        document.body.appendChild(el)
      })
  
      it('dynamic components, simultaneous', done => {
        const vm = new Vue({
          template: `<div>
            <transition>
              <component :is="view" class="test">
              </component>
            </transition>
          </div>`,
          data: { view: 'one' },
          components
        }).$mount(el)
        expect(vm.$el.textContent).toBe('one')
        vm.view = 'two'
        waitForUpdate(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test v-leave v-leave-active">one</div>' +
            '<div class="test v-enter v-enter-active">two</div>'
          )
        }).thenWaitFor(nextFrame).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test v-leave-active">one</div>' +
            '<div class="test v-enter-active">two</div>'
          )
        }).thenWaitFor(duration + 10).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test">two</div>'
          )
        }).then(done)
      })
  
      it('dynamic components, out-in', done => {
        let next
        const vm = new Vue({
          template: `<div>
            <transition name="test" mode="out-in" @after-leave="afterLeave">
              <component :is="view" class="test">
              </component>
            </transition>
          </div>`,
          data: { view: 'one' },
          components,
          methods: {
            afterLeave () {
              next()
            }
          }
        }).$mount(el)
        expect(vm.$el.textContent).toBe('one')
        vm.view = 'two'
        waitForUpdate(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test test-leave test-leave-active">one</div><!---->'
          )
        }).thenWaitFor(nextFrame).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test test-leave-active">one</div><!---->'
          )
        }).thenWaitFor(_next => { next = _next }).then(() => {
          expect(vm.$el.innerHTML).toBe('<!---->')
        }).thenWaitFor(nextFrame).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test test-enter test-enter-active">two</div>'
          )
        }).thenWaitFor(nextFrame).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test test-enter-active">two</div>'
          )
        }).thenWaitFor(duration + 10).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test">two</div>'
          )
        }).then(done)
      })
  
      // #3440
      it('dynamic components, out-in (with extra re-render)', done => {
        let next
        const vm = new Vue({
          template: `<div>
            <transition name="test" mode="out-in" @after-leave="afterLeave">
              <component :is="view" class="test">
              </component>
            </transition>
          </div>`,
          data: { view: 'one' },
          components,
          methods: {
            afterLeave () {
              next()
            }
          }
        }).$mount(el)
        expect(vm.$el.textContent).toBe('one')
        vm.view = 'two'
        waitForUpdate(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test test-leave test-leave-active">one</div><!---->'
          )
        }).thenWaitFor(nextFrame).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test test-leave-active">one</div><!---->'
          )
          // Force re-render before the element finishes leaving
          // this should not cause the incoming element to enter early
          vm.$forceUpdate()
        }).thenWaitFor(_next => { next = _next }).then(() => {
          expect(vm.$el.innerHTML).toBe('<!---->')
        }).thenWaitFor(nextFrame).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test test-enter test-enter-active">two</div>'
          )
        }).thenWaitFor(nextFrame).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test test-enter-active">two</div>'
          )
        }).thenWaitFor(duration + 10).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test">two</div>'
          )
        }).then(done)
      })
  
      it('dynamic components, in-out', done => {
        let next
        const vm = new Vue({
          template: `<div>
            <transition name="test" mode="in-out" @after-enter="afterEnter">
              <component :is="view" class="test">
              </component>
            </transition>
          </div>`,
          data: { view: 'one' },
          components,
          methods: {
            afterEnter () {
              next()
            }
          }
        }).$mount(el)
        expect(vm.$el.textContent).toBe('one')
        vm.view = 'two'
        waitForUpdate(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test">one</div>' +
            '<div class="test test-enter test-enter-active">two</div>'
          )
        }).thenWaitFor(nextFrame).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test">one</div>' +
            '<div class="test test-enter-active">two</div>'
          )
        }).thenWaitFor(_next => { next = _next }).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test">one</div>' +
            '<div class="test">two</div>'
          )
        }).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test test-leave test-leave-active">one</div>' +
            '<div class="test">two</div>'
          )
        }).thenWaitFor(nextFrame).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test test-leave-active">one</div>' +
            '<div class="test">two</div>'
          )
        }).thenWaitFor(duration + 10).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test">two</div>'
          )
        }).then(done)
      })
  
      it('dynamic components, in-out with early cancel', done => {
        let next
        const vm = new Vue({
          template: `<div>
            <transition name="test" mode="in-out" @after-enter="afterEnter">
              <component :is="view" class="test"></component>
            </transition>
          </div>`,
          data: { view: 'one' },
          components,
          methods: {
            afterEnter () {
              next()
            }
          }
        }).$mount(el)
        expect(vm.$el.textContent).toBe('one')
        vm.view = 'two'
        waitForUpdate(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test">one</div>' +
            '<div class="test test-enter test-enter-active">two</div>'
          )
        }).thenWaitFor(nextFrame).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test">one</div>' +
            '<div class="test test-enter-active">two</div>'
          )
          // switch again before enter finishes,
          // this cancels both enter and leave.
          vm.view = 'one'
        }).then(() => {
          // 1. the pending leaving "one" should be removed instantly.
          // 2. the entering "two" should be placed into its final state instantly.
          // 3. a new "one" is created and entering
          expect(vm.$el.innerHTML).toBe(
            '<div class="test">two</div>' +
            '<div class="test test-enter test-enter-active">one</div>'
          )
        }).thenWaitFor(nextFrame).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test">two</div>' +
            '<div class="test test-enter-active">one</div>'
          )
        }).thenWaitFor(_next => { next = _next }).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test">two</div>' +
            '<div class="test">one</div>'
          )
        }).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test test-leave test-leave-active">two</div>' +
            '<div class="test">one</div>'
          )
        }).thenWaitFor(nextFrame).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test test-leave-active">two</div>' +
            '<div class="test">one</div>'
          )
        }).thenWaitFor(duration + 10).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test">one</div>'
          )
        }).then(done).then(done)
      })
  
      it('normal elements with different keys, simultaneous', done => {
        const vm = new Vue({
          template: `<div>
            <transition>
              <div :key="view" class="test">{{view}}</div>
            </transition>
          </div>`,
          data: { view: 'one' },
          components
        }).$mount(el)
        expect(vm.$el.textContent).toBe('one')
        vm.view = 'two'
        waitForUpdate(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test v-leave v-leave-active">one</div>' +
            '<div class="test v-enter v-enter-active">two</div>'
          )
        }).thenWaitFor(nextFrame).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test v-leave-active">one</div>' +
            '<div class="test v-enter-active">two</div>'
          )
        }).thenWaitFor(duration + 10).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test">two</div>'
          )
        }).then(done)
      })
  
      it('normal elements with different keys, out-in', done => {
        let next
        const vm = new Vue({
          template: `<div>
            <transition name="test" mode="out-in" @after-leave="afterLeave">
              <div :key="view" class="test">{{view}}</div>
            </transition>
          </div>`,
          data: { view: 'one' },
          components,
          methods: {
            afterLeave () {
              next()
            }
          }
        }).$mount(el)
        expect(vm.$el.textContent).toBe('one')
        vm.view = 'two'
        waitForUpdate(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test test-leave test-leave-active">one</div><!---->'
          )
        }).thenWaitFor(nextFrame).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test test-leave-active">one</div><!---->'
          )
        }).thenWaitFor(_next => { next = _next }).then(() => {
          expect(vm.$el.innerHTML).toBe('<!---->')
        }).thenWaitFor(nextFrame).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test test-enter test-enter-active">two</div>'
          )
        }).thenWaitFor(nextFrame).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test test-enter-active">two</div>'
          )
        }).thenWaitFor(duration + 10).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test">two</div>'
          )
        }).then(done)
      })
  
      it('normal elements with different keys, in-out', done => {
        let next
        const vm = new Vue({
          template: `<div>
            <transition name="test" mode="in-out" @after-enter="afterEnter">
              <div :key="view" class="test">{{view}}</div>
            </transition>
          </div>`,
          data: { view: 'one' },
          components,
          methods: {
            afterEnter () {
              next()
            }
          }
        }).$mount(el)
        expect(vm.$el.textContent).toBe('one')
        vm.view = 'two'
        waitForUpdate(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test">one</div>' +
            '<div class="test test-enter test-enter-active">two</div>'
          )
        }).thenWaitFor(nextFrame).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test">one</div>' +
            '<div class="test test-enter-active">two</div>'
          )
        }).thenWaitFor(_next => { next = _next }).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test">one</div>' +
            '<div class="test">two</div>'
          )
        }).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test test-leave test-leave-active">one</div>' +
            '<div class="test">two</div>'
          )
        }).thenWaitFor(nextFrame).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test test-leave-active">one</div>' +
            '<div class="test">two</div>'
          )
        }).thenWaitFor(duration + 10).then(() => {
          expect(vm.$el.innerHTML).toBe(
            '<div class="test">two</div>'
          )
        }).then(done)
      })
  
      it('warn invaid mode', () => {
        new Vue({
          template: '<transition mode="foo"><div>123</div></transition>'
        }).$mount()
        expect('invalid <transition> mode: foo').toHaveBeenWarned()
      })
    })
  }
  