Choices/test/scripts/components/wrapped-select.test.ts
2025-03-14 09:36:07 +08:00

134 lines
3.8 KiB
TypeScript

import { expect } from 'chai';
import { stub, spy } from 'sinon';
import WrappedElement from '../../../src/scripts/components/wrapped-element';
import WrappedSelect from '../../../src/scripts/components/wrapped-select';
import Templates from '../../../src/scripts/templates';
import { DEFAULT_CLASSNAMES } from '../../../src';
describe('components/wrappedSelect', () => {
let instance: WrappedSelect | null;
let element: HTMLSelectElement;
beforeEach(() => {
element = document.createElement('select');
element.id = 'target';
for (let i = 0; i <= 4; i++) {
const option = document.createElement('option');
if (i === 0) {
option.value = '';
option.innerHTML = 'Placeholder label';
} else {
option.value = `Value ${i}`;
if (i % 2 === 0) {
option.innerHTML = `Label ${i}`;
} else {
option.label = `Label ${i}`;
}
}
if (i === 1) {
option.setAttribute('placeholder', '');
}
element.appendChild(option);
}
document.body.appendChild(element);
instance = new WrappedSelect({
element: document.getElementById('target') as HTMLSelectElement,
classNames: DEFAULT_CLASSNAMES,
template: spy(Templates.option),
extractPlaceholder: true,
});
});
afterEach(() => {
document.body.innerHTML = '';
instance = null;
});
describe('constructor', () => {
it('assigns choices element to class', () => {
expect(instance).to.not.be.null;
if (!instance) {
return;
}
expect(instance.element).to.equal(element);
});
it('assigns classnames to class', () => {
expect(instance).to.not.be.null;
if (!instance) {
return;
}
expect(instance.classNames).to.deep.equal(DEFAULT_CLASSNAMES);
});
});
describe('inherited methods', () => {
const methods: string[] = ['conceal', 'reveal', 'enable', 'disable'];
methods.forEach((method) => {
beforeEach(() => {
stub(WrappedElement.prototype, method as keyof WrappedElement<HTMLSelectElement>);
});
afterEach(() => {
WrappedElement.prototype[method].restore();
});
describe(method, () => {
it(`calls super.${method}`, () => {
expect(instance).to.not.be.null;
if (!instance) {
return;
}
expect(WrappedElement.prototype[method].called).to.equal(false);
instance[method]();
expect(WrappedElement.prototype[method].called).to.equal(true);
});
});
});
});
describe('placeholderOption getter', () => {
it('returns option element with empty value attribute', () => {
expect(instance).to.not.be.null;
if (!instance) {
return;
}
expect(instance.placeholderOption).to.be.instanceOf(HTMLOptionElement);
if (instance.placeholderOption) {
expect(instance.placeholderOption.value).to.equal('');
}
});
it('returns option element with placeholder attribute as fallback', () => {
expect(instance).to.not.be.null;
if (!instance) {
return;
}
expect(instance.element.firstChild).to.not.be.null;
if (instance.element.firstChild) {
instance.element.removeChild(instance.element.firstChild);
}
expect(instance.placeholderOption).to.be.instanceOf(HTMLOptionElement);
if (instance.placeholderOption) {
expect(instance.placeholderOption.value).to.equal('Value 1');
}
});
});
describe('options getter', () => {
it('returns all option elements', () => {
expect(instance).to.not.be.null;
if (!instance) {
return;
}
const optionsAsChoices = instance.optionsAsChoices();
expect(optionsAsChoices).to.be.an('array');
});
});
});