mirror of
https://github.com/Choices-js/Choices.git
synced 2024-05-07 16:16:35 +02:00
fix: template testing & type errors
This commit is contained in:
parent
7f727480e8
commit
6b16e93977
|
@ -152,7 +152,9 @@ class Choices implements Choices {
|
|||
userConfig: Partial<Options> = {},
|
||||
) {
|
||||
if (userConfig.allowHTML === undefined) {
|
||||
console.warn('Deprecation warning: allowHTML in the future will be defaulted to false. You must explicitly set it to true to properly display html tags in choices.');
|
||||
console.warn(
|
||||
'Deprecation warning: allowHTML in the future will be defaulted to false. You must explicitly set it to true to properly display html tags in choices.',
|
||||
);
|
||||
}
|
||||
|
||||
this.config = merge.all<Options>(
|
||||
|
|
|
@ -160,11 +160,11 @@ export interface Options {
|
|||
editItems: boolean;
|
||||
|
||||
/**
|
||||
* Whether HTML should be shown properly when showing choices.
|
||||
* Whether HTML should be shown properly when showing choices.
|
||||
* (Can be used to perform XSS attacks if not disabled or handled correctly)
|
||||
*
|
||||
*
|
||||
* **Input types affected:** text, select-one, select-multiple
|
||||
*
|
||||
*
|
||||
* @default true
|
||||
*/
|
||||
allowHTML: boolean;
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import { expect } from 'chai';
|
||||
import templates from './templates';
|
||||
import { strToEl } from './lib/utils';
|
||||
import { DEFAULT_CLASSNAMES, DEFAULT_CONFIG } from './defaults';
|
||||
import { Options } from './interfaces/options';
|
||||
import { ClassNames } from './interfaces/class-names';
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} element1
|
||||
|
@ -21,11 +24,25 @@ function expectEqualElements(element1, element2): void {
|
|||
}
|
||||
}
|
||||
|
||||
function createOptionsWithPartialClasses(
|
||||
classNames: Partial<ClassNames>,
|
||||
options: Partial<Options> = {},
|
||||
): Options {
|
||||
return {
|
||||
...DEFAULT_CONFIG,
|
||||
...options,
|
||||
classNames: {
|
||||
...DEFAULT_CLASSNAMES,
|
||||
...classNames,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
describe('templates', () => {
|
||||
describe('containerOuter', () => {
|
||||
const classes = {
|
||||
const options = createOptionsWithPartialClasses({
|
||||
containerOuter: 'class-1',
|
||||
};
|
||||
});
|
||||
const direction = 'rtl';
|
||||
|
||||
describe('select element', () => {
|
||||
|
@ -38,7 +55,7 @@ describe('templates', () => {
|
|||
|
||||
const expectedOutput = strToEl(`
|
||||
<div
|
||||
class="${classes.containerOuter}"
|
||||
class="${options.classNames.containerOuter}"
|
||||
data-type="${passedElementType}"
|
||||
role="combobox"
|
||||
aria-autocomplete="list"
|
||||
|
@ -49,7 +66,7 @@ describe('templates', () => {
|
|||
</div>
|
||||
`);
|
||||
const actualOutput = templates.containerOuter(
|
||||
classes,
|
||||
options,
|
||||
direction,
|
||||
isSelectElement,
|
||||
isSelectOneElement,
|
||||
|
@ -69,7 +86,7 @@ describe('templates', () => {
|
|||
|
||||
const expectedOutput = strToEl(`
|
||||
<div
|
||||
class="${classes.containerOuter}"
|
||||
class="${options.classNames.containerOuter}"
|
||||
data-type="${passedElementType}"
|
||||
role="listbox"
|
||||
aria-haspopup="true"
|
||||
|
@ -79,7 +96,7 @@ describe('templates', () => {
|
|||
</div>
|
||||
`);
|
||||
const actualOutput = templates.containerOuter(
|
||||
classes,
|
||||
options,
|
||||
direction,
|
||||
isSelectElement,
|
||||
isSelectOneElement,
|
||||
|
@ -100,7 +117,7 @@ describe('templates', () => {
|
|||
|
||||
const expectedOutput = strToEl(`
|
||||
<div
|
||||
class="${classes.containerOuter}"
|
||||
class="${options.classNames.containerOuter}"
|
||||
data-type="${passedElementType}"
|
||||
role="listbox"
|
||||
tabindex="0"
|
||||
|
@ -111,7 +128,7 @@ describe('templates', () => {
|
|||
</div>
|
||||
`);
|
||||
const actualOutput = templates.containerOuter(
|
||||
classes,
|
||||
options,
|
||||
direction,
|
||||
isSelectElement,
|
||||
isSelectOneElement,
|
||||
|
@ -133,7 +150,7 @@ describe('templates', () => {
|
|||
|
||||
const expectedOutput = strToEl(`
|
||||
<div
|
||||
class="${classes.containerOuter}"
|
||||
class="${options.classNames.containerOuter}"
|
||||
data-type="${passedElementType}"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
|
@ -142,7 +159,7 @@ describe('templates', () => {
|
|||
</div>
|
||||
`);
|
||||
const actualOutput = templates.containerOuter(
|
||||
classes,
|
||||
options,
|
||||
direction,
|
||||
isSelectElement,
|
||||
isSelectOneElement,
|
||||
|
@ -157,31 +174,31 @@ describe('templates', () => {
|
|||
|
||||
describe('containerInner', () => {
|
||||
it('returns expected html', () => {
|
||||
const classes = {
|
||||
const innerOptions = createOptionsWithPartialClasses({
|
||||
containerInner: 'class-1',
|
||||
};
|
||||
});
|
||||
const expectedOutput = strToEl(
|
||||
`<div class="${classes.containerInner}"></div>`,
|
||||
`<div class="${innerOptions.classNames.containerInner}"></div>`,
|
||||
);
|
||||
const actualOutput = templates.containerInner(classes);
|
||||
const actualOutput = templates.containerInner(innerOptions);
|
||||
|
||||
expectEqualElements(actualOutput, expectedOutput);
|
||||
});
|
||||
});
|
||||
|
||||
describe('itemList', () => {
|
||||
const classes = {
|
||||
const itemOptions = createOptionsWithPartialClasses({
|
||||
list: 'class-1',
|
||||
listSingle: 'class-2',
|
||||
listItems: 'class-3',
|
||||
};
|
||||
});
|
||||
|
||||
describe('select one element', () => {
|
||||
it('returns expected html', () => {
|
||||
const expectedOutput = strToEl(
|
||||
`<div class="${classes.list} ${classes.listSingle}"></div>`,
|
||||
`<div class="${itemOptions.classNames.list} ${itemOptions.classNames.listSingle}"></div>`,
|
||||
);
|
||||
const actualOutput = templates.itemList(classes, true);
|
||||
const actualOutput = templates.itemList(itemOptions, true);
|
||||
|
||||
expectEqualElements(actualOutput, expectedOutput);
|
||||
});
|
||||
|
@ -190,9 +207,9 @@ describe('templates', () => {
|
|||
describe('non select one element', () => {
|
||||
it('returns expected html', () => {
|
||||
const expectedOutput = strToEl(
|
||||
`<div class="${classes.list} ${classes.listItems}"></div>`,
|
||||
`<div class="${itemOptions.classNames.list} ${itemOptions.classNames.listItems}"></div>`,
|
||||
);
|
||||
const actualOutput = templates.itemList(classes, false);
|
||||
const actualOutput = templates.itemList(itemOptions, false);
|
||||
|
||||
expectEqualElements(actualOutput, expectedOutput);
|
||||
});
|
||||
|
@ -201,33 +218,33 @@ describe('templates', () => {
|
|||
|
||||
describe('placeholder', () => {
|
||||
it('returns expected html', () => {
|
||||
const classes = {
|
||||
const placeholderOptions = createOptionsWithPartialClasses({
|
||||
placeholder: 'class-1',
|
||||
};
|
||||
});
|
||||
const value = 'test';
|
||||
const expectedOutput = strToEl(`
|
||||
<div class="${classes.placeholder}">${value}</div>`);
|
||||
const actualOutput = templates.placeholder(classes, value);
|
||||
<div class="${placeholderOptions.classNames.placeholder}">${value}</div>`);
|
||||
const actualOutput = templates.placeholder(placeholderOptions, value);
|
||||
|
||||
expectEqualElements(actualOutput, expectedOutput);
|
||||
});
|
||||
});
|
||||
|
||||
describe('choiceList', () => {
|
||||
const classes = {
|
||||
const choiceListOptions = createOptionsWithPartialClasses({
|
||||
list: 'class-1',
|
||||
};
|
||||
});
|
||||
|
||||
describe('select one element', () => {
|
||||
it('returns expected html', () => {
|
||||
const expectedOutput = strToEl(`
|
||||
<div
|
||||
class="${classes.list}"
|
||||
class="${choiceListOptions.classNames.list}"
|
||||
role="listbox"
|
||||
>
|
||||
</div>
|
||||
`);
|
||||
const actualOutput = templates.choiceList(classes, true);
|
||||
const actualOutput = templates.choiceList(choiceListOptions, true);
|
||||
|
||||
expectEqualElements(actualOutput, expectedOutput);
|
||||
});
|
||||
|
@ -237,13 +254,13 @@ describe('templates', () => {
|
|||
it('returns expected html', () => {
|
||||
const expectedOutput = strToEl(`
|
||||
<div
|
||||
class="${classes.list}"
|
||||
class="${choiceListOptions.classNames.list}"
|
||||
role="listbox"
|
||||
aria-multiselectable="true"
|
||||
>
|
||||
</div>
|
||||
`);
|
||||
const actualOutput = templates.choiceList(classes, false);
|
||||
const actualOutput = templates.choiceList(choiceListOptions, false);
|
||||
|
||||
expectEqualElements(actualOutput, expectedOutput);
|
||||
});
|
||||
|
@ -251,11 +268,11 @@ describe('templates', () => {
|
|||
});
|
||||
|
||||
describe('choiceGroup', () => {
|
||||
const classes = {
|
||||
const groupOptions = createOptionsWithPartialClasses({
|
||||
group: 'class-1',
|
||||
groupHeading: 'class-2',
|
||||
itemDisabled: 'class-3',
|
||||
};
|
||||
});
|
||||
|
||||
let data;
|
||||
|
||||
|
@ -271,16 +288,16 @@ describe('templates', () => {
|
|||
it('returns expected html', () => {
|
||||
const expectedOutput = strToEl(`
|
||||
<div
|
||||
class="${classes.group}"
|
||||
class="${groupOptions.classNames.group}"
|
||||
data-group
|
||||
data-id="${data.id}"
|
||||
data-value="${data.value}"
|
||||
role="group"
|
||||
>
|
||||
<div class="${classes.groupHeading}">${data.value}</div>
|
||||
<div class="${groupOptions.classNames.groupHeading}">${data.value}</div>
|
||||
</div>
|
||||
`);
|
||||
const actualOutput = templates.choiceGroup(classes, data);
|
||||
const actualOutput = templates.choiceGroup(groupOptions, data);
|
||||
|
||||
expectEqualElements(actualOutput, expectedOutput);
|
||||
});
|
||||
|
@ -297,17 +314,17 @@ describe('templates', () => {
|
|||
it('returns expected html', () => {
|
||||
const expectedOutput = strToEl(`
|
||||
<div
|
||||
class="${classes.group} ${classes.itemDisabled}"
|
||||
class="${groupOptions.classNames.group} ${groupOptions.classNames.itemDisabled}"
|
||||
data-group
|
||||
data-id="${data.id}"
|
||||
data-value="${data.value}"
|
||||
role="group"
|
||||
aria-disabled="true"
|
||||
>
|
||||
<div class="${classes.groupHeading}">${data.value}</div>
|
||||
<div class="${groupOptions.classNames.groupHeading}">${data.value}</div>
|
||||
</div>
|
||||
`);
|
||||
const actualOutput = templates.choiceGroup(classes, data);
|
||||
const actualOutput = templates.choiceGroup(groupOptions, data);
|
||||
|
||||
expectEqualElements(actualOutput, expectedOutput);
|
||||
});
|
||||
|
@ -315,14 +332,14 @@ describe('templates', () => {
|
|||
});
|
||||
|
||||
describe('choice', () => {
|
||||
const classes = {
|
||||
const choiceOptions = createOptionsWithPartialClasses({
|
||||
item: 'class-1',
|
||||
itemChoice: 'class-2',
|
||||
itemDisabled: 'class-3',
|
||||
itemSelectable: 'class-4',
|
||||
placeholder: 'class-5',
|
||||
selectedState: 'class-6',
|
||||
};
|
||||
});
|
||||
|
||||
const itemSelectText = 'test 6';
|
||||
|
||||
|
@ -344,7 +361,7 @@ describe('templates', () => {
|
|||
it('returns expected html', () => {
|
||||
const expectedOutput = strToEl(`
|
||||
<div
|
||||
class="${classes.item} ${classes.itemChoice} ${classes.itemSelectable}"
|
||||
class="${choiceOptions.classNames.item} ${choiceOptions.classNames.itemChoice} ${choiceOptions.classNames.itemSelectable}"
|
||||
data-select-text="${itemSelectText}"
|
||||
data-choice
|
||||
data-id="${data.id}"
|
||||
|
@ -356,7 +373,11 @@ describe('templates', () => {
|
|||
${data.label}
|
||||
</div>
|
||||
`);
|
||||
const actualOutput = templates.choice(classes, data, itemSelectText);
|
||||
const actualOutput = templates.choice(
|
||||
choiceOptions,
|
||||
data,
|
||||
itemSelectText,
|
||||
);
|
||||
|
||||
expectEqualElements(actualOutput, expectedOutput);
|
||||
});
|
||||
|
@ -373,7 +394,7 @@ describe('templates', () => {
|
|||
it('returns expected html', () => {
|
||||
const expectedOutput = strToEl(`
|
||||
<div
|
||||
class="${classes.item} ${classes.itemChoice} ${classes.itemDisabled}"
|
||||
class="${choiceOptions.classNames.item} ${choiceOptions.classNames.itemChoice} ${choiceOptions.classNames.itemDisabled}"
|
||||
data-select-text="${itemSelectText}"
|
||||
data-choice
|
||||
data-id="${data.id}"
|
||||
|
@ -386,7 +407,11 @@ describe('templates', () => {
|
|||
${data.label}
|
||||
</div>
|
||||
`);
|
||||
const actualOutput = templates.choice(classes, data, itemSelectText);
|
||||
const actualOutput = templates.choice(
|
||||
choiceOptions,
|
||||
data,
|
||||
itemSelectText,
|
||||
);
|
||||
|
||||
expectEqualElements(actualOutput, expectedOutput);
|
||||
});
|
||||
|
@ -403,7 +428,7 @@ describe('templates', () => {
|
|||
it('returns expected html', () => {
|
||||
const expectedOutput = strToEl(`
|
||||
<div
|
||||
class="${classes.item} ${classes.itemChoice} ${classes.selectedState} ${classes.itemSelectable}"
|
||||
class="${choiceOptions.classNames.item} ${choiceOptions.classNames.itemChoice} ${choiceOptions.classNames.selectedState} ${choiceOptions.classNames.itemSelectable}"
|
||||
data-select-text="${itemSelectText}"
|
||||
data-choice
|
||||
data-id="${data.id}"
|
||||
|
@ -415,7 +440,11 @@ describe('templates', () => {
|
|||
${data.label}
|
||||
</div>
|
||||
`);
|
||||
const actualOutput = templates.choice(classes, data, itemSelectText);
|
||||
const actualOutput = templates.choice(
|
||||
choiceOptions,
|
||||
data,
|
||||
itemSelectText,
|
||||
);
|
||||
|
||||
expectEqualElements(actualOutput, expectedOutput);
|
||||
});
|
||||
|
@ -432,7 +461,7 @@ describe('templates', () => {
|
|||
it('returns expected html', () => {
|
||||
const expectedOutput = strToEl(`
|
||||
<div
|
||||
class="${classes.item} ${classes.itemChoice} ${classes.placeholder} ${classes.itemSelectable}"
|
||||
class="${choiceOptions.classNames.item} ${choiceOptions.classNames.itemChoice} ${choiceOptions.classNames.placeholder} ${choiceOptions.classNames.itemSelectable}"
|
||||
data-select-text="${itemSelectText}"
|
||||
data-choice
|
||||
data-id="${data.id}"
|
||||
|
@ -444,7 +473,11 @@ describe('templates', () => {
|
|||
${data.label}
|
||||
</div>
|
||||
`);
|
||||
const actualOutput = templates.choice(classes, data, itemSelectText);
|
||||
const actualOutput = templates.choice(
|
||||
choiceOptions,
|
||||
data,
|
||||
itemSelectText,
|
||||
);
|
||||
|
||||
expectEqualElements(actualOutput, expectedOutput);
|
||||
});
|
||||
|
@ -461,7 +494,7 @@ describe('templates', () => {
|
|||
it('returns expected html', () => {
|
||||
const expectedOutput = strToEl(`
|
||||
<div
|
||||
class="${classes.item} ${classes.itemChoice} ${classes.itemSelectable}"
|
||||
class="${choiceOptions.classNames.item} ${choiceOptions.classNames.itemChoice} ${choiceOptions.classNames.itemSelectable}"
|
||||
data-select-text="${itemSelectText}"
|
||||
data-choice
|
||||
data-id="${data.id}"
|
||||
|
@ -473,7 +506,11 @@ describe('templates', () => {
|
|||
${data.label}
|
||||
</div>
|
||||
`);
|
||||
const actualOutput = templates.choice(classes, data, itemSelectText);
|
||||
const actualOutput = templates.choice(
|
||||
choiceOptions,
|
||||
data,
|
||||
itemSelectText,
|
||||
);
|
||||
|
||||
expectEqualElements(actualOutput, expectedOutput);
|
||||
});
|
||||
|
@ -481,10 +518,10 @@ describe('templates', () => {
|
|||
});
|
||||
|
||||
describe('input', () => {
|
||||
const classes = {
|
||||
const inputOptions = createOptionsWithPartialClasses({
|
||||
input: 'class-1',
|
||||
inputCloned: 'class-2',
|
||||
};
|
||||
});
|
||||
|
||||
it('returns expected html', () => {
|
||||
/*
|
||||
|
@ -496,52 +533,52 @@ describe('templates', () => {
|
|||
<input
|
||||
type="search"
|
||||
name="search_terms"
|
||||
class="${classes.input} ${classes.inputCloned}"
|
||||
class="${inputOptions.classNames.input} ${inputOptions.classNames.inputCloned}"
|
||||
autocomplete="off"
|
||||
role="textbox"
|
||||
aria-autocomplete="list"
|
||||
aria-label="test placeholder"
|
||||
>
|
||||
`);
|
||||
const actualOutput = templates.input(classes, 'test placeholder');
|
||||
const actualOutput = templates.input(inputOptions, 'test placeholder');
|
||||
|
||||
expectEqualElements(actualOutput, expectedOutput);
|
||||
});
|
||||
});
|
||||
|
||||
describe('dropdown', () => {
|
||||
const classes = {
|
||||
const dropdownOptions = createOptionsWithPartialClasses({
|
||||
list: 'class-1',
|
||||
listDropdown: 'class-2',
|
||||
};
|
||||
});
|
||||
|
||||
it('returns expected html', () => {
|
||||
const expectedOutput = strToEl(
|
||||
`<div class="${classes.list} ${classes.listDropdown}" aria-expanded="false"></div>`,
|
||||
`<div class="${dropdownOptions.classNames.list} ${dropdownOptions.classNames.listDropdown}" aria-expanded="false"></div>`,
|
||||
);
|
||||
const actualOutput = templates.dropdown(classes);
|
||||
const actualOutput = templates.dropdown(dropdownOptions);
|
||||
|
||||
expectEqualElements(actualOutput, expectedOutput);
|
||||
});
|
||||
});
|
||||
|
||||
describe('notice', () => {
|
||||
const classes = {
|
||||
const noticeOptions = createOptionsWithPartialClasses({
|
||||
item: 'class-1',
|
||||
itemChoice: 'class-2',
|
||||
noResults: 'class-3',
|
||||
noChoices: 'class-4',
|
||||
};
|
||||
});
|
||||
|
||||
const label = 'test';
|
||||
|
||||
it('returns expected html', () => {
|
||||
const expectedOutput = strToEl(`
|
||||
<div class="${classes.item} ${classes.itemChoice}">
|
||||
<div class="${noticeOptions.classNames.item} ${noticeOptions.classNames.itemChoice}">
|
||||
${label}
|
||||
</div>
|
||||
`);
|
||||
const actualOutput = templates.notice(classes, label);
|
||||
const actualOutput = templates.notice(noticeOptions, label);
|
||||
|
||||
expectEqualElements(actualOutput, expectedOutput);
|
||||
});
|
||||
|
@ -550,11 +587,15 @@ describe('templates', () => {
|
|||
describe('no results', () => {
|
||||
it('adds no results classname', () => {
|
||||
const expectedOutput = strToEl(`
|
||||
<div class="${classes.item} ${classes.itemChoice} ${classes.noResults}">
|
||||
<div class="${noticeOptions.classNames.item} ${noticeOptions.classNames.itemChoice} ${noticeOptions.classNames.noResults}">
|
||||
${label}
|
||||
</div>
|
||||
`);
|
||||
const actualOutput = templates.notice(classes, label, 'no-results');
|
||||
const actualOutput = templates.notice(
|
||||
noticeOptions,
|
||||
label,
|
||||
'no-results',
|
||||
);
|
||||
|
||||
expectEqualElements(actualOutput, expectedOutput);
|
||||
});
|
||||
|
@ -563,11 +604,15 @@ describe('templates', () => {
|
|||
describe('no choices', () => {
|
||||
it('adds no choices classname', () => {
|
||||
const expectedOutput = strToEl(`
|
||||
<div class="${classes.item} ${classes.itemChoice} ${classes.noChoices}">
|
||||
<div class="${noticeOptions.classNames.item} ${noticeOptions.classNames.itemChoice} ${noticeOptions.classNames.noChoices}">
|
||||
${label}
|
||||
</div>
|
||||
`);
|
||||
const actualOutput = templates.notice(classes, label, 'no-choices');
|
||||
const actualOutput = templates.notice(
|
||||
noticeOptions,
|
||||
label,
|
||||
'no-choices',
|
||||
);
|
||||
|
||||
expectEqualElements(actualOutput, expectedOutput);
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue