import Alpine from 'alpinejs'
import { wait } from '@testing-library/dom'
global.MutationObserver = class {
observe() {}
}
test('x-for', async () => {
document.body.innerHTML = `
`
Alpine.start()
expect(document.querySelectorAll('span').length).toEqual(1)
expect(document.querySelectorAll('span')[0].textContent).toEqual('foo')
document.querySelector('button').click()
await wait(() => { expect(document.querySelectorAll('span').length).toEqual(2) })
expect(document.querySelectorAll('span')[0].textContent).toEqual('foo')
expect(document.querySelectorAll('span')[1].textContent).toEqual('bar')
})
test('removes all elements when array is empty and previously had one item', async () => {
document.body.innerHTML = `
`
Alpine.start()
expect(document.querySelectorAll('span').length).toEqual(1)
document.querySelector('button').click()
await wait(() => { expect(document.querySelectorAll('span').length).toEqual(0) })
})
test('removes all elements when array is empty and previously had multiple items', async () => {
document.body.innerHTML = `
`
Alpine.start()
expect(document.querySelectorAll('span').length).toEqual(2)
document.querySelector('button').click()
await wait(() => { expect(document.querySelectorAll('span').length).toEqual(3) })
})
test('can use index inside of loop', async () => {
document.body.innerHTML = `
`
Alpine.start()
expect(document.querySelector('h1').textContent).toEqual('0')
expect(document.querySelector('h2').textContent).toEqual('0')
})
test('can use third iterator param (collection) inside of loop', async () => {
document.body.innerHTML = `
`
Alpine.start()
expect(document.querySelector('h1').textContent).toEqual('foo')
expect(document.querySelector('h2').textContent).toEqual('foo')
})
test('can use x-if in conjunction with x-for', async () => {
document.body.innerHTML = `
`
Alpine.start()
expect(document.querySelectorAll('span').length).toEqual(0)
document.querySelector('button').click()
await new Promise(resolve => setTimeout(resolve, 1))
expect(document.querySelectorAll('span').length).toEqual(2)
document.querySelector('button').click()
await new Promise(resolve => setTimeout(resolve, 1))
expect(document.querySelectorAll('span').length).toEqual(0)
})
test('listeners in loop get fresh iteration data even though they are only registered initially', async () => {
document.body.innerHTML = `
`
Alpine.start()
await wait(() => { expect(document.querySelectorAll('h1').length).toEqual(1) })
await wait(() => { expect(document.querySelectorAll('h2').length).toEqual(2) })
expect(document.querySelectorAll('h2')[0].textContent).toEqual('bob')
expect(document.querySelectorAll('h2')[1].textContent).toEqual('lob')
document.querySelector('button').click()
await wait(() => { expect(document.querySelectorAll('h2').length).toEqual(3) })
expect(document.querySelectorAll('h2')[0].textContent).toEqual('bob')
expect(document.querySelectorAll('h2')[1].textContent).toEqual('lob')
expect(document.querySelectorAll('h2')[2].textContent).toEqual('law')
})
test('x-for updates the right elements when new item are inserted at the beginning of the list', async () => {
document.body.innerHTML = `
`
Alpine.start()
await wait(() => { expect(document.querySelectorAll('h1').length).toEqual(2) })
await wait(() => { expect(document.querySelectorAll('h2').length).toEqual(4) })
expect(document.querySelectorAll('h2')[0].textContent).toEqual('foo: bob = 0')
expect(document.querySelectorAll('h2')[1].textContent).toEqual('foo: lob = 0')
expect(document.querySelectorAll('h2')[2].textContent).toEqual('baz: bab = 0')
expect(document.querySelectorAll('h2')[3].textContent).toEqual('baz: lab = 0')
expect(document._alerts.length).toEqual(0)
document.querySelectorAll('h2')[0].click()
await wait(() => {
expect(document.querySelectorAll('h2')[0].textContent).toEqual('foo: bob = 1')
expect(document.querySelectorAll('h2')[1].textContent).toEqual('foo: lob = 0')
expect(document.querySelectorAll('h2')[2].textContent).toEqual('baz: bab = 0')
expect(document.querySelectorAll('h2')[3].textContent).toEqual('baz: lab = 0')
expect(document._alerts.length).toEqual(1)
expect(document._alerts[0]).toEqual('foo: bob = 1')
})
document.querySelectorAll('h2')[2].click()
await wait(() => {
expect(document.querySelectorAll('h2')[0].textContent).toEqual('foo: bob = 1')
expect(document.querySelectorAll('h2')[1].textContent).toEqual('foo: lob = 0')
expect(document.querySelectorAll('h2')[2].textContent).toEqual('baz: bab = 1')
expect(document.querySelectorAll('h2')[3].textContent).toEqual('baz: lab = 0')
expect(document._alerts.length).toEqual(2)
expect(document._alerts[0]).toEqual('foo: bob = 1')
expect(document._alerts[1]).toEqual('baz: bab = 1')
})
document.querySelectorAll('h2')[0].click()
await wait(() => {
expect(document.querySelectorAll('h2')[0].textContent).toEqual('foo: bob = 2')
expect(document.querySelectorAll('h2')[1].textContent).toEqual('foo: lob = 0')
expect(document.querySelectorAll('h2')[2].textContent).toEqual('baz: bab = 1')
expect(document.querySelectorAll('h2')[3].textContent).toEqual('baz: lab = 0')
expect(document._alerts.length).toEqual(3)
expect(document._alerts[0]).toEqual('foo: bob = 1')
expect(document._alerts[1]).toEqual('baz: bab = 1')
expect(document._alerts[2]).toEqual('foo: bob = 2')
})
})
test('make sure new elements with different keys added to the beginning of a loop are initialized instead of just updated', async () => {
let clickCount = 0
window.registerClick = () => {
clickCount++
}
document.body.innerHTML = `
`
Alpine.start()
document.querySelector('h1').click()
expect(clickCount).toEqual(1)
document.querySelector('button').click()
document.querySelector('h1').click()
expect(clickCount).toEqual(2)
})
test('x-for over range using i in x syntax', async () => {
document.body.innerHTML = `
`
Alpine.start()
expect(document.querySelectorAll('span').length).toEqual(10)
})
test('x-for over range using i in x syntax with data property', async () => {
document.body.innerHTML = `
`
Alpine.start()
expect(document.querySelectorAll('span').length).toEqual(10)
})
test('x-for with an array of numbers', async () => {
document.body.innerHTML = `
`
Alpine.start()
document.querySelector('#push-2').click()
await wait(() => {
expect(document.querySelector('span').textContent).toEqual('2')
})
document.querySelector('#push-3').click()
await wait(() => {
expect(document.querySelectorAll('span').length).toEqual(2)
expect(document.querySelectorAll('span')[1].textContent).toEqual('3')
})
})
test('x-for over range using i in x syntax with i <= 0', async () => {
document.body.innerHTML = `