chore(field): improve InteractionStateMixin tests
This commit is contained in:
parent
901fc8c503
commit
89112f6c78
1 changed files with 93 additions and 108 deletions
|
|
@ -1,14 +1,28 @@
|
||||||
import { expect, fixture, unsafeStatic, html, defineCE } from '@open-wc/testing';
|
import {
|
||||||
|
expect,
|
||||||
|
fixture,
|
||||||
|
unsafeStatic,
|
||||||
|
html,
|
||||||
|
defineCE,
|
||||||
|
triggerFocusFor,
|
||||||
|
triggerBlurFor,
|
||||||
|
} from '@open-wc/testing';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
import { LionLitElement } from '@lion/core/src/LionLitElement.js';
|
import { LitElement } from '@lion/core';
|
||||||
|
|
||||||
import { InteractionStateMixin } from '../src/InteractionStateMixin.js';
|
import { InteractionStateMixin } from '../src/InteractionStateMixin.js';
|
||||||
|
|
||||||
describe('InteractionStateMixin', async () => {
|
describe('InteractionStateMixin', async () => {
|
||||||
let elem;
|
let tagString;
|
||||||
|
let tag;
|
||||||
before(() => {
|
before(() => {
|
||||||
elem = defineCE(
|
tagString = defineCE(
|
||||||
class IState extends InteractionStateMixin(LionLitElement) {
|
class IState extends InteractionStateMixin(LitElement) {
|
||||||
|
connectedCallback() {
|
||||||
|
super.connectedCallback();
|
||||||
|
this.tabIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
set modelValue(v) {
|
set modelValue(v) {
|
||||||
this._modelValue = v;
|
this._modelValue = v;
|
||||||
this.dispatchEvent(
|
this.dispatchEvent(
|
||||||
|
|
@ -19,149 +33,120 @@ describe('InteractionStateMixin', async () => {
|
||||||
get modelValue() {
|
get modelValue() {
|
||||||
return this._modelValue;
|
return this._modelValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
get inputElement() {
|
|
||||||
return this.querySelector('input');
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
tag = unsafeStatic(tagString);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sets states to false on init', async () => {
|
it('sets states to false on init', async () => {
|
||||||
const input = await fixture(`<${elem}><input slot="input"></${elem}>`);
|
const el = await fixture(html`<${tag}></${tag}>`);
|
||||||
expect(input.dirty).to.equal(false);
|
expect(el.dirty).to.be.false;
|
||||||
expect(input.touched).to.equal(false);
|
expect(el.touched).to.be.false;
|
||||||
expect(input.prefilled).to.equal(false);
|
expect(el.prefilled).to.be.false;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sets dirty when value changed', async () => {
|
it('sets dirty when value changed', async () => {
|
||||||
const input = await fixture(`<${elem}><input slot="input"></${elem}>`);
|
const el = await fixture(html`<${tag}></${tag}>`);
|
||||||
input.modelValue = 'foobar';
|
expect(el.dirty).to.be.false;
|
||||||
expect(input.dirty).to.equal(true);
|
el.modelValue = 'foobar';
|
||||||
|
expect(el.dirty).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Skipping, since this issue (not being able to set focus on element extending from LitElement)
|
|
||||||
// only occurs in WCT context (not in Storybook/Stackblitz).
|
|
||||||
// See: https://stackblitz.com/edit/lit-element-request-update-bug-g59tjq?file=blurry.js
|
|
||||||
// it.skip
|
|
||||||
it('sets touched to true when field left after focus', async () => {
|
it('sets touched to true when field left after focus', async () => {
|
||||||
// const formElement = await LionTest.htmlFixture(`<${elem}><input type="text" slot="input"></${elem}>`);
|
const el = await fixture(html`<${tag}></${tag}>`);
|
||||||
// await triggerFocusFor(formElement.inputElement); // focus/blur can't be delegated
|
await triggerFocusFor(el);
|
||||||
// await triggerBlurFor(formElement.inputElement);
|
await triggerBlurFor(el);
|
||||||
// expect(formElement.touched).to.equal(true);
|
expect(el.touched).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sets a class "state-(touched|dirty)"', async () => {
|
it('sets a class "state-(touched|dirty)"', async () => {
|
||||||
const state = await fixture(`<${elem}><input slot="input"></${elem}>`);
|
const el = await fixture(html`<${tag}></${tag}>`);
|
||||||
state.touched = true;
|
el.touched = true;
|
||||||
await state.updateComplete;
|
await el.updateComplete;
|
||||||
expect(state.classList.contains('state-touched')).to.equal(true, 'has class "state-touched"');
|
expect(el.classList.contains('state-touched')).to.equal(true, 'has class "state-touched"');
|
||||||
|
|
||||||
state.dirty = true;
|
el.dirty = true;
|
||||||
await state.updateComplete;
|
await el.updateComplete;
|
||||||
expect(state.classList.contains('state-dirty')).to.equal(true, 'has class "state-dirty"');
|
expect(el.classList.contains('state-dirty')).to.equal(true, 'has class "state-dirty"');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('fires "(touched|dirty)-state-changed" event when state changes', async () => {
|
it('fires "(touched|dirty)-state-changed" event when state changes', async () => {
|
||||||
const iState = await fixture(`<${elem}><input slot="input"></${elem}>`);
|
const touchedSpy = sinon.spy();
|
||||||
const cbTouched = sinon.spy();
|
const dirtySpy = sinon.spy();
|
||||||
const cbDirty = sinon.spy();
|
const el = await fixture(
|
||||||
|
html`<${tag} @touched-changed=${touchedSpy} @dirty-changed=${dirtySpy}></${tag}>`,
|
||||||
|
);
|
||||||
|
|
||||||
iState.addEventListener('touched-changed', cbTouched);
|
el.touched = true;
|
||||||
iState.addEventListener('dirty-changed', cbDirty);
|
expect(touchedSpy.callCount).to.equal(1);
|
||||||
|
|
||||||
iState.touched = true;
|
el.dirty = true;
|
||||||
expect(cbTouched.callCount).to.equal(1);
|
expect(dirtySpy.callCount).to.equal(1);
|
||||||
|
|
||||||
iState.dirty = true;
|
|
||||||
expect(cbDirty.callCount).to.equal(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Skipping, since this issue (not being able to set focus on element extending from LitElement)
|
|
||||||
// only occurs in WCT context (not in Storybook/Stackblitz).
|
|
||||||
// See: https://stackblitz.com/edit/lit-element-request-update-bug-g59tjq?file=blurry.js
|
|
||||||
// it.skip
|
|
||||||
it('sets prefilled to true when field left and value non-empty', async () => {
|
|
||||||
// const iState = await LionTest.htmlFixture(`<${elem}><input slot="input"></${elem}>`);
|
|
||||||
// await triggerFocusFor(iState.inputElement);
|
|
||||||
// iState.modelValue = externalVariables.prefilledModelValue || '000';
|
|
||||||
// await triggerBlurFor(iState.inputElement);
|
|
||||||
// expect(iState.prefilled).to.equal(true);
|
|
||||||
// await triggerFocusFor(iState.inputElement);
|
|
||||||
// iState.modelValue = externalVariables.nonPrefilledModelValue || '';
|
|
||||||
// await triggerBlurFor(iState.inputElement);
|
|
||||||
// expect(iState.prefilled).to.equal(false);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sets prefilled once instantiated', async () => {
|
it('sets prefilled once instantiated', async () => {
|
||||||
const tag = unsafeStatic(elem);
|
const el = await fixture(html`
|
||||||
const element = await fixture(html`
|
<${tag} .modelValue=${'prefilled'}></${tag}>
|
||||||
<${tag}
|
`);
|
||||||
.modelValue=${'prefilled'}
|
expect(el.prefilled).to.be.true;
|
||||||
><input slot="input"></${tag}>`);
|
|
||||||
expect(element.prefilled).to.equal(true);
|
|
||||||
|
|
||||||
const nonPrefilled = await fixture(html`
|
const nonPrefilled = await fixture(html`
|
||||||
<${tag}
|
<${tag} .modelValue=${''}></${tag}>
|
||||||
.modelValue=''}
|
`);
|
||||||
><input slot="input"></${tag}>`);
|
expect(nonPrefilled.prefilled).to.be.false;
|
||||||
expect(nonPrefilled.prefilled).to.equal(false);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// This method actually tests the implementation of the _isPrefilled method.
|
// This method actually tests the implementation of the _isPrefilled method.
|
||||||
it(`can determine "prefilled" based on different modelValue types (Arrays, Objects, Numbers,
|
it(`can determine "prefilled" based on different modelValue types (Arrays, Objects, Numbers,
|
||||||
Booleans, Strings)`, async () => {
|
Booleans, Strings)`, async () => {
|
||||||
const input = await fixture(`<${elem}><input slot="input"></${elem}>`);
|
const el = await fixture(html`<${tag}></${tag}>`);
|
||||||
|
|
||||||
const changeModelValueAndLeave = modelValue => {
|
const changeModelValueAndLeave = modelValue => {
|
||||||
input.dispatchEvent(new Event('focus', { bubbles: true }));
|
el.dispatchEvent(new Event('focus', { bubbles: true }));
|
||||||
input.modelValue = modelValue;
|
el.modelValue = modelValue;
|
||||||
input.dispatchEvent(new Event('blur', { bubbles: true }));
|
el.dispatchEvent(new Event('blur', { bubbles: true }));
|
||||||
};
|
};
|
||||||
|
|
||||||
// Prefilled
|
// Prefilled
|
||||||
changeModelValueAndLeave(input, ['bla']);
|
changeModelValueAndLeave(['not-empty']);
|
||||||
expect(input.prefilled).to.equal(false, 'empty array should be considered "prefilled"');
|
expect(el.prefilled, 'not empty array should be "prefilled"').to.be.true;
|
||||||
changeModelValueAndLeave(input, { bla: 'bla' });
|
changeModelValueAndLeave({ not: 'empty' });
|
||||||
expect(input.prefilled).to.equal(false, 'empty object should be considered "prefilled"');
|
expect(el.prefilled, 'not empty object should be "prefilled"').to.be.true;
|
||||||
changeModelValueAndLeave(input, 0);
|
changeModelValueAndLeave(0);
|
||||||
expect(input.prefilled).to.equal(false, 'numbers should be considered "prefilled"');
|
expect(el.prefilled, 'numbers should be "prefilled"').to.be.true;
|
||||||
changeModelValueAndLeave(input, false);
|
changeModelValueAndLeave(false);
|
||||||
expect(input.prefilled).to.equal(false, 'Booleans should be considered "prefilled"');
|
expect(el.prefilled, 'booleans should be "prefilled"').to.be.true;
|
||||||
changeModelValueAndLeave(input, '');
|
|
||||||
expect(input.prefilled).to.equal(false, 'empty string should be considered "prefilled"');
|
|
||||||
|
|
||||||
// Not prefilled
|
// Not prefilled
|
||||||
changeModelValueAndLeave(input, []);
|
changeModelValueAndLeave([]);
|
||||||
expect(input.prefilled).to.equal(false, 'empty array should not be considered "prefilled"');
|
expect(el.prefilled, 'empty array should not be "prefilled"').to.be.false;
|
||||||
changeModelValueAndLeave(input, {});
|
changeModelValueAndLeave({});
|
||||||
expect(input.prefilled).to.equal(false, 'empty object should not be considered "prefilled"');
|
expect(el.prefilled, 'empty object should not be "prefilled"').to.be.false;
|
||||||
changeModelValueAndLeave(input, '');
|
changeModelValueAndLeave('');
|
||||||
expect(input.prefilled).to.equal(false, 'empty string should not be considered "prefilled"');
|
expect(el.prefilled, 'empty string should not be "prefilled"').to.be.false;
|
||||||
|
changeModelValueAndLeave(null);
|
||||||
changeModelValueAndLeave(input, null);
|
expect(el.prefilled, 'null should not be "prefilled"').to.be.false;
|
||||||
expect(input.prefilled).to.equal(false, 'null should not be considered "prefilled"');
|
changeModelValueAndLeave(undefined);
|
||||||
changeModelValueAndLeave(input, undefined);
|
expect(el.prefilled, 'undefined should not be "prefilled"').to.be.false;
|
||||||
expect(input.prefilled).to.equal(false, 'undefined should not be considered "prefilled"');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('has a method resetInteractionState()', async () => {
|
it('has a method resetInteractionState()', async () => {
|
||||||
const input = await fixture(`<${elem}><input slot="input"></${elem}>`);
|
const el = await fixture(html`<${tag}></${tag}>`);
|
||||||
input.dirty = true;
|
el.dirty = true;
|
||||||
input.touched = true;
|
el.touched = true;
|
||||||
input.prefilled = true;
|
el.prefilled = true;
|
||||||
input.resetInteractionState();
|
el.resetInteractionState();
|
||||||
expect(input.dirty).to.equal(false);
|
expect(el.dirty).to.be.false;
|
||||||
expect(input.touched).to.equal(false);
|
expect(el.touched).to.be.false;
|
||||||
expect(input.prefilled).to.equal(false);
|
expect(el.prefilled).to.be.false;
|
||||||
|
|
||||||
input.dirty = true;
|
el.dirty = true;
|
||||||
input.touched = true;
|
el.touched = true;
|
||||||
input.prefilled = false;
|
el.prefilled = false;
|
||||||
input.modelValue = 'Some value';
|
el.modelValue = 'Some value';
|
||||||
input.resetInteractionState();
|
el.resetInteractionState();
|
||||||
expect(input.dirty).to.equal(false);
|
expect(el.dirty).to.be.false;
|
||||||
expect(input.touched).to.equal(false);
|
expect(el.touched).to.be.false;
|
||||||
expect(input.prefilled).to.equal(true);
|
expect(el.prefilled).to.be.true;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue