This commit adds the exports entry in each package.json, exposing the public parts of each package and hiding the private ones.
153 lines
5.6 KiB
JavaScript
153 lines
5.6 KiB
JavaScript
import '@lion/fieldset/lion-fieldset';
|
|
import '@lion/input/lion-input';
|
|
import { expect, html, fixture } from '@open-wc/testing';
|
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
import sinon from 'sinon';
|
|
|
|
/**
|
|
* @typedef {import('@lion/input').LionInput} LionInput
|
|
* @typedef {import('@lion/fieldset').LionFieldset} LionFieldset
|
|
* @typedef {import('@lion/core').TemplateResult} TemplateResult
|
|
*/
|
|
const inputFixture = /** @type {(arg: TemplateResult) => Promise<LionInput>} */ (fixture);
|
|
const fieldsetFixture = /** @type {(arg: TemplateResult) => Promise<LionFieldset>} */ (fixture);
|
|
|
|
describe('model value event', () => {
|
|
describe('form path', () => {
|
|
it('should be property', async () => {
|
|
const spy = sinon.spy();
|
|
const input = await inputFixture(html`<lion-input></lion-input>`);
|
|
input.addEventListener('model-value-changed', spy);
|
|
input.modelValue = 'woof';
|
|
const e = spy.firstCall.args[0];
|
|
expect(e.detail).to.have.property('formPath');
|
|
});
|
|
|
|
it('should contain dispatching field', async () => {
|
|
const spy = sinon.spy();
|
|
const input = await inputFixture(html`<lion-input></lion-input>`);
|
|
input.addEventListener('model-value-changed', spy);
|
|
input.modelValue = 'foo';
|
|
const e = spy.firstCall.args[0];
|
|
expect(e.detail.formPath).to.eql([input]);
|
|
});
|
|
|
|
it('should contain field and group', async () => {
|
|
const spy = sinon.spy();
|
|
const fieldset = await fieldsetFixture(html`
|
|
<lion-fieldset name="fieldset">
|
|
<lion-input name="input"></lion-input>
|
|
</lion-fieldset>
|
|
`);
|
|
await fieldset.registrationComplete;
|
|
fieldset.addEventListener('model-value-changed', spy);
|
|
const input = /** @type {LionInput} */ (fieldset.querySelector('lion-input'));
|
|
input.modelValue = 'foo';
|
|
const e = spy.firstCall.args[0];
|
|
expect(e.detail.formPath).to.eql([input, fieldset]);
|
|
});
|
|
|
|
it('should contain deep elements', async () => {
|
|
const spy = sinon.spy();
|
|
const grandparent = await fieldsetFixture(html`
|
|
<lion-fieldset name="grandparent">
|
|
<lion-fieldset name="parent">
|
|
<lion-input name="input"></lion-input>
|
|
</lion-fieldset>
|
|
</lion-fieldset>
|
|
`);
|
|
const parent = /** @type {LionFieldset} */ (grandparent.querySelector('[name=parent]'));
|
|
const input = /** @type {LionInput} */ (grandparent.querySelector('[name=input]'));
|
|
await grandparent.registrationComplete;
|
|
await parent.registrationComplete;
|
|
|
|
grandparent.addEventListener('model-value-changed', spy);
|
|
input.modelValue = 'foo';
|
|
const e = spy.firstCall.args[0];
|
|
expect(e.detail.formPath).to.eql([input, parent, grandparent]);
|
|
});
|
|
|
|
it('should ignore elements that are not fields or fieldsets', async () => {
|
|
const spy = sinon.spy();
|
|
const grandparent = await fieldsetFixture(html`
|
|
<lion-fieldset name="grandparent">
|
|
<div>
|
|
<lion-fieldset name="parent">
|
|
<div>
|
|
<div>
|
|
<lion-input name="input"></lion-input>
|
|
</div>
|
|
</div>
|
|
</lion-fieldset>
|
|
</div>
|
|
</lion-fieldset>
|
|
`);
|
|
const parent = /** @type {LionFieldset} */ (grandparent.querySelector('[name=parent]'));
|
|
const input = /** @type {LionInput} */ (grandparent.querySelector('[name=input]'));
|
|
await grandparent.registrationComplete;
|
|
await parent.registrationComplete;
|
|
|
|
grandparent.addEventListener('model-value-changed', spy);
|
|
input.modelValue = 'foo';
|
|
const e = spy.firstCall.args[0];
|
|
expect(e.detail.formPath).to.eql([input, parent, grandparent]);
|
|
});
|
|
});
|
|
|
|
describe('signature', () => {
|
|
/** @type {?} */
|
|
let e;
|
|
beforeEach(async () => {
|
|
const spy = sinon.spy();
|
|
const el = await inputFixture(html`<lion-input></lion-input>`);
|
|
el.addEventListener('model-value-changed', spy);
|
|
el.modelValue = 'foo';
|
|
// eslint-disable-next-line prefer-destructuring
|
|
e = spy.firstCall.args[0];
|
|
});
|
|
|
|
// TODO: Re-enable at some point...
|
|
// In my opinion (@CubLion) we should not bubble events.
|
|
// Instead each parent should explicitly listen to children events,
|
|
// and then re-dispatch on themselves.
|
|
it.skip('should not bubble', async () => {
|
|
expect(e.bubbles).to.be.false;
|
|
});
|
|
|
|
it('should not leave shadow boundary', async () => {
|
|
expect(e.composed).to.be.false;
|
|
});
|
|
});
|
|
|
|
describe('propagation', () => {
|
|
it('should dispatch different event at each level', async () => {
|
|
const grandparent = await fieldsetFixture(html`
|
|
<lion-fieldset name="grandparent">
|
|
<lion-fieldset name="parent">
|
|
<lion-input name="input"></lion-input>
|
|
</lion-fieldset>
|
|
</lion-fieldset>
|
|
`);
|
|
const parent = /** @type {LionFieldset} */ (grandparent.querySelector('[name="parent"]'));
|
|
const input = /** @type {LionInput} */ (grandparent.querySelector('[name="input"]'));
|
|
await grandparent.registrationComplete;
|
|
await parent.registrationComplete;
|
|
|
|
/** @type {sinon.SinonSpy[]} */
|
|
const spies = [];
|
|
[grandparent, parent, input].forEach(element => {
|
|
const spy = sinon.spy();
|
|
spies.push(spy);
|
|
element.addEventListener('model-value-changed', spy);
|
|
});
|
|
input.modelValue = 'foo';
|
|
spies.forEach((spy, index) => {
|
|
const currentEvent = spy.firstCall.args[0];
|
|
for (let i = index + 1; i < spies.length; i += 1) {
|
|
const nextEvent = spies[i].firstCall.args[0];
|
|
expect(currentEvent).not.to.eql(nextEvent);
|
|
}
|
|
});
|
|
});
|
|
});
|
|
});
|