lion/packages/validate/test/Validator.test.js
Thomas Allmer 396deb2e3b feat: finalize validation and adopt it everywhere
Co-authored-by: Alex Ghiu <alex.ghiu@ing.com>
Co-authored-by: Gerjan van Geest <Gerjan.van.Geest@ing.com>
Co-authored-by: Thijs Louisse <Thijs.Louisse@ing.com>
Co-authored-by: Joren Broekema <joren.broekema@ing.com>
Co-authored-by: Erik Kroes <erik.kroes@ing.com>
2019-11-18 15:30:08 +01:00

114 lines
3.7 KiB
JavaScript

import { expect, fixture, html, unsafeStatic, defineCE } from '@open-wc/testing';
import { LitElement } from '@lion/core';
import sinon from 'sinon';
import { ValidateMixin } from '../src/ValidateMixin.js';
import { Validator } from '../src/Validator.js';
describe('Validator', () => {
it('has an "execute" function returning "shown" state', async () => {
class MyValidator extends Validator {
execute(modelValue, param) {
const hasError = modelValue === 'test' && param === 'me';
return hasError;
}
}
expect(new MyValidator().execute('test', 'me')).to.be.true;
});
it('throws when executing a Validator without a name', async () => {
class MyValidator extends Validator {}
expect(() => {
new MyValidator().execute();
}).to.throw('You must provide a name like "this.name = \'IsCat\'" for your Validator');
});
it('receives a "param" as a first argument on instantiation', async () => {
const vali = new Validator('myParam');
expect(vali.param).to.equal('myParam');
});
it('receives a config object (optionally) as a second argument on instantiation', async () => {
const vali = new Validator('myParam', { my: 'config' });
expect(vali.config).to.eql({ my: 'config' });
});
it('fires "param-changed" event on param change', async () => {
const vali = new Validator('foo');
const cb = sinon.spy(() => {});
vali.addEventListener('param-changed', cb);
vali.param = 'bar';
expect(cb.callCount).to.equal(1);
});
it('fires "config-changed" event on config change', async () => {
const vali = new Validator('foo', { foo: 'bar' });
const cb = sinon.spy(() => {});
vali.addEventListener('config-changed', cb);
vali.config = { bar: 'foo' };
expect(cb.callCount).to.equal(1);
});
it('has access to FormControl', async () => {
const lightDom = '';
const tagString = defineCE(
class extends ValidateMixin(LitElement) {
static get properties() {
return { modelValue: String };
}
},
);
const tag = unsafeStatic(tagString);
class MyValidator extends Validator {
execute(modelValue, param) {
const hasError = modelValue === 'forbidden' && param === 'values';
return hasError;
}
// eslint-disable-next-line
onFormControlConnect(formControl) {
// I could do something like:
// - add aria-required="true"
// - add type restriction for MaxLength(3, { isBlocking: true })
}
// eslint-disable-next-line
onFormControlDisconnect(formControl) {
// I will cleanup what I did in connect
}
}
const myVal = new MyValidator();
const connectSpy = sinon.spy(myVal, 'onFormControlConnect');
const disconnectSpy = sinon.spy(myVal, 'onFormControlDisconnect');
const el = await fixture(html`
<${tag} .validators=${[myVal]}>${lightDom}</${tag}>
`);
expect(connectSpy.callCount).to.equal(1);
expect(connectSpy.calledWith(el)).to.equal(true);
expect(disconnectSpy.callCount).to.equal(0);
el.validators = [];
expect(connectSpy.callCount).to.equal(1);
expect(disconnectSpy.callCount).to.equal(1);
expect(disconnectSpy.calledWith(el)).to.equal(true);
});
describe('Types', () => {
it('has type "error" by default', async () => {
expect(new Validator().type).to.equal('error');
});
it('supports customized types', async () => {
// This test shows the best practice of adding custom types
class MyValidator extends Validator {
constructor(...args) {
super(...args);
this.type = 'my-type';
}
}
expect(new MyValidator().type).to.equal('my-type');
});
});
});