mirror of
https://github.com/Choices-js/Choices.git
synced 2024-06-03 14:32:11 +02:00
More coverage
This commit is contained in:
parent
43417510cd
commit
e79699facd
|
@ -87,7 +87,8 @@
|
||||||
"src/**/**/**/**/**/*.js"
|
"src/**/**/**/**/**/*.js"
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"src/**/**/**/**/**/*.test.js"
|
"src/**/**/**/**/**/*.test.js",
|
||||||
|
"src/scripts/src/lib/polyfills.js"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { getWindowHeight } from '../lib/utils';
|
||||||
|
|
||||||
export default class Container {
|
export default class Container {
|
||||||
constructor(instance, element, classNames) {
|
constructor(instance, element, classNames) {
|
||||||
this.parentInstance = instance;
|
this.parentInstance = instance;
|
||||||
|
@ -55,26 +57,15 @@ export default class Container {
|
||||||
* @param {Number} dropdownPos
|
* @param {Number} dropdownPos
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
shouldFlip(dropdownPos) {
|
shouldFlip(dropdownPos, windowHeight = getWindowHeight()) {
|
||||||
if (dropdownPos === undefined) {
|
if (dropdownPos === undefined) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const body = document.body;
|
|
||||||
const html = document.documentElement;
|
|
||||||
const winHeight = Math.max(
|
|
||||||
body.scrollHeight,
|
|
||||||
body.offsetHeight,
|
|
||||||
html.clientHeight,
|
|
||||||
html.scrollHeight,
|
|
||||||
html.offsetHeight,
|
|
||||||
);
|
|
||||||
|
|
||||||
// If flip is enabled and the dropdown bottom position is
|
// If flip is enabled and the dropdown bottom position is
|
||||||
// greater than the window height flip the dropdown.
|
// greater than the window height flip the dropdown.
|
||||||
let shouldFlip = false;
|
let shouldFlip = false;
|
||||||
if (this.config.position === 'auto') {
|
if (this.config.position === 'auto') {
|
||||||
shouldFlip = dropdownPos >= winHeight;
|
shouldFlip = dropdownPos >= windowHeight;
|
||||||
} else if (this.config.position === 'top') {
|
} else if (this.config.position === 'top') {
|
||||||
shouldFlip = true;
|
shouldFlip = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,16 +18,18 @@ describe('components/container', () => {
|
||||||
instance = new Container(choicesInstance, choicesElement, DEFAULT_CLASSNAMES);
|
instance = new Container(choicesInstance, choicesElement, DEFAULT_CLASSNAMES);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('assigns choices instance to class', () => {
|
describe('constructor', () => {
|
||||||
expect(instance.parentInstance).to.eql(choicesInstance);
|
it('assigns choices instance to class', () => {
|
||||||
});
|
expect(instance.parentInstance).to.eql(choicesInstance);
|
||||||
|
});
|
||||||
|
|
||||||
it('assigns choices element to class', () => {
|
it('assigns choices element to class', () => {
|
||||||
expect(instance.element).to.eql(choicesElement);
|
expect(instance.element).to.eql(choicesElement);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('assigns classnames to class', () => {
|
it('assigns classnames to class', () => {
|
||||||
expect(instance.classNames).to.eql(DEFAULT_CLASSNAMES);
|
expect(instance.classNames).to.eql(DEFAULT_CLASSNAMES);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getElement', () => {
|
describe('getElement', () => {
|
||||||
|
@ -90,7 +92,43 @@ describe('components/container', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// describe('shouldFlip', () => {});
|
describe('shouldFlip', () => {
|
||||||
|
describe('not passing dropdownPos', () => {
|
||||||
|
it('returns false', () => {
|
||||||
|
expect(instance.shouldFlip()).to.equal(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('passing dropdownPos', () => {
|
||||||
|
describe('position config option set to "auto"', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
instance.config.position = 'auto';
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('dropdownPos is greater than window height', () => {
|
||||||
|
it('returns false', () => {
|
||||||
|
expect(instance.shouldFlip(100, 1000)).to.equal(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('dropdownPos is less than window height', () => {
|
||||||
|
it('returns true', () => {
|
||||||
|
expect(instance.shouldFlip(100, 50)).to.equal(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('position config option set to "top"', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
instance.config.position = 'top';
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns true', () => {
|
||||||
|
expect(instance.shouldFlip(100)).to.equal(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('setActiveDescendant', () => {
|
describe('setActiveDescendant', () => {
|
||||||
it('sets element\'s aria-activedescendant attribute with passed descendant ID', () => {
|
it('sets element\'s aria-activedescendant attribute with passed descendant ID', () => {
|
||||||
|
|
|
@ -20,16 +20,18 @@ describe('components/dropdown', () => {
|
||||||
instance = new Dropdown(choicesInstance, choicesElement, DEFAULT_CLASSNAMES);
|
instance = new Dropdown(choicesInstance, choicesElement, DEFAULT_CLASSNAMES);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('assigns choices instance to instance', () => {
|
describe('constructor', () => {
|
||||||
expect(instance.parentInstance).to.eql(choicesInstance);
|
it('assigns choices instance to instance', () => {
|
||||||
});
|
expect(instance.parentInstance).to.eql(choicesInstance);
|
||||||
|
});
|
||||||
|
|
||||||
it('assigns choices element to instance', () => {
|
it('assigns choices element to instance', () => {
|
||||||
expect(instance.element).to.eql(choicesElement);
|
expect(instance.element).to.eql(choicesElement);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('assigns classnames to instance', () => {
|
it('assigns classnames to instance', () => {
|
||||||
expect(instance.classNames).to.eql(DEFAULT_CLASSNAMES);
|
expect(instance.classNames).to.eql(DEFAULT_CLASSNAMES);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getElement', () => {
|
describe('getElement', () => {
|
||||||
|
|
|
@ -152,30 +152,6 @@ describe('components/input', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// describe('activate', () => {
|
|
||||||
// describe('when passed focusInput argument is true, canSearch is true and current element is not in focus', () => {
|
|
||||||
// let focusSpy;
|
|
||||||
// beforeEach(() => {
|
|
||||||
// instance.parentInstance.canSearch = true;
|
|
||||||
// focusSpy = spy(instance.element, 'focus');
|
|
||||||
// });
|
|
||||||
|
|
||||||
// afterEach(() => {
|
|
||||||
// focusSpy.restore();
|
|
||||||
// });
|
|
||||||
|
|
||||||
// it('focuses element', () => {
|
|
||||||
// expect(focusSpy.callCount).to.equal(0);
|
|
||||||
// instance.activate(true);
|
|
||||||
// expect(focusSpy.callCount).to.equal(1);
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
|
|
||||||
describe('deactivate', () => {
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('enable', () => {
|
describe('enable', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
instance.element.setAttribute('disabled', '');
|
instance.element.setAttribute('disabled', '');
|
||||||
|
@ -219,10 +195,49 @@ describe('components/input', () => {
|
||||||
focusStub.restore();
|
focusStub.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('focuses element if isFocussed flag is set to false', () => {
|
describe('when element is not focussed', () => {
|
||||||
instance.isFocussed = false;
|
it('focuses element if isFocussed flag is set to false', () => {
|
||||||
instance.focus();
|
instance.isFocussed = true;
|
||||||
expect(focusStub.callCount).to.equal(1);
|
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', () => {
|
||||||
|
it('doesn\'t blur element', () => {
|
||||||
|
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);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -17,16 +17,18 @@ describe('components/list', () => {
|
||||||
instance = new List(choicesInstance, choicesElement, DEFAULT_CLASSNAMES);
|
instance = new List(choicesInstance, choicesElement, DEFAULT_CLASSNAMES);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('assigns choices instance to class', () => {
|
describe('constructor', () => {
|
||||||
expect(instance.parentInstance).to.eql(choicesInstance);
|
it('assigns choices instance to class', () => {
|
||||||
});
|
expect(instance.parentInstance).to.eql(choicesInstance);
|
||||||
|
});
|
||||||
|
|
||||||
it('assigns choices element to class', () => {
|
it('assigns choices element to class', () => {
|
||||||
expect(instance.element).to.eql(choicesElement);
|
expect(instance.element).to.eql(choicesElement);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('assigns classnames to class', () => {
|
it('assigns classnames to class', () => {
|
||||||
expect(instance.classNames).to.eql(DEFAULT_CLASSNAMES);
|
expect(instance.classNames).to.eql(DEFAULT_CLASSNAMES);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getElement', () => {
|
describe('getElement', () => {
|
||||||
|
@ -46,11 +48,21 @@ describe('components/list', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('scrollTo', () => {
|
describe('scrollTo', () => {
|
||||||
it('scrolls element to passed position', () => {
|
describe('passing position', () => {
|
||||||
const scrollPosition = 20;
|
it('scrolls element to passed position', () => {
|
||||||
expect(instance.element.scrollTop).to.equal(0);
|
const scrollPosition = 20;
|
||||||
instance.scrollTo(scrollPosition);
|
expect(instance.element.scrollTop).to.equal(0);
|
||||||
expect(instance.element.scrollTop).to.equal(scrollPosition);
|
instance.scrollTo(scrollPosition);
|
||||||
|
expect(instance.element.scrollTop).to.equal(scrollPosition);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('not passing position', () => {
|
||||||
|
it('scrolls element to default position', () => {
|
||||||
|
expect(instance.element.scrollTop).to.equal(0);
|
||||||
|
instance.scrollTo();
|
||||||
|
expect(instance.element.scrollTop).to.equal(0);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,8 @@ export const DEFAULT_CLASSNAMES = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DEFAULT_CONFIG = {
|
export const DEFAULT_CONFIG = {
|
||||||
|
items: [],
|
||||||
|
choices: [],
|
||||||
silent: false,
|
silent: false,
|
||||||
renderChoiceLimit: -1,
|
renderChoiceLimit: -1,
|
||||||
maxItemCount: -1,
|
maxItemCount: -1,
|
||||||
|
@ -59,9 +61,9 @@ export const DEFAULT_CONFIG = {
|
||||||
noResultsText: 'No results found',
|
noResultsText: 'No results found',
|
||||||
noChoicesText: 'No choices to choose from',
|
noChoicesText: 'No choices to choose from',
|
||||||
itemSelectText: 'Press to select',
|
itemSelectText: 'Press to select',
|
||||||
|
uniqueItemText: 'Only unique values can be added.',
|
||||||
addItemText: value => `Press Enter to add <b>"${value}"</b>`,
|
addItemText: value => `Press Enter to add <b>"${value}"</b>`,
|
||||||
maxItemText: maxItemCount => `Only ${maxItemCount} values can be added.`,
|
maxItemText: maxItemCount => `Only ${maxItemCount} values can be added.`,
|
||||||
uniqueItemText: 'Only unique values can be added.',
|
|
||||||
fuseOptions: {
|
fuseOptions: {
|
||||||
includeScore: true,
|
includeScore: true,
|
||||||
},
|
},
|
||||||
|
|
155
src/scripts/src/constants.test.js
Normal file
155
src/scripts/src/constants.test.js
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
import { expect } from 'chai';
|
||||||
|
import {
|
||||||
|
DEFAULT_CLASSNAMES,
|
||||||
|
DEFAULT_CONFIG,
|
||||||
|
EVENTS,
|
||||||
|
ACTION_TYPES,
|
||||||
|
KEY_CODES,
|
||||||
|
SCROLLING_SPEED,
|
||||||
|
} from './constants';
|
||||||
|
|
||||||
|
describe('constants', () => {
|
||||||
|
describe('type checks', () => {
|
||||||
|
describe('DEFAULT_CLASSNAMES', () => {
|
||||||
|
it('exports as an object with expected keys', () => {
|
||||||
|
expect(DEFAULT_CLASSNAMES).to.be.an('object');
|
||||||
|
expect(Object.keys(DEFAULT_CLASSNAMES)).to.eql([
|
||||||
|
'containerOuter',
|
||||||
|
'containerInner',
|
||||||
|
'input',
|
||||||
|
'inputCloned',
|
||||||
|
'list',
|
||||||
|
'listItems',
|
||||||
|
'listSingle',
|
||||||
|
'listDropdown',
|
||||||
|
'item',
|
||||||
|
'itemSelectable',
|
||||||
|
'itemDisabled',
|
||||||
|
'itemChoice',
|
||||||
|
'placeholder',
|
||||||
|
'group',
|
||||||
|
'groupHeading',
|
||||||
|
'button',
|
||||||
|
'activeState',
|
||||||
|
'focusState',
|
||||||
|
'openState',
|
||||||
|
'disabledState',
|
||||||
|
'highlightedState',
|
||||||
|
'hiddenState',
|
||||||
|
'flippedState',
|
||||||
|
'loadingState',
|
||||||
|
'noResults',
|
||||||
|
'noChoices',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('DEFAULT_CONFIG', () => {
|
||||||
|
it('exports as an object', () => {
|
||||||
|
expect(DEFAULT_CONFIG).to.be.an('object');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('has expected config options', () => {
|
||||||
|
expect(DEFAULT_CONFIG.items).to.be.an('array');
|
||||||
|
expect(DEFAULT_CONFIG.choices).to.be.an('array');
|
||||||
|
expect(DEFAULT_CONFIG.silent).to.be.a('boolean');
|
||||||
|
expect(DEFAULT_CONFIG.renderChoiceLimit).to.be.a('number');
|
||||||
|
expect(DEFAULT_CONFIG.maxItemCount).to.be.a('number');
|
||||||
|
expect(DEFAULT_CONFIG.addItems).to.be.a('boolean');
|
||||||
|
expect(DEFAULT_CONFIG.removeItems).to.be.a('boolean');
|
||||||
|
expect(DEFAULT_CONFIG.removeItemButton).to.be.a('boolean');
|
||||||
|
expect(DEFAULT_CONFIG.editItems).to.be.a('boolean');
|
||||||
|
expect(DEFAULT_CONFIG.duplicateItems).to.be.a('boolean');
|
||||||
|
expect(DEFAULT_CONFIG.delimiter).to.be.a('string');
|
||||||
|
expect(DEFAULT_CONFIG.paste).to.be.a('boolean');
|
||||||
|
expect(DEFAULT_CONFIG.searchEnabled).to.be.a('boolean');
|
||||||
|
expect(DEFAULT_CONFIG.searchChoices).to.be.a('boolean');
|
||||||
|
expect(DEFAULT_CONFIG.searchFloor).to.be.a('number');
|
||||||
|
expect(DEFAULT_CONFIG.searchResultLimit).to.be.a('number');
|
||||||
|
expect(DEFAULT_CONFIG.searchFields).to.be.an('array');
|
||||||
|
expect(DEFAULT_CONFIG.position).to.be.a('string');
|
||||||
|
expect(DEFAULT_CONFIG.regexFilter).to.equal(null);
|
||||||
|
expect(DEFAULT_CONFIG.shouldSort).to.be.a('boolean');
|
||||||
|
expect(DEFAULT_CONFIG.shouldSortItems).to.be.a('boolean');
|
||||||
|
expect(DEFAULT_CONFIG.placeholder).to.be.a('boolean');
|
||||||
|
expect(DEFAULT_CONFIG.placeholderValue).to.equal(null);
|
||||||
|
expect(DEFAULT_CONFIG.searchPlaceholderValue).to.equal(null);
|
||||||
|
expect(DEFAULT_CONFIG.prependValue).to.equal(null);
|
||||||
|
expect(DEFAULT_CONFIG.appendValue).to.equal(null);
|
||||||
|
expect(DEFAULT_CONFIG.renderSelectedChoices).to.be.a('string');
|
||||||
|
expect(DEFAULT_CONFIG.loadingText).to.be.a('string');
|
||||||
|
expect(DEFAULT_CONFIG.noResultsText).to.be.a('string');
|
||||||
|
expect(DEFAULT_CONFIG.noChoicesText).to.be.a('string');
|
||||||
|
expect(DEFAULT_CONFIG.itemSelectText).to.be.a('string');
|
||||||
|
expect(DEFAULT_CONFIG.uniqueItemText).to.be.a('string');
|
||||||
|
expect(DEFAULT_CONFIG.addItemText).to.be.a('function');
|
||||||
|
expect(DEFAULT_CONFIG.maxItemText).to.be.a('function');
|
||||||
|
expect(DEFAULT_CONFIG.fuseOptions).to.be.an('object');
|
||||||
|
expect(DEFAULT_CONFIG.callbackOnInit).to.equal(null);
|
||||||
|
expect(DEFAULT_CONFIG.callbackOnCreateTemplates).to.equal(null);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('EVENTS', () => {
|
||||||
|
it('exports as an object with expected keys', () => {
|
||||||
|
expect(EVENTS).to.be.an('object');
|
||||||
|
expect(Object.keys(EVENTS)).to.eql([
|
||||||
|
'showDropdown',
|
||||||
|
'hideDropdown',
|
||||||
|
'change',
|
||||||
|
'choice',
|
||||||
|
'search',
|
||||||
|
'addItem',
|
||||||
|
'removeItem',
|
||||||
|
'highlightItem',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('ACTION_TYPES', () => {
|
||||||
|
it('exports as an object with expected keys', () => {
|
||||||
|
expect(ACTION_TYPES).to.be.an('object');
|
||||||
|
expect(Object.keys(ACTION_TYPES)).to.eql([
|
||||||
|
'ADD_CHOICE',
|
||||||
|
'FILTER_CHOICES',
|
||||||
|
'ACTIVATE_CHOICES',
|
||||||
|
'CLEAR_CHOICES',
|
||||||
|
'ADD_GROUP',
|
||||||
|
'ADD_ITEM',
|
||||||
|
'REMOVE_ITEM',
|
||||||
|
'HIGHLIGHT_ITEM',
|
||||||
|
'CLEAR_ALL',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('KEY_CODES', () => {
|
||||||
|
it('exports as an object with expected keys', () => {
|
||||||
|
expect(KEY_CODES).to.be.an('object');
|
||||||
|
expect(Object.keys(KEY_CODES)).to.eql([
|
||||||
|
'BACK_KEY',
|
||||||
|
'DELETE_KEY',
|
||||||
|
'ENTER_KEY',
|
||||||
|
'A_KEY',
|
||||||
|
'ESC_KEY',
|
||||||
|
'UP_KEY',
|
||||||
|
'DOWN_KEY',
|
||||||
|
'PAGE_UP_KEY',
|
||||||
|
'PAGE_DOWN_KEY',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('exports each value as a number', () => {
|
||||||
|
Object.keys(KEY_CODES).forEach((key) => {
|
||||||
|
expect(KEY_CODES[key]).to.be.a('number');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('SCROLLING_SPEED', () => {
|
||||||
|
it('exports as an number', () => {
|
||||||
|
expect(SCROLLING_SPEED).to.be.a('number');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -582,3 +582,15 @@ export const regexFilter = (value, regex) => {
|
||||||
const expression = new RegExp(regex.source, 'i');
|
const expression = new RegExp(regex.source, 'i');
|
||||||
return expression.test(value);
|
return expression.test(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getWindowHeight = () => {
|
||||||
|
const body = document.body;
|
||||||
|
const html = document.documentElement;
|
||||||
|
return Math.max(
|
||||||
|
body.scrollHeight,
|
||||||
|
body.offsetHeight,
|
||||||
|
html.clientHeight,
|
||||||
|
html.scrollHeight,
|
||||||
|
html.offsetHeight,
|
||||||
|
);
|
||||||
|
};
|
|
@ -8,18 +8,36 @@ describe('reducers/choices', () => {
|
||||||
|
|
||||||
describe('when choices do not exist', () => {
|
describe('when choices do not exist', () => {
|
||||||
describe('ADD_CHOICE', () => {
|
describe('ADD_CHOICE', () => {
|
||||||
it('adds choice', () => {
|
const value = 'test';
|
||||||
const value = 'test';
|
const label = 'test';
|
||||||
const label = 'test';
|
const id = 'test';
|
||||||
const id = 'test';
|
const groupId = 'test';
|
||||||
const groupId = 'test';
|
const disabled = false;
|
||||||
const disabled = false;
|
const elementId = 'test';
|
||||||
const elementId = 'test';
|
const customProperties = 'test';
|
||||||
const customProperties = 'test';
|
const placeholder = 'test';
|
||||||
const placeholder = 'test';
|
|
||||||
|
|
||||||
const expectedResponse = [
|
describe('passing expected values', () => {
|
||||||
{
|
it('adds choice', () => {
|
||||||
|
const expectedResponse = [
|
||||||
|
{
|
||||||
|
value,
|
||||||
|
label,
|
||||||
|
id,
|
||||||
|
groupId,
|
||||||
|
disabled,
|
||||||
|
elementId,
|
||||||
|
customProperties,
|
||||||
|
placeholder,
|
||||||
|
selected: false,
|
||||||
|
active: true,
|
||||||
|
score: 9999,
|
||||||
|
keyCode: null,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const actualResponse = choices(undefined, {
|
||||||
|
type: 'ADD_CHOICE',
|
||||||
value,
|
value,
|
||||||
label,
|
label,
|
||||||
id,
|
id,
|
||||||
|
@ -28,26 +46,82 @@ describe('reducers/choices', () => {
|
||||||
elementId,
|
elementId,
|
||||||
customProperties,
|
customProperties,
|
||||||
placeholder,
|
placeholder,
|
||||||
selected: false,
|
});
|
||||||
active: true,
|
|
||||||
score: 9999,
|
|
||||||
keyCode: null,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const actualResponse = choices(undefined, {
|
expect(actualResponse).to.eql(expectedResponse);
|
||||||
type: 'ADD_CHOICE',
|
});
|
||||||
value,
|
});
|
||||||
label,
|
|
||||||
id,
|
describe('fallback values', () => {
|
||||||
groupId,
|
describe('passing no label', () => {
|
||||||
disabled,
|
it('adds choice using value as label', () => {
|
||||||
elementId,
|
const expectedResponse = [
|
||||||
customProperties,
|
{
|
||||||
placeholder,
|
value,
|
||||||
|
label: value,
|
||||||
|
id,
|
||||||
|
groupId,
|
||||||
|
disabled,
|
||||||
|
elementId,
|
||||||
|
customProperties,
|
||||||
|
placeholder,
|
||||||
|
selected: false,
|
||||||
|
active: true,
|
||||||
|
score: 9999,
|
||||||
|
keyCode: null,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const actualResponse = choices(undefined, {
|
||||||
|
type: 'ADD_CHOICE',
|
||||||
|
value,
|
||||||
|
label: null,
|
||||||
|
id,
|
||||||
|
groupId,
|
||||||
|
disabled,
|
||||||
|
elementId,
|
||||||
|
customProperties,
|
||||||
|
placeholder,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(actualResponse).to.eql(expectedResponse);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(actualResponse).to.eql(expectedResponse);
|
describe('passing no placeholder value', () => {
|
||||||
|
it('adds choice with placeholder set to false', () => {
|
||||||
|
const expectedResponse = [
|
||||||
|
{
|
||||||
|
value,
|
||||||
|
label: value,
|
||||||
|
id,
|
||||||
|
groupId,
|
||||||
|
disabled,
|
||||||
|
elementId,
|
||||||
|
customProperties,
|
||||||
|
placeholder: false,
|
||||||
|
selected: false,
|
||||||
|
active: true,
|
||||||
|
score: 9999,
|
||||||
|
keyCode: null,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const actualResponse = choices(undefined, {
|
||||||
|
type: 'ADD_CHOICE',
|
||||||
|
value,
|
||||||
|
label: null,
|
||||||
|
id,
|
||||||
|
groupId,
|
||||||
|
disabled,
|
||||||
|
elementId,
|
||||||
|
customProperties,
|
||||||
|
placeholder: undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(actualResponse).to.eql(expectedResponse);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -19,9 +19,7 @@ export default function items(state = defaultState, action) {
|
||||||
|
|
||||||
return newState.map((obj) => {
|
return newState.map((obj) => {
|
||||||
const item = obj;
|
const item = obj;
|
||||||
if (item.highlighted) {
|
item.highlighted = false;
|
||||||
item.highlighted = false;
|
|
||||||
}
|
|
||||||
return item;
|
return item;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,34 +19,83 @@ describe('reducers/items', () => {
|
||||||
const placeholder = 'This is a placeholder';
|
const placeholder = 'This is a placeholder';
|
||||||
const keyCode = 10;
|
const keyCode = 10;
|
||||||
|
|
||||||
const expectedResponse = [
|
describe('passing expected values', () => {
|
||||||
{
|
let actualResponse;
|
||||||
id,
|
|
||||||
choiceId,
|
|
||||||
groupId,
|
|
||||||
value,
|
|
||||||
label,
|
|
||||||
active: true,
|
|
||||||
highlighted: false,
|
|
||||||
customProperties,
|
|
||||||
placeholder,
|
|
||||||
keyCode: null,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const actualResponse = items(undefined, {
|
beforeEach(() => {
|
||||||
type: 'ADD_ITEM',
|
actualResponse = items(undefined, {
|
||||||
value,
|
type: 'ADD_ITEM',
|
||||||
label,
|
value,
|
||||||
id,
|
label,
|
||||||
choiceId,
|
id,
|
||||||
groupId,
|
choiceId,
|
||||||
customProperties,
|
groupId,
|
||||||
placeholder,
|
customProperties,
|
||||||
keyCode,
|
placeholder,
|
||||||
|
keyCode,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('adds item', () => {
|
||||||
|
const expectedResponse = [
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
choiceId,
|
||||||
|
groupId,
|
||||||
|
value,
|
||||||
|
label,
|
||||||
|
active: true,
|
||||||
|
highlighted: false,
|
||||||
|
customProperties,
|
||||||
|
placeholder,
|
||||||
|
keyCode: null,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
expect(actualResponse).to.eql(expectedResponse);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('unhighlights all highlighted items', () => {
|
||||||
|
actualResponse.forEach((item) => {
|
||||||
|
expect(item.highlighted).to.equal(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(actualResponse).to.eql(expectedResponse);
|
describe('fallback values', () => {
|
||||||
|
describe('passing no placeholder value', () => {
|
||||||
|
it('adds item with placeholder set to false', () => {
|
||||||
|
const expectedResponse = [
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
choiceId,
|
||||||
|
groupId,
|
||||||
|
value,
|
||||||
|
label,
|
||||||
|
active: true,
|
||||||
|
highlighted: false,
|
||||||
|
customProperties,
|
||||||
|
placeholder: false,
|
||||||
|
keyCode: null,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const actualResponse = items(undefined, {
|
||||||
|
type: 'ADD_ITEM',
|
||||||
|
value,
|
||||||
|
label,
|
||||||
|
id,
|
||||||
|
choiceId,
|
||||||
|
groupId,
|
||||||
|
customProperties,
|
||||||
|
placeholder: undefined,
|
||||||
|
keyCode,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(actualResponse).to.eql(expectedResponse);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ export default class Store {
|
||||||
* Get items from store reduced to just their values
|
* Get items from store reduced to just their values
|
||||||
* @return {Array} Item objects
|
* @return {Array} Item objects
|
||||||
*/
|
*/
|
||||||
getItemsReducedToValues(items = this.getItems()) {
|
getItemsReducedToValues(items) {
|
||||||
const values = items.reduce((prev, current) => {
|
const values = items.reduce((prev, current) => {
|
||||||
prev.push(current.value);
|
prev.push(current.value);
|
||||||
return prev;
|
return prev;
|
||||||
|
|
|
@ -21,14 +21,18 @@ describe('reducers/store', () => {
|
||||||
getStateStub.restore();
|
getStateStub.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('creates redux store on construction', () => {
|
|
||||||
expect(instance.store).to.contain.keys([
|
describe('constructor', () => {
|
||||||
'subscribe',
|
it('creates redux store', () => {
|
||||||
'dispatch',
|
expect(instance.store).to.contain.keys([
|
||||||
'getState',
|
'subscribe',
|
||||||
]);
|
'dispatch',
|
||||||
|
'getState',
|
||||||
|
]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('subscribe', () => {
|
describe('subscribe', () => {
|
||||||
it('wraps redux subscribe method', () => {
|
it('wraps redux subscribe method', () => {
|
||||||
const onChange = () => {};
|
const onChange = () => {};
|
||||||
|
@ -79,14 +83,26 @@ describe('reducers/store', () => {
|
||||||
id: 2,
|
id: 2,
|
||||||
choiceId: 2,
|
choiceId: 2,
|
||||||
groupId: -1,
|
groupId: -1,
|
||||||
value: 'Item one',
|
value: 'Item two',
|
||||||
label: 'Item one',
|
label: 'Item two',
|
||||||
active: true,
|
active: true,
|
||||||
highlighted: false,
|
highlighted: false,
|
||||||
customProperties: null,
|
customProperties: null,
|
||||||
placeholder: false,
|
placeholder: false,
|
||||||
keyCode: null,
|
keyCode: null,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
choiceId: 3,
|
||||||
|
groupId: -1,
|
||||||
|
value: 'Item three',
|
||||||
|
label: 'Item three',
|
||||||
|
active: true,
|
||||||
|
highlighted: true,
|
||||||
|
customProperties: null,
|
||||||
|
placeholder: false,
|
||||||
|
keyCode: null,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
choices: [
|
choices: [
|
||||||
{
|
{
|
||||||
|
@ -153,13 +169,21 @@ describe('reducers/store', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getItemsFilteredByHighlighted', () => {
|
||||||
|
it('returns items that are active and highlighted', () => {
|
||||||
|
const expectedResponse = state.items.filter((item => item.highlighted && item.active));
|
||||||
|
const actualResponse = instance.getItemsFilteredByHighlighted();
|
||||||
|
expect(actualResponse).to.eql(expectedResponse);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('getItemsReducedToValues', () => {
|
describe('getItemsReducedToValues', () => {
|
||||||
it('returns an array of item values', () => {
|
it('returns an array of item values', () => {
|
||||||
const expectedResponse = state.items.reduce((items, item) => {
|
const expectedResponse = state.items.reduce((items, item) => {
|
||||||
items.push(item.value);
|
items.push(item.value);
|
||||||
return items;
|
return items;
|
||||||
}, []);
|
}, []);
|
||||||
const actualResponse = instance.getItemsReducedToValues();
|
const actualResponse = instance.getItemsReducedToValues(state.items);
|
||||||
expect(actualResponse).to.eql(expectedResponse);
|
expect(actualResponse).to.eql(expectedResponse);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -197,11 +221,20 @@ describe('reducers/store', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getChoiceById', () => {
|
describe('getChoiceById', () => {
|
||||||
it('returns active choice by id', () => {
|
describe('passing id', () => {
|
||||||
const id = '1';
|
it('returns active choice by passed id', () => {
|
||||||
const expectedResponse = state.choices.find((choice => choice.id === parseInt(id, 10)));
|
const id = '1';
|
||||||
const actualResponse = instance.getChoiceById(id);
|
const expectedResponse = state.choices.find((choice => choice.id === parseInt(id, 10)));
|
||||||
expect(actualResponse).to.eql(expectedResponse);
|
const actualResponse = instance.getChoiceById(id);
|
||||||
|
expect(actualResponse).to.eql(expectedResponse);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('passing no id', () => {
|
||||||
|
it('returns false', () => {
|
||||||
|
const actualResponse = instance.getChoiceById();
|
||||||
|
expect(actualResponse).to.equal(false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue