chore(steps): clean up tests

This commit is contained in:
Mikhail Bashkirov 2019-06-03 12:42:41 +02:00
parent f39b1e06fc
commit 72516ac2c5
2 changed files with 136 additions and 129 deletions

View file

@ -1,90 +1,110 @@
import { expect, fixture, oneEvent } from '@open-wc/testing'; import { expect, fixture, html, oneEvent } from '@open-wc/testing';
import '../lion-steps.js';
import '../lion-step.js'; import '../lion-step.js';
describe('lion-step', () => { describe('lion-step', () => {
it('has a condition which allows it to become active (condition is true by default)', async () => { it('has a condition which allows it to become active (condition is true by default)', async () => {
const steps = await fixture(` const el = await fixture(html`
<fake-lion-steps><lion-step>Step 1</lion-step></fake-lion-steps> <fake-lion-steps>
<lion-step>Step 1</lion-step>
</fake-lion-steps>
`); `);
expect(steps.children[0].condition()).to.equal(true); expect(el.children[0].condition()).to.equal(true);
expect(steps.children[0].passesCondition()).to.equal(true); expect(el.children[0].passesCondition()).to.equal(true);
}); });
it('does not invert condition by default', async () => { it('does not invert condition by default', async () => {
const steps = await fixture(` const el = await fixture(html`
<fake-lion-steps><lion-step>Step 1</lion-step></fake-lion-steps> <fake-lion-steps>
<lion-step>Step 1</lion-step>
</fake-lion-steps>
`); `);
expect(steps.children[0].invertCondition).to.equal(false); expect(el.children[0].invertCondition).to.equal(false);
expect(steps.children[0].passesCondition()).to.equal(true); expect(el.children[0].passesCondition()).to.equal(true);
}); });
it('can invert its condition', async () => { it('can invert its condition', async () => {
const steps = await fixture(` const el = await fixture(html`
<fake-lion-steps><lion-step>Step 1</lion-step></fake-lion-steps> <fake-lion-steps>
<lion-step>Step 1</lion-step>
</fake-lion-steps>
`); `);
steps.children[0].condition = () => true; el.children[0].condition = () => true;
steps.children[0].invertCondition = true; el.children[0].invertCondition = true;
expect(steps.children[0].condition()).to.equal(true); expect(el.children[0].condition()).to.equal(true);
expect(steps.children[0].passesCondition()).to.equal(false); expect(el.children[0].passesCondition()).to.equal(false);
}); });
it('allows to define it as the initial-step', async () => { it('allows to define it as the initial-step', async () => {
const withInitial = await fixture(` const el = await fixture(html`
<fake-lion-steps><lion-step initial-step>Step 1</lion-step></fake-lion-steps> <fake-lion-steps>
<lion-step initial-step>Step 1</lion-step>
</fake-lion-steps>
`); `);
expect(withInitial.current).to.equal(0); expect(el.current).to.equal(0);
expect(withInitial.children[0].status).to.equal('entered'); expect(el.children[0].status).to.equal('entered');
const withSecondInitial = await fixture(`<fake-lion-steps const el2 = await fixture(html`
><lion-step>Step 1</lion-step><lion-step initial-step>Step 2</lion-step></fake-lion-steps> <fake-lion-steps>
`); <lion-step>Step 1</lion-step>
expect(withSecondInitial.current).to.equal(1); <lion-step initial-step>Step 2</lion-step>
expect(withSecondInitial.children[0].status).to.equal('untouched'); </fake-lion-steps>
expect(withSecondInitial.children[1].status).to.equal('entered'); `);
expect(el2.current).to.equal(1);
expect(el2.children[0].status).to.equal('untouched');
expect(el2.children[1].status).to.equal('entered');
}); });
it('has "untouched" status by default', async () => { it('has "untouched" status by default', async () => {
const steps = await fixture(` const el = await fixture(html`
<fake-lion-steps><lion-step>Step 1</lion-step></fake-lion-steps> <fake-lion-steps>
<lion-step>Step 1</lion-step>
</fake-lion-steps>
`); `);
expect(steps.children[0].status).to.equal('untouched'); expect(el.children[0].status).to.equal('untouched');
}); });
it('communicates with a parent steps controller to handles actions', async () => { it('communicates with a parent steps controller to handles actions', async () => {
const steps = await fixture(` const el = await fixture(html`
<fake-lion-steps><lion-step>Step 1</lion-step></fake-lion-steps> <fake-lion-steps>
<lion-step>Step 1</lion-step>
</fake-lion-steps>
`); `);
expect(steps.children[0].controller).to.equal(steps); expect(el.children[0].controller).to.equal(el);
}); });
describe('navigation', () => { describe('navigation', () => {
it('can be entered', async () => { it('can be entered', async () => {
const steps = await fixture(` const el = await fixture(html`
<fake-lion-steps><lion-step>Step 1</lion-step></fake-lion-steps> <fake-lion-steps>
<lion-step>Step 1</lion-step>
</fake-lion-steps>
`); `);
setTimeout(() => steps.children[0].enter(), 0); setTimeout(() => el.children[0].enter(), 0);
await oneEvent(steps.children[0], 'enter'); await oneEvent(el.children[0], 'enter');
expect(steps.children[0].status).to.equal('entered'); expect(el.children[0].status).to.equal('entered');
}); });
it('can be left', async () => { it('can be left', async () => {
const steps = await fixture(` const el = await fixture(html`
<fake-lion-steps><lion-step>Step 1</lion-step></fake-lion-steps> <fake-lion-steps>
<lion-step>Step 1</lion-step>
</fake-lion-steps>
`); `);
setTimeout(() => steps.children[0].leave(), 0); setTimeout(() => el.children[0].leave(), 0);
await oneEvent(steps.children[0], 'leave'); await oneEvent(el.children[0], 'leave');
expect(steps.children[0].status).to.equal('left'); expect(el.children[0].status).to.equal('left');
}); });
it('can be skipped', async () => { it('can be skipped', async () => {
const steps = await fixture(` const el = await fixture(html`
<fake-lion-steps><lion-step>Step 1</lion-step></fake-lion-steps> <fake-lion-steps>
<lion-step>Step 1</lion-step>
</fake-lion-steps>
`); `);
setTimeout(() => steps.children[0].skip(), 0); setTimeout(() => el.children[0].skip(), 0);
await oneEvent(steps.children[0], 'skip'); await oneEvent(el.children[0], 'skip');
expect(steps.children[0].status).to.equal('skipped'); expect(el.children[0].status).to.equal('skipped');
}); });
}); });
}); });

