import { haveAttribute, haveLength, haveText, haveValue, haveHtml, html, test } from '../../utils'
test('can morph components and preserve Alpine state',
[html`
`],
({ get }, reload, window, document) => {
let toHtml = document.querySelector('div').outerHTML
get('span').should(haveText('bar'))
get('button').click()
get('span').should(haveText('baz'))
get('div').then(([el]) => window.Alpine.morph(el, toHtml))
get('span').should(haveText('baz'))
},
)
test('morphing target uses outer Alpine scope',
[html`
`],
({ get }, reload, window, document) => {
let toHtml = document.querySelector('div').outerHTML
get('span').should(haveText('bar'))
get('button').click()
get('span').should(haveText('baz'))
get('div').then(([el]) => window.Alpine.morph(el, toHtml))
get('span').should(haveText('baz'))
},
)
test('can morph with HTML change and preserve Alpine state',
[html`
`],
({ get }, reload, window, document) => {
let toHtml = document.querySelector('div').outerHTML.replace('Change Foo', 'Changed Foo')
get('span').should(haveText('bar'))
get('button').click()
get('span').should(haveText('baz'))
get('button').should(haveText('Change Foo'))
get('div').then(([el]) => window.Alpine.morph(el, toHtml))
get('span').should(haveText('baz'))
get('button').should(haveText('Changed Foo'))
},
)
test('morphing an element with multiple nested Alpine components preserves scope',
[html`
`],
({ get }, reload, window, document) => {
let toHtml = document.querySelector('div').outerHTML
get('span').should(haveText('bar'))
get('h1').should(haveText('lob'))
get('button').click()
get('a').click()
get('span').should(haveText('baz'))
get('h1').should(haveText('law'))
get('div').then(([el]) => window.Alpine.morph(el, toHtml))
get('span').should(haveText('baz'))
get('h1').should(haveText('law'))
},
)
test('can morph teleports',
[html`
`],
({ get }, reload, window, document) => {
let toHtml = html`
`
get('h1').should(haveText('1'))
get('h2').should(haveText('hey'))
get('button').click()
get('h1').should(haveText('2'))
get('h2').should(haveText('hey'))
get('div#a').then(([el]) => window.Alpine.morph(el, toHtml))
get('h1').should(haveText('2'))
get('h2').should(haveText('there'))
},
)
test('can morph',
[html`
`],
({ get }, reload, window, document) => {
let toHtml = html`
`
get('input').type('foo')
get('ul').then(([el]) => window.Alpine.morph(el, toHtml))
get('li').should(haveLength(2))
get('li:nth-of-type(1)').should(haveText('bar'))
get('li:nth-of-type(2)').should(haveText('foo'))
get('li:nth-of-type(1) input').should(haveValue('foo'))
get('li:nth-of-type(2) input').should(haveValue(''))
},
)
test('can morph using lookahead',
[html`
`],
({ get }, reload, window, document) => {
let toHtml = html`
`
get('input').type('foo')
get('ul').then(([el]) => window.Alpine.morph(el, toHtml, {lookahead: true}))
get('li').should(haveLength(3))
get('li:nth-of-type(1)').should(haveText('bar'))
get('li:nth-of-type(2)').should(haveText('baz'))
get('li:nth-of-type(3)').should(haveText('foo'))
get('li:nth-of-type(1) input').should(haveValue(''))
get('li:nth-of-type(2) input').should(haveValue(''))
get('li:nth-of-type(3) input').should(haveValue('foo'))
},
)
test('can morph using keys',
[html`
`],
({ get }, reload, window, document) => {
let toHtml = html`
`
get('input').type('foo')
get('ul').then(([el]) => window.Alpine.morph(el, toHtml))
get('li').should(haveLength(3))
get('li:nth-of-type(1)').should(haveText('bar'))
get('li:nth-of-type(2)').should(haveText('baz'))
get('li:nth-of-type(3)').should(haveText('foo'))
get('li:nth-of-type(1) input').should(haveValue(''))
get('li:nth-of-type(2) input').should(haveValue(''))
get('li:nth-of-type(3) input').should(haveValue('foo'))
},
)
test('can morph using a custom key function',
[html`
`],
({ get }, reload, window, document) => {
let toHtml = html`
`
get('input').type('foo')
get('ul').then(([el]) => window.Alpine.morph(el, toHtml, {key(el) {return el.dataset.key}}))
get('li').should(haveLength(3))
get('li:nth-of-type(1)').should(haveText('bar'))
get('li:nth-of-type(2)').should(haveText('baz'))
get('li:nth-of-type(3)').should(haveText('foo'))
get('li:nth-of-type(1) input').should(haveValue(''))
get('li:nth-of-type(2) input').should(haveValue(''))
get('li:nth-of-type(3) input').should(haveValue('foo'))
},
)
test('can morph using keys with existing key to be moved up',
[html`
`],
({ get }, reload, window, document) => {
let toHtml = html`
`
get('li:nth-of-type(1) input').type('foo')
get('li:nth-of-type(3) input').type('baz')
get('ul').then(([el]) => window.Alpine.morph(el, toHtml))
get('li').should(haveLength(2))
get('li:nth-of-type(1)').should(haveText('foo'))
get('li:nth-of-type(2)').should(haveText('baz'))
get('li:nth-of-type(1) input').should(haveValue('foo'))
get('li:nth-of-type(2) input').should(haveValue('baz'))
},
)
test('can morph text nodes',
[html`Foo
Bar
`],
({ get }, reload, window, document) => {
let toHtml = html`Foo
Baz
`
get('h2').then(([el]) => window.Alpine.morph(el, toHtml))
get('h2').should(haveHtml('Foo
Baz'))
},
)
test('can morph with added element before and siblings are different',
[html`
`],
({ get }, reload, window, document) => {
let toHtml = html`
`
get('button').then(([el]) => window.Alpine.morph(el, toHtml))
get('button > div').should(haveLength(2))
get('button > div:nth-of-type(1)').should(haveText('first'))
get('button > div:nth-of-type(2)').should(haveHtml(`
second
third
`))
},
)
test('can morph using different keys',
[html`
`],
({ get }, reload, window, document) => {
let toHtml = html`
`
get('ul').then(([el]) => window.Alpine.morph(el, toHtml))
get('li').should(haveLength(1))
get('li:nth-of-type(1)').should(haveText('bar'))
get('li:nth-of-type(1)').should(haveAttribute('key', '2'))
},
)
test('can morph elements with dynamic ids',
[html`
`],
({ get }, reload, window, document) => {
let toHtml = html`
`
get('input').type('foo')
get('ul').then(([el]) => window.Alpine.morph(el, toHtml, {
key(el) { return el.id }
}))
get('li:nth-of-type(1) input').should(haveValue('foo'))
},
)
test('can morph different inline nodes',
[html`
Hello World
`],
({ get }, reload, window, document) => {
let toHtml = html`
Welcome Person!
`
get('div').then(([el]) => window.Alpine.morph(el, toHtml))
get('div').should(haveHtml('\n Welcome Person!\n '))
},
)
test('can morph multiple nodes',
[html`
`],
({ get }, reload, window, document) => {
let paragraphs = document.querySelectorAll('p')
window.Alpine.morph(paragraphs[0], '1
2
1 |
`],
({ get }, reload, window, document) => {
let tr = document.querySelector('tr')
window.Alpine.morph(tr, '2 |
')
get('td').should(haveText('2'))
},
)
test('can morph with conditional markers',
[html`
foo
bar
`],
({ get }, reload, window, document) => {
let toHtml = html`
foo
baz
bar
`
get('div:nth-of-type(1) input').type('foo')
get('div:nth-of-type(2) input').type('bar')
get('main').then(([el]) => window.Alpine.morph(el, toHtml))
get('div:nth-of-type(1) input').should(haveValue('foo'))
get('div:nth-of-type(2) input').should(haveValue(''))
get('div:nth-of-type(3) input').should(haveValue('bar'))
},
)
test('can morph with flat-nested conditional markers',
[html`
foo
bar
`],
({ get }, reload, window, document) => {
let toHtml = html`
foo
baz
bar
`
get('div:nth-of-type(1) input').type('foo')
get('div:nth-of-type(2) input').type('bar')
get('main').then(([el]) => window.Alpine.morph(el, toHtml))
get('div:nth-of-type(1) input').should(haveValue('foo'))
get('div:nth-of-type(2) input').should(haveValue(''))
get('div:nth-of-type(3) input').should(haveValue('bar'))
},
)
// '@event' handlers cannot be assigned directly on the element without Alpine's internl monkey patching...
test('can morph @event handlers', [
html`
`],
({ get, click }, reload, window, document) => {
let toHtml = html`
`;
get('button').should(haveText('bar'));
get('button').then(([el]) => window.Alpine.morph(el, toHtml));
get('button').click();
get('button').should(haveText('buzz'));
}
);
test('can morph menu',
[html`
`],
({ get }, reload, window, document) => {
let toHtml = html`
`
get('[data-trigger]').should(haveText('ready'));
get('button[data-trigger').click()
get('input').type('foo')
get('main').then(([el]) => window.Alpine.morph(el, toHtml, {
key(el) { return el.id }
}))
get('input').should(haveValue('foo'))
},
)