describe('hx-swap attribute', function() {
  beforeEach(function() {
    this.server = makeServer()
    clearWorkArea()
  })
  afterEach(function() {
    this.server.restore()
    clearWorkArea()
  })
  it('swap innerHTML properly', function() {
    this.server.respondWith('GET', '/test', 'Click Me')
    this.server.respondWith('GET', '/test2', 'Clicked!')
    var div = make('
')
    div.click()
    this.server.respond()
    div.innerHTML.should.equal('Click Me')
    var a = div.querySelector('a')
    a.click()
    this.server.respond()
    a.innerHTML.should.equal('Clicked!')
  })
  it('swap textContent properly with HTML tags', function() {
    this.server.respondWith('GET', '/test', 'Click Me')
    var d1 = make('')
    d1.click()
    should.equal(byId('d1'), d1)
    this.server.respond()
    d1.textContent.should.equal('Click Me')
    should.equal(byId('a1'), null)
  })
  it('swap textContent properly with HTML tags and text', function() {
    this.server.respondWith('GET', '/test', 'text content Click Me')
    var d1 = make('')
    d1.click()
    should.equal(byId('d1'), d1)
    this.server.respond()
    d1.textContent.should.equal('text content Click Me')
    should.equal(byId('a1'), null)
  })
  it('swap textContent ignores OOB swaps', function() {
    this.server.respondWith('GET', '/test', 'hi Click Me')
    var d1 = make('')
    var d2 = make('some text
')
    d1.click()
    should.equal(byId('d1'), d1)
    should.equal(byId('d2'), d2)
    this.server.respond()
    d1.textContent.should.equal('hi Click Me')
    d2.outerHTML.should.equal('some text
')
    should.equal(byId('a1'), null)
  })
  it('swap textContent properly with text', function() {
    this.server.respondWith('GET', '/test', 'plain text')
    var div = make('')
    div.click()
    should.equal(byId('d1'), div)
    this.server.respond()
    div.textContent.should.equal('plain text')
    should.equal(byId('a1'), null)
  })
  it('swap outerHTML properly', function() {
    this.server.respondWith('GET', '/test', 'Click Me')
    this.server.respondWith('GET', '/test2', 'Clicked!')
    var div = make('')
    div.click()
    should.equal(byId('d1'), div)
    this.server.respond()
    should.equal(byId('d1'), null)
    byId('a1').click()
    this.server.respond()
    byId('a1').innerHTML.should.equal('Clicked!')
  })
  it('swap beforebegin properly', function() {
    var i = 0
    this.server.respondWith('GET', '/test', function(xhr) {
      i++
      xhr.respond(200, {}, '' + i + '')
    })
    this.server.respondWith('GET', '/test2', '*')
    var div = make('*
')
    var parent = div.parentElement
    div.click()
    this.server.respond()
    div.innerText.should.equal('*')
    removeWhiteSpace(parent.innerText).should.equal('1*')
    byId('a1').click()
    this.server.respond()
    removeWhiteSpace(parent.innerText).should.equal('**')
    div.click()
    this.server.respond()
    div.innerText.should.equal('*')
    removeWhiteSpace(parent.innerText).should.equal('*2*')
    byId('a2').click()
    this.server.respond()
    removeWhiteSpace(parent.innerText).should.equal('***')
  })
  it('swap afterbegin properly', function() {
    var i = 0
    this.server.respondWith('GET', '/test', function(xhr) {
      i++
      xhr.respond(200, {}, '' + i)
    })
    var div = make('*
')
    div.click()
    this.server.respond()
    div.innerText.should.equal('1*')
    div.click()
    this.server.respond()
    div.innerText.should.equal('21*')
    div.click()
    this.server.respond()
    div.innerText.should.equal('321*')
  })
  it('swap afterbegin properly with no initial content', function() {
    var i = 0
    this.server.respondWith('GET', '/test', function(xhr) {
      i++
      xhr.respond(200, {}, '' + i)
    })
    var div = make('')
    div.click()
    this.server.respond()
    div.innerText.should.equal('1')
    div.click()
    this.server.respond()
    div.innerText.should.equal('21')
    div.click()
    this.server.respond()
    div.innerText.should.equal('321')
  })
  it('swap afterend properly', function() {
    var i = 0
    this.server.respondWith('GET', '/test', function(xhr) {
      i++
      xhr.respond(200, {}, '' + i + '')
    })
    this.server.respondWith('GET', '/test2', '*')
    var div = make('*
')
    var parent = div.parentElement
    div.click()
    this.server.respond()
    div.innerText.should.equal('*')
    removeWhiteSpace(parent.innerText).should.equal('*1')
    byId('a1').click()
    this.server.respond()
    removeWhiteSpace(parent.innerText).should.equal('**')
    div.click()
    this.server.respond()
    div.innerText.should.equal('*')
    removeWhiteSpace(parent.innerText).should.equal('*2*')
    byId('a2').click()
    this.server.respond()
    removeWhiteSpace(parent.innerText).should.equal('***')
  })
  it('handles beforeend properly', function() {
    var i = 0
    this.server.respondWith('GET', '/test', function(xhr) {
      i++
      xhr.respond(200, {}, '' + i)
    })
    var div = make('*
')
    div.click()
    this.server.respond()
    div.innerText.should.equal('*1')
    div.click()
    this.server.respond()
    div.innerText.should.equal('*12')
    div.click()
    this.server.respond()
    div.innerText.should.equal('*123')
  })
  it('handles beforeend properly with no initial content', function() {
    var i = 0
    this.server.respondWith('GET', '/test', function(xhr) {
      i++
      xhr.respond(200, {}, '' + i)
    })
    var div = make('')
    div.click()
    this.server.respond()
    div.innerText.should.equal('1')
    div.click()
    this.server.respond()
    div.innerText.should.equal('12')
    div.click()
    this.server.respond()
    div.innerText.should.equal('123')
  })
  it('properly parses various swap specifications', function() {
    var swapSpec = htmx._('getSwapSpecification') // internal function for swap spec
    swapSpec(make('')).swapStyle.should.equal('innerHTML')
    swapSpec(make("")).swapStyle.should.equal('innerHTML')
    swapSpec(make("")).swapDelay.should.equal(0)
    swapSpec(make("")).settleDelay.should.equal(0) // set to 0 in tests
    swapSpec(make("")).swapDelay.should.equal(10)
    swapSpec(make("")).swapDelay.should.equal(0)
    swapSpec(make("")).swapDelay.should.equal(0)
    swapSpec(make("")).settleDelay.should.equal(10)
    swapSpec(make("")).settleDelay.should.equal(0)
    swapSpec(make("")).settleDelay.should.equal(0)
    swapSpec(make("")).swapDelay.should.equal(10)
    swapSpec(make("")).settleDelay.should.equal(11)
    swapSpec(make("")).swapDelay.should.equal(10)
    swapSpec(make("")).settleDelay.should.equal(11)
    swapSpec(make("")).settleDelay.should.equal(0)
    swapSpec(make("")).settleDelay.should.equal(0)
    swapSpec(make("")).settleDelay.should.equal(0)
    swapSpec(make("")).settleDelay.should.equal(0)
    swapSpec(make("")).settleDelay.should.equal(11)
    swapSpec(make("")).settleDelay.should.equal(11)
    swapSpec(make("")).swapStyle.should.equal('innerHTML')
    swapSpec(make("")).swapDelay.should.equal(10)
    swapSpec(make("")).swapDelay.should.equal(0)
    swapSpec(make("")).swapDelay.should.equal(0)
    swapSpec(make("")).swapStyle.should.equal('innerHTML')
    swapSpec(make("")).settleDelay.should.equal(10)
    swapSpec(make("")).settleDelay.should.equal(0)
    swapSpec(make("")).settleDelay.should.equal(0)
    swapSpec(make("")).swapStyle.should.equal('innerHTML')
    swapSpec(make("")).swapDelay.should.equal(10)
    swapSpec(make("")).settleDelay.should.equal(11)
    swapSpec(make("")).swapDelay.should.equal(0)
    swapSpec(make("")).settleDelay.should.equal(0)
    swapSpec(make("")).swapStyle.should.equal('innerHTML')
    swapSpec(make("")).swapDelay.should.equal(10)
    swapSpec(make("")).settleDelay.should.equal(11)
    swapSpec(make("")).swapDelay.should.equal(10)
    swapSpec(make("")).settleDelay.should.equal(0)
    swapSpec(make("")).swapStyle.should.equal('customstyle')
  })
  it('works with a swap delay', function(done) {
    this.server.respondWith('GET', '/test', 'Clicked!')
    var div = make("")
    div.click()
    this.server.respond()
    div.innerText.should.equal('')
    setTimeout(function() {
      div.innerText.should.equal('Clicked!')
      done()
    }, 30)
  })
  it('works immediately with no swap delay', function(done) {
    this.server.respondWith('GET', '/test', 'Clicked!')
    var div = make(
      ""
    )
    div.click()
    this.server.respond()
    div.innerText.should.equal('Clicked!')
    done()
  })
  it('works with a settle delay', function(done) {
    this.server.respondWith('GET', '/test', "")
    var div = make("")
    div.click()
    this.server.respond()
    div.classList.contains('foo').should.equal(false)
    setTimeout(function() {
      byId('d1').classList.contains('foo').should.equal(true)
      done()
    }, 30)
  })
  it('works with no settle delay', function(done) {
    this.server.respondWith(
      'GET',
      '/test',
      ""
    )
    var div = make(
      ""
    )
    div.click()
    this.server.respond()
    div.classList.contains('foo').should.equal(false)
    setTimeout(function() {
      byId('d1').classList.contains('foo').should.equal(true)
      done()
    }, 30)
  })
  it('swap outerHTML properly  w/ data-* prefix', function() {
    this.server.respondWith('GET', '/test', 'Click Me')
    this.server.respondWith('GET', '/test2', 'Clicked!')
    var div = make('')
    div.click()
    should.equal(byId('d1'), div)
    this.server.respond()
    should.equal(byId('d1'), null)
    byId('a1').click()
    this.server.respond()
    byId('a1').innerHTML.should.equal('Clicked!')
  })
  it('swap none works properly', function() {
    this.server.respondWith('GET', '/test', 'Ooops, swapped')
    var div = make('Foo
')
    div.click()
    this.server.respond()
    div.innerHTML.should.equal('Foo')
  })
  it('swap outerHTML does not trigger htmx:afterSwap on original element', function() {
    this.server.respondWith('GET', '/test', 'Clicked!')
    var div = make('')
    div.addEventListener('htmx:afterSwap', function() {
      count++
    })
    div.click()
    var count = 0
    should.equal(byId('d1'), div)
    this.server.respond()
    should.equal(byId('d1'), null)
    count.should.equal(0)
  })
  it('swap delete works properly', function() {
    this.server.respondWith('GET', '/test', 'Oops, deleted!')
    var div = make('Foo
')
    div.click()
    this.server.respond()
    should.equal(byId('d1'), null)
  })
  it('in presence of bad swap spec, it uses the default swap strategy', function() {
    var initialSwapStyle = htmx.config.defaultSwapStyle
    htmx.config.defaultSwapStyle = 'outerHTML'
    try {
      this.server.respondWith('GET', '/test', 'Clicked!')
      var div = make('')
      var b1 = byId('b1')
      b1.click()
      this.server.respond()
      div.innerHTML.should.equal('Clicked!')
    } finally {
      htmx.config.defaultSwapStyle = initialSwapStyle
    }
  })
  it('hx-swap ignoreTitle works', function() {
    window.document.title = 'Test Title'
    this.server.respondWith('GET', '/test', function(xhr) {
      xhr.respond(200, {}, "htmx rocks!Clicked!")
    })
    var btn = make('')
    btn.click()
    this.server.respond()
    btn.innerText.should.equal('Clicked!')
    window.document.title.should.equal('Test Title')
  })
})