View file

@ -29,89 +29,84 @@ async function checkWorkflow(steps, expected) {
describe('lion-steps', () => { describe('lion-steps', () => {
describe('initialization', () => { describe('initialization', () => {
it('activates step with an "initial-step" attribute', async () => { it('activates step with an "initial-step" attribute', async () => {
const steps = await fixture(` const el = await fixture(html`
<lion-steps> <lion-steps>
<lion-step initial-step>Step 0</lion-step> <lion-step initial-step>Step 0</lion-step>
<lion-step>Step 1</lion-step> <lion-step>Step 1</lion-step>
</lion-steps> </lion-steps>
`); `);
const firstStep = steps.children[0]; expect(el.current).to.equal(0);
expect(steps.current).to.equal(0); expect(el.children[0].status).to.equal('entered');
expect(firstStep.status).to.equal('entered');
}); });
}); });
describe('navigation', () => { describe('navigation', () => {
it('can navigate to the next step', async () => { it('can navigate to the next step', async () => {
const steps = await fixture(` const el = await fixture(html`
<lion-steps> <lion-steps>
<lion-step initial-step>Step 0</lion-step> <lion-step initial-step>Step 0</lion-step>
<lion-step>Step 1</lion-step> <lion-step>Step 1</lion-step>
</lion-steps> </lion-steps>
`); `);
setTimeout(() => { setTimeout(() => el.next());
steps.next();
});
const { detail } = await oneEvent(steps, 'transition'); const { detail } = await oneEvent(el, 'transition');
expect(detail.fromStep.number).to.equal(0); expect(detail.fromStep.number).to.equal(0);
expect(detail.fromStep.element.innerHTML).to.equal('Step 0'); expect(detail.fromStep.element.innerHTML).to.equal('Step 0');
expect(detail.toStep.number).to.equal(1); expect(detail.toStep.number).to.equal(1);
expect(detail.toStep.element.innerHTML).to.equal('Step 1'); expect(detail.toStep.element.innerHTML).to.equal('Step 1');
expect(steps.current).to.equal(1); expect(el.current).to.equal(1);
}); });
it('can navigate to the previous step', async () => { it('can navigate to the previous step', async () => {
const steps = await fixture(` const el = await fixture(html`
<lion-steps> <lion-steps>
<lion-step>Step 0</lion-step> <lion-step>Step 0</lion-step>
<lion-step initial-step>Step 1</lion-step> <lion-step initial-step>Step 1</lion-step>
</lion-steps> </lion-steps>
`); `);
setTimeout(() => { setTimeout(() => el.previous());
steps.previous();
});
const { detail } = await oneEvent(steps, 'transition'); const { detail } = await oneEvent(el, 'transition');
expect(detail.fromStep.number).to.equal(1); expect(detail.fromStep.number).to.equal(1);
expect(detail.fromStep.element.innerHTML).to.equal('Step 1'); expect(detail.fromStep.element.innerHTML).to.equal('Step 1');
expect(detail.toStep.number).to.equal(0); expect(detail.toStep.number).to.equal(0);
expect(detail.toStep.element.innerHTML).to.equal('Step 0'); expect(detail.toStep.element.innerHTML).to.equal('Step 0');
expect(steps.current).to.equal(0); expect(el.current).to.equal(0);
}); });
it('prevents navigating to the next step if user is on the last step', async () => { it('prevents navigating to the next step if user is on the last step', async () => {
const steps = await fixture(` const el = await fixture(html`
<lion-steps> <lion-steps>
<lion-step>Step 0</lion-step> <lion-step>Step 0</lion-step>
<lion-step initial-step>Step 1</lion-step> <lion-step initial-step>Step 1</lion-step>
</lion-steps> </lion-steps>
`); `);
const cb = sinon.spy(); const cb = sinon.spy();
steps.addEventListener('transition', cb); el.addEventListener('transition', cb);
expect(() => steps.next()).to.throw(); expect(() => el.next()).to.throw();
expect(cb.callCount).to.equal(0); expect(cb.callCount).to.equal(0);
expect(steps.current).to.equal(1); expect(el.current).to.equal(1);
}); });
it('prevents navigating to the previous step if user is on the first step', async () => { it('prevents navigating to the previous step if user is on the first step', async () => {
const steps = await fixture(` const el = await fixture(html`
<lion-steps> <lion-steps>
<lion-step initial-step>Step 0</lion-step> <lion-step initial-step>Step 0</lion-step>
<lion-step>Step 1</lion-step> <lion-step>Step 1</lion-step>
</lion-steps> </lion-steps>
`); `);
const cb = sinon.spy(); const cb = sinon.spy();
steps.addEventListener('transition', cb); el.addEventListener('transition', cb);
expect(() => steps.previous()).to.throw(); expect(() => el.previous()).to.throw();
expect(cb.callCount).to.equal(0); expect(cb.callCount).to.equal(0);
expect(steps.current).to.equal(0); expect(el.current).to.equal(0);
}); });
it('can navigate to an arbitrary step skipping intermediate conditions', async () => { it('can navigate to an arbitrary step skipping intermediate conditions', async () => {
const steps = await fixture(html` const el = await fixture(html`
<lion-steps .data=${{ age: 25 }}> <lion-steps .data=${{ age: 25 }}>
<lion-step initial-step>Step 0</lion-step> <lion-step initial-step>Step 0</lion-step>
<lion-step .condition=${data => data.age < 18}>Step 1</lion-step> <lion-step .condition=${data => data.age < 18}>Step 1</lion-step>
@ -121,21 +116,21 @@ describe('lion-steps', () => {
</lion-steps> </lion-steps>
`); `);
steps.current = 2; el.current = 2;
await checkWorkflow(steps, { await checkWorkflow(el, {
transitions: '0 => 2', transitions: '0 => 2',
statuses: 'left untouched entered untouched untouched', statuses: 'left untouched entered untouched untouched',
}); });
steps.current = 3; // can't enter because of condition move to next available one el.current = 3; // can't enter because of condition move to next available one
await checkWorkflow(steps, { await checkWorkflow(el, {
transitions: '2 => 4', transitions: '2 => 4',
statuses: 'left untouched left skipped entered', statuses: 'left untouched left skipped entered',
}); });
}); });
it('throws an error if current step is set out of bounds', async () => { it('throws an error if current step is set out of bounds', async () => {
const el = await fixture(` const el = await fixture(html`
<lion-steps> <lion-steps>
<lion-step>Step 0</lion-step> <lion-step>Step 0</lion-step>
<lion-step>Step 1</lion-step> <lion-step>Step 1</lion-step>
@ -150,7 +145,7 @@ describe('lion-steps', () => {
describe('workflow with data and conditions', () => { describe('workflow with data and conditions', () => {
it('navigates to the next step which passes the condition', async () => { it('navigates to the next step which passes the condition', async () => {
const steps = await fixture(html` const el = await fixture(html`
<lion-steps .data=${{ age: 25 }}> <lion-steps .data=${{ age: 25 }}>
<lion-step initial-step>Step 0</lion-step> <lion-step initial-step>Step 0</lion-step>
<lion-step .condition=${data => data.age < 18}>Step 1</lion-step> <lion-step .condition=${data => data.age < 18}>Step 1</lion-step>
@ -160,18 +155,16 @@ describe('lion-steps', () => {
</lion-steps> </lion-steps>
`); `);
setTimeout(() => { setTimeout(() => el.next());
steps.next();
});
await checkWorkflow(steps, { await checkWorkflow(el, {
transitions: '0 => 3', transitions: '0 => 3',
statuses: 'left skipped skipped entered untouched', statuses: 'left skipped skipped entered untouched',
}); });
}); });
it('skips steps with failing condition when navigating to the next step', async () => { it('skips steps with failing condition when navigating to the next step', async () => {
const steps = await fixture(html` const el = await fixture(html`
<lion-steps .data=${{ age: 19 }}> <lion-steps .data=${{ age: 19 }}>
<lion-step initial-step>Step 0</lion-step> <lion-step initial-step>Step 0</lion-step>
<lion-step .condition=${data => data.age < 18}>Step 1</lion-step> <lion-step .condition=${data => data.age < 18}>Step 1</lion-step>
@ -181,20 +174,18 @@ describe('lion-steps', () => {
</lion-steps> </lion-steps>
`); `);
steps.next(); el.next();
setTimeout(() => { setTimeout(() => el.next());
steps.next();
});
await checkWorkflow(steps, { await checkWorkflow(el, {
transitions: '2 => 4', transitions: '2 => 4',
statuses: 'left skipped left skipped entered', statuses: 'left skipped left skipped entered',
}); });
}); });
it('skips steps with failing condition when navigating to the previous step', async () => { it('skips steps with failing condition when navigating to the previous step', async () => {
const steps = await fixture(html` const el = await fixture(html`
<lion-steps .data=${{ age: 15 }}> <lion-steps .data=${{ age: 15 }}>
<lion-step initial-step>Step 0</lion-step> <lion-step initial-step>Step 0</lion-step>
<lion-step .condition=${data => data.age < 18}>Step 1</lion-step> <lion-step .condition=${data => data.age < 18}>Step 1</lion-step>
@ -204,14 +195,12 @@ describe('lion-steps', () => {
</lion-steps> </lion-steps>
`); `);
steps.next(); el.next();
steps.next(); el.next();
setTimeout(() => { setTimeout(() => el.previous());
steps.previous();
});
await checkWorkflow(steps, { await checkWorkflow(el, {
transitions: '4 => 1', transitions: '4 => 1',
statuses: 'left entered skipped skipped left', statuses: 'left entered skipped skipped left',
}); });
@ -220,7 +209,7 @@ describe('lion-steps', () => {
describe('workflow with inverted condition', () => { describe('workflow with inverted condition', () => {
it('behaves like "if not" when inverted condition is present', async () => { it('behaves like "if not" when inverted condition is present', async () => {
const steps = await fixture(html` const el = await fixture(html`
<lion-steps .data=${{}}> <lion-steps .data=${{}}>
<lion-step initial-step>Step 0</lion-step> <lion-step initial-step>Step 0</lion-step>
<lion-step .condition=${data => data.age < 18} invert-condition>Step 1</lion-step> <lion-step .condition=${data => data.age < 18} invert-condition>Step 1</lion-step>
@ -229,17 +218,17 @@ describe('lion-steps', () => {
`); `);
setTimeout(() => { setTimeout(() => {
steps.data.age = 15; el.data.age = 15;
steps.next(); el.next();
steps.previous(); el.previous();
steps.data.age = 20; el.data.age = 20;
steps.next(); el.next();
steps.next(); el.next();
steps.previous(); el.previous();
steps.previous(); el.previous();
}); });
await checkWorkflow(steps, { await checkWorkflow(el, {
transitions: '0 => 2 => 0 => 1 => 2 => 1 => 0', transitions: '0 => 2 => 0 => 1 => 2 => 1 => 0',
statuses: 'entered left left', statuses: 'entered left left',
}); });
@ -247,7 +236,7 @@ describe('lion-steps', () => {
it('behaves like "if/else" in case both condition and inverted condition are present', async () => { it('behaves like "if/else" in case both condition and inverted condition are present', async () => {
const condition = data => data.age < 18; const condition = data => data.age < 18;
const steps = await fixture(html` const el = await fixture(html`
<lion-steps .data=${{}}> <lion-steps .data=${{}}>
<lion-step initial-step>Step 0</lion-step> <lion-step initial-step>Step 0</lion-step>
<lion-step .condition=${condition}>Step 1</lion-step> <lion-step .condition=${condition}>Step 1</lion-step>
@ -256,15 +245,15 @@ describe('lion-steps', () => {
`); `);
setTimeout(() => { setTimeout(() => {
steps.data.age = 15; el.data.age = 15;
steps.next(); el.next();
steps.previous(); el.previous();
steps.data.age = 20; el.data.age = 20;
steps.next(); el.next();
steps.previous(); el.previous();
}); });
await checkWorkflow(steps, { await checkWorkflow(el, {
transitions: '0 => 1 => 0 => 2 => 0', transitions: '0 => 1 => 0 => 2 => 0',
statuses: 'entered skipped left', statuses: 'entered skipped left',
}); });
@ -273,7 +262,7 @@ describe('lion-steps', () => {
describe('workflow with forward-only', () => { describe('workflow with forward-only', () => {
it('activates step when going forward', async () => { it('activates step when going forward', async () => {
const steps = await fixture(` const el = await fixture(html`
<lion-steps> <lion-steps>
<lion-step initial-step>Step 0</lion-step> <lion-step initial-step>Step 0</lion-step>
<lion-step forward-only>Step 1</lion-step> <lion-step forward-only>Step 1</lion-step>
@ -282,18 +271,18 @@ describe('lion-steps', () => {
`); `);
setTimeout(() => { setTimeout(() => {
steps.next(); el.next();
steps.next(); el.next();
}); });
await checkWorkflow(steps, { await checkWorkflow(el, {
transitions: '0 => 1 => 2', transitions: '0 => 1 => 2',
statuses: 'left left entered', statuses: 'left left entered',
}); });
}); });
it('skips step when going back to prevent reevaluation of "service" steps', async () => { it('skips step when going back to prevent reevaluation of "service" steps', async () => {
const steps = await fixture(` const el = await fixture(html`
<lion-steps> <lion-steps>
<lion-step initial-step>Step 0</lion-step> <lion-step initial-step>Step 0</lion-step>
<lion-step forward-only>Step 1</lion-step> <lion-step forward-only>Step 1</lion-step>
@ -301,21 +290,19 @@ describe('lion-steps', () => {
</lion-steps> </lion-steps>
`); `);
steps.next(); el.next();
steps.next(); el.next();
setTimeout(() => { setTimeout(() => el.previous());
steps.previous();
});
await checkWorkflow(steps, { await checkWorkflow(el, {
transitions: '2 => 0', transitions: '2 => 0',
statuses: 'entered left left', statuses: 'entered left left',
}); });
}); });
it('does not set "skipped" status when going back', async () => { it('does not set "skipped" status when going back', async () => {
const steps = await fixture(` const el = await fixture(html`
<lion-steps> <lion-steps>
<lion-step initial-step>Step 0</lion-step> <lion-step initial-step>Step 0</lion-step>
<lion-step forward-only>Step 1</lion-step> <lion-step forward-only>Step 1</lion-step>
@ -323,11 +310,11 @@ describe('lion-steps', () => {
</lion-steps> </lion-steps>
`); `);
steps.next(); el.next();
steps.next(); el.next();
steps.previous(); el.previous();
expect(steps.children[1].status).to.equal('left'); expect(el.children[1].status).to.equal('left');
}); });
}); });
}); });