import { tmpl, domBackend, composedBackend, shadowBackend } from '../base/env'
import * as glassEasel from '../../src'
const domHtml = (elem: glassEasel.Element): string => {
const domElem = elem.getBackendElement() as unknown as Element
return domElem.innerHTML
}
const testCases = (testBackend: glassEasel.GeneralBackendContext) => {
describe('binding map update enabled', () => {
test('multi-target update', () => {
const def = glassEasel.registerElement({
template: tmpl(`
{{c}}
`),
data: {
c: 'abc',
},
})
const elem = glassEasel.Component.createWithContext('root', def.general(), testBackend)
const child = elem.getShadowRoot()!.getElementById('b')!
expect(domHtml(elem)).toBe('abc
')
expect(child.dataset.a).toBe('abc')
elem.setData({ c: 'def' })
expect(domHtml(elem)).toBe('def
')
expect(child.dataset.a).toBe('def')
})
test('model data path update', () => {
const subComp = glassEasel.registerElement({
template: tmpl(`
{{propA}}
`),
properties: {
propA: Number,
},
})
const def = glassEasel.registerElement({
using: {
comp: subComp.general(),
},
template: tmpl(`
{{ ['A', 'B', 'C'][index + 1] }}
`),
data: {
index: 0,
list: [
{
a: 123,
},
{
a: 456,
},
],
},
})
const elem = glassEasel.Component.createWithContext('root', def, testBackend)
const comp = elem.getShadowRoot()!.getElementById('comp') as glassEasel.GeneralComponent
expect(domHtml(elem)).toBe('123
B')
comp.setData({ propA: 789 })
expect(domHtml(elem)).toBe('789
B')
expect(elem.data.list).toEqual([{ a: 789 }, { a: 456 }])
elem.setData({ index: 1 })
expect(domHtml(elem)).toBe('456
C')
expect(elem.data.list).toEqual([{ a: 789 }, { a: 456 }])
comp.setData({ propA: 123 })
expect(domHtml(elem)).toBe('123
C')
expect(elem.data.list).toEqual([{ a: 789 }, { a: 123 }])
})
})
describe('binding map update forced', () => {
test('mixed usage in multiple components', () => {
const subComp = glassEasel.registerElement({
properties: {
content: String,
propA: Number,
},
template: tmpl(`
{{content}}
`),
})
const def = glassEasel.registerElement({
using: {
'sub-comp': subComp.general(),
},
template: tmpl(
`
`,
{ updateMode: 'bindingMap' },
),
data: {
a: 123,
c: 'abc',
},
})
const elem = glassEasel.Component.createWithContext('root', def, testBackend)
const child = (
elem.getShadowRoot()!.childNodes[0] as glassEasel.GeneralComponent
).asInstanceOf(subComp)!
expect(domHtml(elem)).toBe('abc
')
elem.setData({ c: 'def' })
expect(domHtml(elem)).toBe('def
')
child.setData({ propA: 456 })
expect(elem.data.a).toBe(456)
child.setData({ propA: 789 })
expect(elem.data.a).toBe(789)
})
test('ignore fields with usage in if position', () => {
const def = glassEasel.registerElement({
template: tmpl(
`
{{a}}
{{b}}
{{c}}
{{c}}
`,
{ updateMode: 'bindingMap' },
),
data: {
a: 1,
b: 2,
c: 3,
},
})
const elem = glassEasel.Component.createWithContext('root', def.general(), testBackend)
expect(domHtml(elem)).toBe('1
2
3
3
')
elem.setData({ b: 20 })
expect(domHtml(elem)).toBe('1
2
3
3
')
elem.setData({ c: 30 })
expect(domHtml(elem)).toBe('1
2
3
3
')
elem.setData({ a: 10 })
expect(domHtml(elem)).toBe('10
2
3
3
')
elem.setData({ a: 100, b: 200 })
expect(domHtml(elem)).toBe('100
2
3
3
')
})
test('ignore fields with usage in for position', () => {
const def = glassEasel.registerElement({
template: tmpl(
`
{{a}}
{{b}}
{{c}}
{{c}}
`,
{ updateMode: 'bindingMap' },
),
data: {
a: 1,
b: 2,
c: 3,
},
})
const elem = glassEasel.Component.createWithContext('root', def.general(), testBackend)
expect(domHtml(elem)).toBe('1
2
3
3
3
')
elem.setData({ b: 20 })
expect(domHtml(elem)).toBe('1
2
3
3
3
')
elem.setData({ c: 30 })
expect(domHtml(elem)).toBe('1
2
3
3
3
')
elem.setData({ a: 10 })
expect(domHtml(elem)).toBe('10
2
3
3
3
')
elem.setData({ a: 100, b: 200 })
expect(domHtml(elem)).toBe('100
2
3
3
3
')
})
test('ignore fields with usage in template position', () => {
const def = glassEasel.registerElement({
template: tmpl(
`
{{c}}
{{a}}
{{b}}
{{c}}
`,
{ updateMode: 'bindingMap' },
),
data: {
a: 1,
b: 'child',
c: 3,
},
})
const elem = glassEasel.Component.createWithContext('root', def.general(), testBackend)
expect(domHtml(elem)).toBe('1
child
3
3
')
elem.setData({ b: 20 })
expect(domHtml(elem)).toBe('1
child
3
3
')
elem.setData({ c: 30 })
expect(domHtml(elem)).toBe('1
child
3
3
')
elem.setData({ a: 10 })
expect(domHtml(elem)).toBe('10
child
3
3
')
elem.setData({ a: 100, b: 200 })
expect(domHtml(elem)).toBe('100
child
3
3
')
})
test('ignore fields with usage in slot position', () => {
const def = glassEasel.registerElement({
template: tmpl(
`
{{a}}
{{b}}
`,
{ updateMode: 'bindingMap' },
),
data: {
a: 1,
b: 2,
},
})
const elem = glassEasel.Component.createWithContext('root', def.general(), testBackend)
expect(domHtml(elem)).toBe('1
2
')
elem.setData({ b: 20 })
expect(domHtml(elem)).toBe('1
2
')
elem.setData({ a: 10 })
expect(domHtml(elem)).toBe('10
2
')
elem.setData({ a: 100, b: 200 })
expect(domHtml(elem)).toBe('100
2
')
})
test('ignore fields with usage in let-var position', () => {
const def = glassEasel.registerElement({
template: tmpl(
`
{{a}}
{{b}}
`,
{ updateMode: 'bindingMap' },
),
data: {
a: 1,
b: 2,
},
})
const elem = glassEasel.Component.createWithContext('root', def.general(), testBackend)
expect(domHtml(elem)).toBe('1
2
')
elem.setData({ b: 20 })
expect(domHtml(elem)).toBe('1
2
')
elem.setData({ a: 10 })
expect(domHtml(elem)).toBe('10
2
')
elem.setData({ a: 100, b: 200 })
expect(domHtml(elem)).toBe('100
2
')
})
})
}
describe('binding map (DOM backend)', () => testCases(domBackend))
describe('binding map (shadow backend)', () => testCases(shadowBackend))
describe('binding map (composed backend)', () => testCases(composedBackend))