fix: template testing & type errors

This commit is contained in:
viction 2021-12-24 17:32:50 +00:00
parent 7f727480e8
commit 6b16e93977
3 changed files with 117 additions and 70 deletions

View file

@ -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>(

View file

@ -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;

View file

@ -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);
});