2017-10-10 13:56:36 +02:00
|
|
|
import { expect } from 'chai';
|
2017-12-10 17:41:39 +01:00
|
|
|
import { stub } from 'sinon';
|
2017-10-10 13:56:36 +02:00
|
|
|
import Input from './input';
|
2018-05-21 18:01:03 +02:00
|
|
|
import { DEFAULT_CLASSNAMES } from '../constants';
|
2017-10-10 13:56:36 +02:00
|
|
|
|
2017-10-29 19:56:24 +01:00
|
|
|
describe('components/input', () => {
|
2017-10-10 13:56:36 +02:00
|
|
|
let instance;
|
|
|
|
let choicesElement;
|
|
|
|
|
|
|
|
beforeEach(() => {
|
2017-10-12 10:35:58 +02:00
|
|
|
choicesElement = document.createElement('input');
|
2018-05-21 18:01:03 +02:00
|
|
|
instance = new Input({
|
|
|
|
element: choicesElement,
|
|
|
|
type: 'text',
|
|
|
|
classNames: DEFAULT_CLASSNAMES,
|
|
|
|
placeholderValue: null,
|
|
|
|
preventPaste: false,
|
|
|
|
});
|
2017-10-10 13:56:36 +02:00
|
|
|
});
|
|
|
|
|
2017-12-18 13:06:38 +01:00
|
|
|
afterEach(() => {
|
|
|
|
document.body.innerHTML = '';
|
|
|
|
instance = null;
|
|
|
|
});
|
|
|
|
|
2017-12-10 17:41:39 +01:00
|
|
|
describe('constructor', () => {
|
|
|
|
it('assigns choices element to class', () => {
|
|
|
|
expect(instance.element).to.eql(choicesElement);
|
|
|
|
});
|
2017-10-10 13:56:36 +02:00
|
|
|
|
2017-12-10 17:41:39 +01:00
|
|
|
it('assigns classnames to class', () => {
|
|
|
|
expect(instance.classNames).to.eql(DEFAULT_CLASSNAMES);
|
|
|
|
});
|
2017-10-10 13:56:36 +02:00
|
|
|
});
|
|
|
|
|
2017-10-12 10:35:58 +02:00
|
|
|
describe('addEventListeners', () => {
|
|
|
|
let addEventListenerStub;
|
|
|
|
|
|
|
|
beforeEach(() => {
|
2017-12-10 17:41:39 +01:00
|
|
|
addEventListenerStub = stub(instance.element, 'addEventListener');
|
2017-10-12 10:35:58 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
afterEach(() => {
|
|
|
|
addEventListenerStub.restore();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('adds event listeners', () => {
|
|
|
|
instance.addEventListeners();
|
2019-10-29 18:46:10 +01:00
|
|
|
expect(['input', 'paste', 'focus', 'blur']).to.have.members(
|
|
|
|
Array.from(
|
|
|
|
{ length: addEventListenerStub.callCount },
|
|
|
|
(v, i) => addEventListenerStub.getCall(i).args[0],
|
|
|
|
),
|
|
|
|
);
|
2017-10-12 10:35:58 +02:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('removeEventListeners', () => {
|
|
|
|
let removeEventListenerStub;
|
|
|
|
|
|
|
|
beforeEach(() => {
|
2017-12-10 17:41:39 +01:00
|
|
|
removeEventListenerStub = stub(instance.element, 'removeEventListener');
|
2017-10-12 10:35:58 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
afterEach(() => {
|
|
|
|
removeEventListenerStub.restore();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('removes event listeners', () => {
|
|
|
|
instance.removeEventListeners();
|
|
|
|
expect(removeEventListenerStub.callCount).to.equal(4);
|
|
|
|
expect(removeEventListenerStub.getCall(0).args[0]).to.equal('input');
|
|
|
|
expect(removeEventListenerStub.getCall(1).args[0]).to.equal('paste');
|
|
|
|
expect(removeEventListenerStub.getCall(2).args[0]).to.equal('focus');
|
|
|
|
expect(removeEventListenerStub.getCall(3).args[0]).to.equal('blur');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2018-05-28 16:33:13 +02:00
|
|
|
describe('_onInput', () => {
|
2017-10-12 10:35:58 +02:00
|
|
|
let setWidthStub;
|
|
|
|
|
|
|
|
beforeEach(() => {
|
2017-12-10 17:41:39 +01:00
|
|
|
setWidthStub = stub(instance, 'setWidth');
|
2017-10-12 10:35:58 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
afterEach(() => {
|
|
|
|
setWidthStub.restore();
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('when element is select one', () => {
|
|
|
|
it('does not set input width', () => {
|
2018-05-21 18:01:03 +02:00
|
|
|
instance.type = 'select-one';
|
2018-05-25 10:22:14 +02:00
|
|
|
instance._onInput();
|
2017-10-12 10:35:58 +02:00
|
|
|
expect(setWidthStub.callCount).to.equal(0);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('when element is not a select one', () => {
|
|
|
|
it('sets input width', () => {
|
2018-05-21 18:01:03 +02:00
|
|
|
instance.type = 'text';
|
2018-05-25 10:22:14 +02:00
|
|
|
instance._onInput();
|
2017-10-12 10:35:58 +02:00
|
|
|
expect(setWidthStub.callCount).to.equal(1);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2018-05-28 16:33:13 +02:00
|
|
|
describe('_onPaste', () => {
|
2017-10-12 10:35:58 +02:00
|
|
|
let eventMock;
|
|
|
|
|
|
|
|
beforeEach(() => {
|
|
|
|
eventMock = {
|
2017-12-10 17:41:39 +01:00
|
|
|
preventDefault: stub(),
|
2017-10-12 10:35:58 +02:00
|
|
|
target: instance.element,
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('when pasting is disabled and target is the element', () => {
|
|
|
|
it('prevents default pasting behaviour', () => {
|
2018-05-21 18:01:03 +02:00
|
|
|
instance.preventPaste = true;
|
2018-05-25 10:22:14 +02:00
|
|
|
instance._onPaste(eventMock);
|
2017-10-12 10:35:58 +02:00
|
|
|
expect(eventMock.preventDefault.callCount).to.equal(1);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('when pasting is enabled', () => {
|
|
|
|
it('does not prevent default pasting behaviour', () => {
|
2018-05-21 18:01:03 +02:00
|
|
|
instance.preventPaste = false;
|
2018-05-25 10:22:14 +02:00
|
|
|
instance._onPaste(eventMock);
|
2017-10-12 10:35:58 +02:00
|
|
|
expect(eventMock.preventDefault.callCount).to.equal(0);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2018-05-28 16:33:13 +02:00
|
|
|
describe('_onFocus', () => {
|
2017-10-12 10:35:58 +02:00
|
|
|
it('sets isFocussed flag to true', () => {
|
|
|
|
expect(instance.isFocussed).to.equal(false);
|
2018-05-25 10:22:14 +02:00
|
|
|
instance._onFocus();
|
2017-10-12 10:35:58 +02:00
|
|
|
expect(instance.isFocussed).to.equal(true);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2018-05-28 16:33:13 +02:00
|
|
|
describe('_onBlur', () => {
|
2017-10-12 10:35:58 +02:00
|
|
|
it('sets isFocussed flag to false', () => {
|
|
|
|
instance.isFocussed = true;
|
2018-05-25 10:22:14 +02:00
|
|
|
instance._onBlur();
|
2017-10-12 10:35:58 +02:00
|
|
|
expect(instance.isFocussed).to.equal(false);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('enable', () => {
|
|
|
|
beforeEach(() => {
|
|
|
|
instance.element.setAttribute('disabled', '');
|
|
|
|
instance.isDisabled = true;
|
|
|
|
instance.enable();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('removes disabled attribute', () => {
|
|
|
|
expect(instance.element.getAttribute('disabled')).to.equal(null);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('sets isDisabled flag to false', () => {
|
|
|
|
expect(instance.isDisabled).to.equal(false);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('disable', () => {
|
|
|
|
beforeEach(() => {
|
|
|
|
instance.element.removeAttribute('disabled', '');
|
|
|
|
instance.isDisabled = false;
|
|
|
|
instance.disable();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('removes disabled attribute', () => {
|
|
|
|
expect(instance.element.getAttribute('disabled')).to.equal('');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('sets isDisabled flag to false', () => {
|
|
|
|
expect(instance.isDisabled).to.equal(true);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('focus', () => {
|
|
|
|
let focusStub;
|
|
|
|
|
|
|
|
beforeEach(() => {
|
2017-12-10 17:41:39 +01:00
|
|
|
focusStub = stub(instance.element, 'focus');
|
2017-10-12 10:35:58 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
afterEach(() => {
|
|
|
|
focusStub.restore();
|
|
|
|
});
|
|
|
|
|
2017-12-10 19:00:57 +01:00
|
|
|
describe('when element is not focussed', () => {
|
|
|
|
it('focuses element if isFocussed flag is set to false', () => {
|
|
|
|
instance.isFocussed = true;
|
|
|
|
instance.focus();
|
|
|
|
expect(focusStub.callCount).to.equal(0);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('when element is focussed', () => {
|
|
|
|
it('focuses element if isFocussed flag is set to false', () => {
|
|
|
|
instance.isFocussed = false;
|
|
|
|
instance.focus();
|
|
|
|
expect(focusStub.callCount).to.equal(1);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('blur', () => {
|
|
|
|
let blurStub;
|
|
|
|
|
|
|
|
beforeEach(() => {
|
|
|
|
blurStub = stub(instance.element, 'blur');
|
|
|
|
});
|
|
|
|
|
|
|
|
afterEach(() => {
|
|
|
|
blurStub.restore();
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('when element is not focussed', () => {
|
2018-05-28 14:55:44 +02:00
|
|
|
it("doesn't blur element", () => {
|
2017-12-10 19:00:57 +01:00
|
|
|
instance.isFocussed = false;
|
|
|
|
instance.blur();
|
|
|
|
expect(blurStub.callCount).to.equal(0);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('when element is focussed', () => {
|
|
|
|
it('blurs element', () => {
|
|
|
|
instance.isFocussed = true;
|
|
|
|
instance.blur();
|
|
|
|
expect(blurStub.callCount).to.equal(1);
|
|
|
|
});
|
2017-10-12 10:35:58 +02:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('clear', () => {
|
|
|
|
let setWidthStub;
|
|
|
|
|
|
|
|
beforeEach(() => {
|
2017-12-10 17:41:39 +01:00
|
|
|
setWidthStub = stub(instance, 'setWidth');
|
2017-10-12 10:35:58 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
afterEach(() => {
|
|
|
|
setWidthStub.restore();
|
|
|
|
});
|
|
|
|
|
2018-05-28 14:55:44 +02:00
|
|
|
it("removes the element's value if it has one", () => {
|
2017-10-12 10:35:58 +02:00
|
|
|
instance.element.value = 'test';
|
|
|
|
expect(instance.element.value).to.equal('test');
|
|
|
|
instance.clear();
|
|
|
|
expect(instance.element.value).to.equal('');
|
|
|
|
});
|
|
|
|
|
2018-05-28 14:55:44 +02:00
|
|
|
it("sets the element's width if flag passed", () => {
|
2017-10-12 10:35:58 +02:00
|
|
|
expect(setWidthStub.callCount).to.equal(0);
|
|
|
|
instance.clear(true);
|
|
|
|
expect(setWidthStub.callCount).to.equal(1);
|
|
|
|
});
|
|
|
|
|
2018-05-21 18:01:03 +02:00
|
|
|
it('returns instance', () => {
|
|
|
|
const response = instance.clear();
|
|
|
|
expect(response).to.eql(instance);
|
2017-10-12 10:35:58 +02:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2019-10-28 20:27:10 +01:00
|
|
|
/**
|
|
|
|
* Blocked by lack of ch support in JSDOM
|
|
|
|
* @see {@link https://github.com/jsdom/cssstyle/pull/107}
|
|
|
|
*
|
2017-10-12 10:35:58 +02:00
|
|
|
describe('setWidth', () => {
|
2019-10-28 20:27:10 +01:00
|
|
|
it('sets the width of the element based on input value and placeholder', () => {
|
|
|
|
instance.placeholder = 'This is a placeholder';
|
|
|
|
instance.element.value = 'This is a value';
|
|
|
|
expect(instance.element.style.width).to.not.equal('16ch');
|
|
|
|
instance.setWidth();
|
|
|
|
expect(instance.element.style.width).to.equal('16ch');
|
|
|
|
expect(instance.element.style.minWidth).to.equal('22ch');
|
2017-10-12 10:35:58 +02:00
|
|
|
});
|
|
|
|
});
|
2019-10-28 20:27:10 +01:00
|
|
|
*/
|
2017-10-12 10:35:58 +02:00
|
|
|
|
2018-04-24 13:54:45 +02:00
|
|
|
describe('placeholder setter', () => {
|
2017-10-12 10:35:58 +02:00
|
|
|
it('sets value of element to passed placeholder', () => {
|
|
|
|
const placeholder = 'test';
|
|
|
|
expect(instance.element.placeholder).to.equal('');
|
2018-04-24 13:54:45 +02:00
|
|
|
instance.placeholder = placeholder;
|
2017-10-12 10:35:58 +02:00
|
|
|
expect(instance.element.placeholder).to.equal(placeholder);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2018-04-24 13:54:45 +02:00
|
|
|
describe('value setter', () => {
|
2017-10-12 10:35:58 +02:00
|
|
|
it('sets value of element to passed value', () => {
|
|
|
|
const value = 'test';
|
|
|
|
expect(instance.element.value).to.equal('');
|
2018-04-24 13:54:45 +02:00
|
|
|
instance.value = value;
|
2017-10-12 10:35:58 +02:00
|
|
|
expect(instance.element.value).to.equal(value);
|
|
|
|
});
|
2018-05-28 16:39:12 +02:00
|
|
|
|
|
|
|
it('casts value to string', () => {
|
|
|
|
const value = 1234;
|
|
|
|
instance.value = value;
|
|
|
|
expect(instance.element.value).to.equal(`${value}`);
|
|
|
|
});
|
2017-10-12 10:35:58 +02:00
|
|
|
});
|
|
|
|
|
2018-04-24 13:54:45 +02:00
|
|
|
describe('value getter', () => {
|
2017-10-12 10:35:58 +02:00
|
|
|
it('sets value of element to passed value', () => {
|
|
|
|
const value = 'test';
|
|
|
|
instance.element.value = value;
|
2018-05-28 16:33:13 +02:00
|
|
|
expect(instance.value).to.equal(value);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('strips HTML from value', () => {
|
|
|
|
const value = '<script>somethingMalicious();</script>';
|
|
|
|
instance.element.value = value;
|
|
|
|
expect(instance.value).to.equal(
|
|
|
|
'<script&rt;somethingMalicious();</script&rt;',
|
|
|
|
);
|
2017-10-12 10:35:58 +02:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('setActiveDescendant', () => {
|
2018-05-28 14:55:44 +02:00
|
|
|
it("sets element's aria-activedescendant attribute with passed descendant ID", () => {
|
2017-10-12 10:35:58 +02:00
|
|
|
const activeDescendantID = '1234';
|
2018-05-28 14:55:44 +02:00
|
|
|
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(
|
|
|
|
null,
|
|
|
|
);
|
2017-10-12 10:35:58 +02:00
|
|
|
instance.setActiveDescendant(activeDescendantID);
|
2018-05-28 14:55:44 +02:00
|
|
|
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(
|
|
|
|
activeDescendantID,
|
|
|
|
);
|
2017-10-12 10:35:58 +02:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('removeActiveDescendant', () => {
|
2018-05-28 14:55:44 +02:00
|
|
|
it("remove elememnt's aria-activedescendant attribute", () => {
|
2017-10-12 10:35:58 +02:00
|
|
|
const activeDescendantID = '1234';
|
2018-05-28 14:55:44 +02:00
|
|
|
instance.element.setAttribute(
|
|
|
|
'aria-activedescendant',
|
|
|
|
activeDescendantID,
|
|
|
|
);
|
|
|
|
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(
|
|
|
|
activeDescendantID,
|
|
|
|
);
|
2017-10-12 10:35:58 +02:00
|
|
|
instance.removeActiveDescendant();
|
2018-05-28 14:55:44 +02:00
|
|
|
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(
|
|
|
|
null,
|
|
|
|
);
|
2017-10-12 10:35:58 +02:00
|
|
|
});
|
|
|
|
});
|
2017-10-10 13:56:36 +02:00
|
|
|
});
|