second commit

This commit is contained in:
2024-12-27 22:31:23 +09:00
parent 2353324570
commit 10a0f110ca
8819 changed files with 1307198 additions and 28 deletions

View File

@ -0,0 +1,547 @@
describe('DateRangePicker', function () {
let clock;
let elem;
let input0;
let input1;
before(function () {
clock = sinon.useFakeTimers({now: new Date(2020, 1, 14)});
});
after(function () {
clock.restore();
});
beforeEach(function () {
elem = domUtils.parseHTML('<div><input><input></div>').firstChild;
[input0, input1] = elem.children;
testContainer.appendChild(elem);
});
afterEach(function () {
testContainer.removeChild(elem);
});
it('input elements\' values are used for the initial dates', function () {
input0.value = '04/20/2020';
input1.value = '04/22/2020';
const drp = new DateRangePicker(elem);
expect(drp.dates, 'to equal', [dateValue(2020, 3, 20), dateValue(2020, 3, 22)]);
drp.destroy();
input0.value = '';
input1.value = '';
});
it('the pickers are hidden at start', function () {
const {drp, picker0, picker1} = createDRP(elem);
expect(isVisible(picker0), 'to be false');
expect(isVisible(picker1), 'to be false');
drp.destroy();
});
it('the pickers becomes visible when the input element get focus and invisivle when losing focus', function () {
const {drp, picker0, picker1} = createDRP(elem);
input0.focus();
expect(isVisible(picker0), 'to be true');
simulant.fire(input0, 'keydown', {key: 'Tab'});
expect(isVisible(picker0), 'to be false');
input1.focus();
expect(isVisible(picker1), 'to be true');
simulant.fire(input1, 'keydown', {key: 'Tab'});
expect(isVisible(picker1), 'to be false');
drp.destroy();
});
it('indicates the range with hilighting the start/end in the pickers', function () {
input0.value = '04/20/2020';
input1.value = '04/22/2020';
const partsClasses = ['.view-switch', '.prev-btn', '.next-btn'];
let {drp, picker0, picker1} = createDRP(elem);
let [viewSwitch0, prevBtn0, nextBtn0] = getParts(picker0, partsClasses);
let [viewSwitch1, prevBtn1, nextBtn1] = getParts(picker1, partsClasses);
input0.focus();
let cells = getCells(picker0);
expect(viewSwitch0.textContent, 'to be', 'April 2020');
expect(getCellIndices(cells, '.selected'), 'to equal', [22]);
expect(getCellIndices(cells, '.range-start'), 'to equal', [22]);
expect(getCellIndices(cells, '.range-end'), 'to equal', [24]);
expect(getCellIndices(cells, '.range'), 'to equal', [23]);
expect(getCellIndices(cells, '.focused'), 'to equal', [22]);
input1.focus();
cells = getCells(picker1);
expect(viewSwitch1.textContent, 'to be', 'April 2020');
expect(getCellIndices(cells, '.selected'), 'to equal', [24]);
expect(getCellIndices(cells, '.range-start'), 'to equal', [22]);
expect(getCellIndices(cells, '.range-end'), 'to equal', [24]);
expect(getCellIndices(cells, '.range'), 'to equal', [23]);
expect(getCellIndices(cells, '.focused'), 'to equal', [24]);
drp.destroy();
// range over months (days → months views)
input0.value = '02/26/2020';
input1.value = '04/12/2020';
({drp, picker0, picker1} = createDRP(elem));
([viewSwitch0, prevBtn0, nextBtn0] = getParts(picker0, partsClasses));
([viewSwitch1, prevBtn1, nextBtn1] = getParts(picker1, partsClasses));
// range-start
input0.focus();
cells = getCells(picker0);
expect(viewSwitch0.textContent, 'to be', 'February 2020');
expect(getCellIndices(cells, '.selected'), 'to equal', [31]);
expect(getCellIndices(cells, '.range-start'), 'to equal', [31]);
expect(getCellIndices(cells, '.range-end'), 'to equal', []);
expect(getCellIndices(cells, '.range'), 'to equal', [32, 33, 34, 35, 36, 37, 38, 39, 40, 41]);
expect(getCellIndices(cells, '.focused'), 'to equal', [31]);
prevBtn0.click();
cells = getCells(picker0);
expect(viewSwitch0.textContent, 'to be', 'January 2020');
expect(getCellIndices(cells, '.selected'), 'to equal', []);
expect(getCellIndices(cells, '.range-start'), 'to equal', []);
expect(getCellIndices(cells, '.range-end'), 'to equal', []);
expect(getCellIndices(cells, '.range'), 'to equal', []);
expect(getCellIndices(cells, '.focused'), 'to equal', [28]);
nextBtn0.click();
nextBtn0.click();
cells = getCells(picker0);
expect(viewSwitch0.textContent, 'to be', 'March 2020');
expect(getCellIndices(cells, '.selected'), 'to equal', []);
expect(getCellIndices(cells, '.range-start'), 'to equal', []);
expect(getCellIndices(cells, '.range-end'), 'to equal', []);
expect(getCellIndices(cells, '.range').length, 'to be', 42);
expect(getCellIndices(cells, '.focused'), 'to equal', [25]);
nextBtn0.click();
cells = getCells(picker0);
expect(viewSwitch0.textContent, 'to be', 'April 2020');
expect(getCellIndices(cells, '.selected'), 'to equal', []);
expect(getCellIndices(cells, '.range-start'), 'to equal', []);
expect(getCellIndices(cells, '.range-end'), 'to equal', [14]);
expect(getCellIndices(cells, '.range'), 'to equal', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]);
expect(getCellIndices(cells, '.focused'), 'to equal', [28]);
viewSwitch0.click();
cells = getCells(picker0);
expect(viewSwitch0.textContent, 'to be', '2020');
expect(getCellIndices(cells, '.selected'), 'to equal', [1]);
expect(getCellIndices(cells, '.range-start'), 'to equal', [1]);
expect(getCellIndices(cells, '.range-end'), 'to equal', [3]);
expect(getCellIndices(cells, '.range'), 'to equal', [2]);
expect(getCellIndices(cells, '.focused'), 'to equal', [3]);
// range-end
input1.focus();
cells = getCells(picker1);
expect(viewSwitch1.textContent, 'to be', 'April 2020');
expect(getCellIndices(cells, '.selected'), 'to equal', [14]);
expect(getCellIndices(cells, '.range-start'), 'to equal', []);
expect(getCellIndices(cells, '.range-end'), 'to equal', [14]);
expect(getCellIndices(cells, '.range'), 'to equal', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]);
expect(getCellIndices(cells, '.focused'), 'to equal', [14]);
nextBtn1.click();
cells = getCells(picker1);
expect(viewSwitch1.textContent, 'to be', 'May 2020');
expect(getCellIndices(cells, '.selected'), 'to equal', []);
expect(getCellIndices(cells, '.range-start'), 'to equal', []);
expect(getCellIndices(cells, '.range-end'), 'to equal', []);
expect(getCellIndices(cells, '.range'), 'to equal', []);
expect(getCellIndices(cells, '.focused'), 'to equal', [16]);
prevBtn1.click();
prevBtn1.click();
cells = getCells(picker1);
expect(viewSwitch1.textContent, 'to be', 'March 2020');
expect(getCellIndices(cells, '.selected'), 'to equal', []);
expect(getCellIndices(cells, '.range-start'), 'to equal', []);
expect(getCellIndices(cells, '.range-end'), 'to equal', []);
expect(getCellIndices(cells, '.range').length, 'to be', 42);
expect(getCellIndices(cells, '.focused'), 'to equal', [11]);
prevBtn1.click();
cells = getCells(picker1);
expect(viewSwitch1.textContent, 'to be', 'February 2020');
expect(getCellIndices(cells, '.selected'), 'to equal', []);
expect(getCellIndices(cells, '.range-start'), 'to equal', [31]);
expect(getCellIndices(cells, '.range-end'), 'to equal', []);
expect(getCellIndices(cells, '.range'), 'to equal', [32, 33, 34, 35, 36, 37, 38, 39, 40, 41]);
expect(getCellIndices(cells, '.focused'), 'to equal', [17]);
viewSwitch1.click();
cells = getCells(picker1);
expect(viewSwitch0.textContent, 'to be', '2020');
expect(getCellIndices(cells, '.selected'), 'to equal', [3]);
expect(getCellIndices(cells, '.range-start'), 'to equal', [1]);
expect(getCellIndices(cells, '.range-end'), 'to equal', [3]);
expect(getCellIndices(cells, '.range'), 'to equal', [2]);
expect(getCellIndices(cells, '.focused'), 'to equal', [1]);
drp.destroy();
// range over years (months → years views)
input0.value = '10/01/2020';
input1.value = '03/31/2023';
({drp, picker0, picker1} = createDRP(elem));
([viewSwitch0, prevBtn0, nextBtn0] = getParts(picker0, partsClasses));
([viewSwitch1, prevBtn1, nextBtn1] = getParts(picker1, partsClasses));
// range-start
input0.focus();
viewSwitch0.click();
cells = getCells(picker0);
expect(viewSwitch0.textContent, 'to be', '2020');
expect(getCellIndices(cells, '.selected'), 'to equal', [9]);
expect(getCellIndices(cells, '.range-start'), 'to equal', [9]);
expect(getCellIndices(cells, '.range-end'), 'to equal', []);
expect(getCellIndices(cells, '.range'), 'to equal', [10, 11]);
expect(getCellIndices(cells, '.focused'), 'to equal', [9]);
prevBtn0.click();
cells = getCells(picker0);
expect(viewSwitch0.textContent, 'to be', '2019');
expect(getCellIndices(cells, '.selected'), 'to equal', []);
expect(getCellIndices(cells, '.range-start'), 'to equal', []);
expect(getCellIndices(cells, '.range-end'), 'to equal', []);
expect(getCellIndices(cells, '.range'), 'to equal', []);
expect(getCellIndices(cells, '.focused'), 'to equal', [9]);
nextBtn0.click();
nextBtn0.click();
cells = getCells(picker0);
expect(viewSwitch0.textContent, 'to be', '2021');
expect(getCellIndices(cells, '.selected'), 'to equal', []);
expect(getCellIndices(cells, '.range-start'), 'to equal', []);
expect(getCellIndices(cells, '.range-end'), 'to equal', []);
expect(getCellIndices(cells, '.range').length, 'to be', 12);
expect(getCellIndices(cells, '.focused'), 'to equal', [9]);
nextBtn0.click();
nextBtn0.click();
cells = getCells(picker0);
expect(viewSwitch0.textContent, 'to be', '2023');
expect(getCellIndices(cells, '.selected'), 'to equal', []);
expect(getCellIndices(cells, '.range-start'), 'to equal', []);
expect(getCellIndices(cells, '.range-end'), 'to equal', [2]);
expect(getCellIndices(cells, '.range'), 'to equal', [0, 1]);
expect(getCellIndices(cells, '.focused'), 'to equal', [9]);
viewSwitch0.click();
cells = getCells(picker0);
expect(viewSwitch0.textContent, 'to be', '2020-2029');
expect(getCellIndices(cells, '.selected'), 'to equal', [1]);
expect(getCellIndices(cells, '.range-start'), 'to equal', [1]);
expect(getCellIndices(cells, '.range-end'), 'to equal', [4]);
expect(getCellIndices(cells, '.range'), 'to equal', [2, 3]);
expect(getCellIndices(cells, '.focused'), 'to equal', [4]);
// range-end
input1.focus();
viewSwitch1.click();
cells = getCells(picker1);
expect(viewSwitch1.textContent, 'to be', '2023');
expect(getCellIndices(cells, '.selected'), 'to equal', [2]);
expect(getCellIndices(cells, '.range-start'), 'to equal', []);
expect(getCellIndices(cells, '.range-end'), 'to equal', [2]);
expect(getCellIndices(cells, '.range'), 'to equal', [0, 1]);
expect(getCellIndices(cells, '.focused'), 'to equal', [2]);
nextBtn1.click();
cells = getCells(picker1);
expect(viewSwitch1.textContent, 'to be', '2024');
expect(getCellIndices(cells, '.selected'), 'to equal', []);
expect(getCellIndices(cells, '.range-start'), 'to equal', []);
expect(getCellIndices(cells, '.range-end'), 'to equal', []);
expect(getCellIndices(cells, '.range'), 'to equal', []);
expect(getCellIndices(cells, '.focused'), 'to equal', [2]);
prevBtn1.click();
prevBtn1.click();
cells = getCells(picker1);
expect(viewSwitch1.textContent, 'to be', '2022');
expect(getCellIndices(cells, '.selected'), 'to equal', []);
expect(getCellIndices(cells, '.range-start'), 'to equal', []);
expect(getCellIndices(cells, '.range-end'), 'to equal', []);
expect(getCellIndices(cells, '.range').length, 'to be', 12);
expect(getCellIndices(cells, '.focused'), 'to equal', [2]);
prevBtn1.click();
prevBtn1.click();
cells = getCells(picker1);
expect(viewSwitch1.textContent, 'to be', '2020');
expect(getCellIndices(cells, '.selected'), 'to equal', []);
expect(getCellIndices(cells, '.range-start'), 'to equal', [9]);
expect(getCellIndices(cells, '.range-end'), 'to equal', []);
expect(getCellIndices(cells, '.range'), 'to equal', [10, 11]);
expect(getCellIndices(cells, '.focused'), 'to equal', [2]);
viewSwitch1.click();
cells = getCells(picker1);
expect(viewSwitch1.textContent, 'to be', '2020-2029');
expect(getCellIndices(cells, '.selected'), 'to equal', [4]);
expect(getCellIndices(cells, '.range-start'), 'to equal', [1]);
expect(getCellIndices(cells, '.range-end'), 'to equal', [4]);
expect(getCellIndices(cells, '.range'), 'to equal', [2, 3]);
expect(getCellIndices(cells, '.focused'), 'to equal', [1]);
drp.destroy();
// range over decades (years → decades views)
input0.value = '01/01/2017';
input1.value = '12/31/2041';
({drp, picker0, picker1} = createDRP(elem));
([viewSwitch0, prevBtn0, nextBtn0] = getParts(picker0, partsClasses));
([viewSwitch1, prevBtn1, nextBtn1] = getParts(picker1, partsClasses));
// range-start
input0.focus();
viewSwitch0.click();
viewSwitch0.click();
cells = getCells(picker0);
expect(viewSwitch0.textContent, 'to be', '2010-2019');
expect(getCellIndices(cells, '.selected'), 'to equal', [8]);
expect(getCellIndices(cells, '.range-start'), 'to equal', [8]);
expect(getCellIndices(cells, '.range-end'), 'to equal', []);
expect(getCellIndices(cells, '.range'), 'to equal', [9, 10, 11]);
expect(getCellIndices(cells, '.focused'), 'to equal', [8]);
prevBtn0.click();
cells = getCells(picker0);
expect(viewSwitch0.textContent, 'to be', '2000-2009');
expect(getCellIndices(cells, '.selected'), 'to equal', []);
expect(getCellIndices(cells, '.range-start'), 'to equal', []);
expect(getCellIndices(cells, '.range-end'), 'to equal', []);
expect(getCellIndices(cells, '.range'), 'to equal', []);
expect(getCellIndices(cells, '.focused'), 'to equal', [8]);
nextBtn0.click();
nextBtn0.click();
cells = getCells(picker0);
expect(viewSwitch0.textContent, 'to be', '2020-2029');
expect(getCellIndices(cells, '.selected'), 'to equal', []);
expect(getCellIndices(cells, '.range-start'), 'to equal', []);
expect(getCellIndices(cells, '.range-end'), 'to equal', []);
expect(getCellIndices(cells, '.range').length, 'to be', 12);
expect(getCellIndices(cells, '.focused'), 'to equal', [8]);
nextBtn0.click();
nextBtn0.click();
cells = getCells(picker0);
expect(viewSwitch0.textContent, 'to be', '2040-2049');
expect(getCellIndices(cells, '.selected'), 'to equal', []);
expect(getCellIndices(cells, '.range-start'), 'to equal', []);
expect(getCellIndices(cells, '.range-end'), 'to equal', [2]);
expect(getCellIndices(cells, '.range'), 'to equal', [0, 1]);
expect(getCellIndices(cells, '.focused'), 'to equal', [8]);
viewSwitch0.click();
cells = getCells(picker0);
expect(viewSwitch0.textContent, 'to be', '2000-2090');
expect(getCellIndices(cells, '.selected'), 'to equal', [2]);
expect(getCellIndices(cells, '.range-start'), 'to equal', [2]);
expect(getCellIndices(cells, '.range-end'), 'to equal', [5]);
expect(getCellIndices(cells, '.range'), 'to equal', [3, 4]);
expect(getCellIndices(cells, '.focused'), 'to equal', [5]);
// range-end
input1.focus();
viewSwitch1.click();
viewSwitch1.click();
cells = getCells(picker1);
expect(viewSwitch1.textContent, 'to be', '2040-2049');
expect(getCellIndices(cells, '.selected'), 'to equal', [2]);
expect(getCellIndices(cells, '.range-start'), 'to equal', []);
expect(getCellIndices(cells, '.range-end'), 'to equal', [2]);
expect(getCellIndices(cells, '.range'), 'to equal', [0, 1]);
expect(getCellIndices(cells, '.focused'), 'to equal', [2]);
nextBtn1.click();
cells = getCells(picker1);
expect(viewSwitch1.textContent, 'to be', '2050-2059');
expect(getCellIndices(cells, '.selected'), 'to equal', []);
expect(getCellIndices(cells, '.range-start'), 'to equal', []);
expect(getCellIndices(cells, '.range-end'), 'to equal', []);
expect(getCellIndices(cells, '.range'), 'to equal', []);
expect(getCellIndices(cells, '.focused'), 'to equal', [2]);
prevBtn1.click();
prevBtn1.click();
cells = getCells(picker1);
expect(viewSwitch1.textContent, 'to be', '2030-2039');
expect(getCellIndices(cells, '.selected'), 'to equal', []);
expect(getCellIndices(cells, '.range-start'), 'to equal', []);
expect(getCellIndices(cells, '.range-end'), 'to equal', []);
expect(getCellIndices(cells, '.range').length, 'to be', 12);
expect(getCellIndices(cells, '.focused'), 'to equal', [2]);
prevBtn1.click();
prevBtn1.click();
cells = getCells(picker1);
expect(viewSwitch1.textContent, 'to be', '2010-2019');
expect(getCellIndices(cells, '.selected'), 'to equal', []);
expect(getCellIndices(cells, '.range-start'), 'to equal', [8]);
expect(getCellIndices(cells, '.range-end'), 'to equal', []);
expect(getCellIndices(cells, '.range'), 'to equal', [9, 10, 11]);
expect(getCellIndices(cells, '.focused'), 'to equal', [2]);
viewSwitch1.click();
cells = getCells(picker1);
expect(viewSwitch1.textContent, 'to be', '2000-2090');
expect(getCellIndices(cells, '.selected'), 'to equal', [5]);
expect(getCellIndices(cells, '.range-start'), 'to equal', [2]);
expect(getCellIndices(cells, '.range-end'), 'to equal', [5]);
expect(getCellIndices(cells, '.range'), 'to equal', [3, 4]);
expect(getCellIndices(cells, '.focused'), 'to equal', [2]);
drp.destroy();
// range over centures (decades views)
input0.value = '01/22/1984';
input1.value = '12/31/2121';
({drp, picker0, picker1} = createDRP(elem));
([viewSwitch0, prevBtn0, nextBtn0] = getParts(picker0, partsClasses));
([viewSwitch1, prevBtn1, nextBtn1] = getParts(picker1, partsClasses));
// range-start
input0.focus();
viewSwitch0.click();
viewSwitch0.click();
viewSwitch0.click();
cells = getCells(picker0);
expect(viewSwitch0.textContent, 'to be', '1900-1990');
expect(getCellIndices(cells, '.selected'), 'to equal', [9]);
expect(getCellIndices(cells, '.range-start'), 'to equal', [9]);
expect(getCellIndices(cells, '.range-end'), 'to equal', []);
expect(getCellIndices(cells, '.range'), 'to equal', [10, 11]);
expect(getCellIndices(cells, '.focused'), 'to equal', [9]);
prevBtn0.click();
cells = getCells(picker0);
expect(viewSwitch0.textContent, 'to be', '1800-1890');
expect(getCellIndices(cells, '.selected'), 'to equal', []);
expect(getCellIndices(cells, '.range-start'), 'to equal', []);
expect(getCellIndices(cells, '.range-end'), 'to equal', []);
expect(getCellIndices(cells, '.range'), 'to equal', []);
expect(getCellIndices(cells, '.focused'), 'to equal', [9]);
nextBtn0.click();
nextBtn0.click();
cells = getCells(picker0);
expect(viewSwitch0.textContent, 'to be', '2000-2090');
expect(getCellIndices(cells, '.selected'), 'to equal', []);
expect(getCellIndices(cells, '.range-start'), 'to equal', []);
expect(getCellIndices(cells, '.range-end'), 'to equal', []);
expect(getCellIndices(cells, '.range').length, 'to be', 12);
expect(getCellIndices(cells, '.focused'), 'to equal', [9]);
nextBtn0.click();
cells = getCells(picker0);
expect(viewSwitch0.textContent, 'to be', '2100-2190');
expect(getCellIndices(cells, '.selected'), 'to equal', []);
expect(getCellIndices(cells, '.range-start'), 'to equal', []);
expect(getCellIndices(cells, '.range-end'), 'to equal', [3]);
expect(getCellIndices(cells, '.range'), 'to equal', [0, 1, 2]);
expect(getCellIndices(cells, '.focused'), 'to equal', [9]);
// range-end
input1.focus();
viewSwitch1.click();
viewSwitch1.click();
viewSwitch1.click();
cells = getCells(picker1);
expect(viewSwitch1.textContent, 'to be', '2100-2190');
expect(getCellIndices(cells, '.selected'), 'to equal', [3]);
expect(getCellIndices(cells, '.range-start'), 'to equal', []);
expect(getCellIndices(cells, '.range-end'), 'to equal', [3]);
expect(getCellIndices(cells, '.range'), 'to equal', [0, 1, 2]);
expect(getCellIndices(cells, '.focused'), 'to equal', [3]);
nextBtn1.click();
cells = getCells(picker1);
expect(viewSwitch1.textContent, 'to be', '2200-2290');
expect(getCellIndices(cells, '.selected'), 'to equal', []);
expect(getCellIndices(cells, '.range-start'), 'to equal', []);
expect(getCellIndices(cells, '.range-end'), 'to equal', []);
expect(getCellIndices(cells, '.range'), 'to equal', []);
expect(getCellIndices(cells, '.focused'), 'to equal', [3]);
prevBtn1.click();
prevBtn1.click();
cells = getCells(picker1);
expect(viewSwitch1.textContent, 'to be', '2000-2090');
expect(getCellIndices(cells, '.selected'), 'to equal', []);
expect(getCellIndices(cells, '.range-start'), 'to equal', []);
expect(getCellIndices(cells, '.range-end'), 'to equal', []);
expect(getCellIndices(cells, '.range').length, 'to be', 12);
expect(getCellIndices(cells, '.focused'), 'to equal', [3]);
prevBtn1.click();
cells = getCells(picker1);
expect(viewSwitch1.textContent, 'to be', '1900-1990');
expect(getCellIndices(cells, '.selected'), 'to equal', []);
expect(getCellIndices(cells, '.range-start'), 'to equal', [9]);
expect(getCellIndices(cells, '.range-end'), 'to equal', []);
expect(getCellIndices(cells, '.range'), 'to equal', [10, 11]);
expect(getCellIndices(cells, '.focused'), 'to equal', [3]);
drp.destroy();
});
});

View File

@ -0,0 +1,415 @@
describe('DateRangePicker - API methods', function () {
let clock;
let elem;
let input0;
let input1;
before(function () {
clock = sinon.useFakeTimers({now: new Date(2020, 1, 14)});
});
after(function () {
clock.restore();
});
beforeEach(function () {
elem = domUtils.parseHTML('<div><input><input></div>').firstChild;
[input0, input1] = elem.children;
testContainer.appendChild(elem);
});
afterEach(function () {
testContainer.removeChild(elem);
});
describe('getDates()', function () {
it('returns an array of the Date objects of selected dates', function () {
input0.value = '04/20/2020';
input1.value = '04/22/2020';
const drp = new DateRangePicker(elem);
expect(drp.getDates(), 'to equal', [
new Date(dateValue(2020, 3, 20)),
new Date(dateValue(2020, 3, 22)),
]);
drp.destroy();
input0.value = '';
input1.value = '';
});
it('returns a formatted date stirngs of selected dates if the format is specified', function () {
input0.value = '04/20/2020';
input1.value = '04/22/2020';
const drp = new DateRangePicker(elem);
expect(drp.getDates('yyyy-mm-dd'), 'to equal', ['2020-04-20', '2020-04-22']);
expect(drp.getDates('d M, yy'), 'to equal', ['20 Apr, 20', '22 Apr, 20']);
drp.destroy();
input0.value = '';
input1.value = '';
});
it('uses undefined instead of Date object if date is not selected', function () {
const drp = new DateRangePicker(elem);
expect(drp.getDates(), 'to equal', [undefined, undefined]);
expect(drp.getDates('yyyy-mm-dd'), 'to equal', [undefined, undefined]);
drp.destroy();
});
});
describe('setDates()', function () {
let drp;
let picker0;
let picker1;
let viewSwitch0;
let viewSwitch1;
let cells0;
let cells1;
it('changes the selected dates to given dates', function () {
({drp, picker0, picker1} = createDRP(elem));
viewSwitch0 = picker0.querySelector('.view-switch');
viewSwitch1 = picker1.querySelector('.view-switch');
cells0 = getCells(picker0);
cells1 = getCells(picker1);
drp.setDates('2/11/2020', '2/14/2020');
expect(drp.datepickers[0].dates, 'to equal', [dateValue(2020, 1, 11)]);
expect(input0.value, 'to be', '02/11/2020');
expect(viewSwitch0.textContent, 'to be', 'February 2020');
expect(getCellIndices(cells0, '.selected'), 'to equal', [16]);
expect(getCellIndices(cells0, '.range-start'), 'to equal', [16]);
expect(getCellIndices(cells0, '.range-end'), 'to equal', [19]);
expect(getCellIndices(cells0, '.range'), 'to equal', [17, 18]);
expect(getCellIndices(cells0, '.focused'), 'to equal', [16]);
expect(drp.datepickers[1].dates, 'to equal', [dateValue(2020, 1, 14)]);
expect(input1.value, 'to be', '02/14/2020');
expect(viewSwitch1.textContent, 'to be', 'February 2020');
expect(getCellIndices(cells1, '.selected'), 'to equal', [19]);
expect(getCellIndices(cells1, '.range-start'), 'to equal', [16]);
expect(getCellIndices(cells1, '.range-end'), 'to equal', [19]);
expect(getCellIndices(cells1, '.range'), 'to equal', [17, 18]);
expect(getCellIndices(cells1, '.focused'), 'to equal', [19]);
drp.setDates(new Date(2020, 4, 31), new Date(2020, 6, 5).getTime());
expect(drp.datepickers[0].dates, 'to equal', [dateValue(2020, 4, 31)]);
expect(input0.value, 'to be', '05/31/2020');
expect(viewSwitch0.textContent, 'to be', 'May 2020');
expect(getCellIndices(cells0, '.selected'), 'to equal', [35]);
expect(getCellIndices(cells0, '.range-start'), 'to equal', [35]);
expect(getCellIndices(cells0, '.range-end'), 'to equal', []);
expect(getCellIndices(cells0, '.range'), 'to equal', [36, 37, 38, 39, 40, 41]);
expect(getCellIndices(cells0, '.focused'), 'to equal', [35]);
expect(drp.datepickers[1].dates, 'to equal', [dateValue(2020, 6, 5)]);
expect(input1.value, 'to be', '07/05/2020');
expect(viewSwitch1.textContent, 'to be', 'July 2020');
expect(getCellIndices(cells1, '.selected'), 'to equal', [7]);
expect(getCellIndices(cells1, '.range-start'), 'to equal', []);
expect(getCellIndices(cells1, '.range-end'), 'to equal', [7]);
expect(getCellIndices(cells1, '.range'), 'to equal', [0, 1, 2, 3, 4, 5, 6]);
expect(getCellIndices(cells1, '.focused'), 'to equal', [7]);
drp.destroy();
input0.value = '';
input1.value = '';
});
it('swapps star↔end dates if given start date > end date', function () {
({drp, picker0, picker1} = createDRP(elem));
viewSwitch0 = picker0.querySelector('.view-switch');
viewSwitch1 = picker1.querySelector('.view-switch');
cells0 = getCells(picker0);
cells1 = getCells(picker1);
drp.setDates(new Date(2020, 6, 5).getTime(), new Date(2020, 4, 31));
expect(drp.datepickers[0].dates, 'to equal', [dateValue(2020, 4, 31)]);
expect(input0.value, 'to be', '05/31/2020');
expect(viewSwitch0.textContent, 'to be', 'May 2020');
expect(getCellIndices(cells0, '.selected'), 'to equal', [35]);
expect(drp.datepickers[1].dates, 'to equal', [dateValue(2020, 6, 5)]);
expect(input1.value, 'to be', '07/05/2020');
expect(viewSwitch1.textContent, 'to be', 'July 2020');
expect(getCellIndices(cells1, '.selected'), 'to equal', [7]);
drp.destroy();
input0.value = '';
input1.value = '';
});
it('ignores invalid dates and the same date as the current one and leaves that side untouched', function () {
input0.value = '02/11/2020';
input1.value = '02/14/2020';
({drp, picker0, picker1} = createDRP(elem));
viewSwitch0 = picker0.querySelector('.view-switch');
viewSwitch1 = picker1.querySelector('.view-switch');
cells0 = getCells(picker0);
cells1 = getCells(picker1);
drp.setDates('', '3/14/2020');
expect(drp.datepickers[0].dates, 'to equal', [dateValue(2020, 1, 11)]);
expect(input0.value, 'to be', '02/11/2020');
expect(viewSwitch0.textContent, 'to be', 'February 2020');
expect(getCellIndices(cells0, '.selected'), 'to equal', [16]);
expect(drp.datepickers[1].dates, 'to equal', [dateValue(2020, 2, 14)]);
expect(input1.value, 'to be', '03/14/2020');
expect(viewSwitch1.textContent, 'to be', 'March 2020');
expect(getCellIndices(cells1, '.selected'), 'to equal', [13]);
let date0Str;
let date0YM;
let date0Indices;
if (new Date(0).getDate() === 1) {
date0Str = '01/01/1970';
date0YM = 'January 1970';
date0Indices = [4];
} else {
date0Str = '12/31/1969';
date0YM = 'December 1969';
date0Indices = [31];
}
drp.setDates(0, new Date(-1, 11, 31));
expect(drp.datepickers[0].dates, 'to equal', [dateValue(0)]);
expect(input0.value, 'to be', date0Str);
expect(viewSwitch0.textContent, 'to be', date0YM);
expect(getCellIndices(cells0, '.selected'), 'to equal', date0Indices);
expect(drp.datepickers[1].dates, 'to equal', [dateValue(2020, 2, 14)]);
expect(input1.value, 'to be', '03/14/2020');
expect(viewSwitch1.textContent, 'to be', 'March 2020');
expect(getCellIndices(cells1, '.selected'), 'to equal', [13]);
input1.value = 'foo';
drp.setDates('2/11/2020', '3/14/2020');
expect(drp.datepickers[0].dates, 'to equal', [dateValue(2020, 1, 11)]);
expect(input0.value, 'to be', '02/11/2020');
expect(viewSwitch0.textContent, 'to be', 'February 2020');
expect(getCellIndices(cells0, '.selected'), 'to equal', [16]);
expect(drp.datepickers[1].dates, 'to equal', [dateValue(2020, 2, 14)]);
expect(input1.value, 'to be', '03/14/2020');
expect(viewSwitch1.textContent, 'to be', 'March 2020');
expect(getCellIndices(cells1, '.selected'), 'to equal', [13]);
input0.value = 'foo';
drp.setDates('2/11/2020', '2/14/2020');
expect(drp.datepickers[0].dates, 'to equal', [dateValue(2020, 1, 11)]);
expect(input0.value, 'to be', '02/11/2020');
expect(viewSwitch0.textContent, 'to be', 'February 2020');
expect(getCellIndices(cells0, '.selected'), 'to equal', [16]);
expect(drp.datepickers[1].dates, 'to equal', [dateValue(2020, 1, 14)]);
expect(input1.value, 'to be', '02/14/2020');
expect(viewSwitch1.textContent, 'to be', 'February 2020');
expect(getCellIndices(cells1, '.selected'), 'to equal', [19]);
drp.destroy();
input0.value = '';
input1.value = '';
});
it('sets the same date to both sides if called with one side only when range is not selected', function () {
({drp, picker0, picker1} = createDRP(elem));
viewSwitch0 = picker0.querySelector('.view-switch');
viewSwitch1 = picker1.querySelector('.view-switch');
cells0 = getCells(picker0);
cells1 = getCells(picker1);
drp.setDates('2/11/2020');
expect(drp.datepickers[0].dates, 'to equal', [dateValue(2020, 1, 11)]);
expect(input0.value, 'to be', '02/11/2020');
expect(viewSwitch0.textContent, 'to be', 'February 2020');
expect(getCellIndices(cells0, '.selected'), 'to equal', [16]);
expect(drp.datepickers[1].dates, 'to equal', [dateValue(2020, 1, 11)]);
expect(input1.value, 'to be', '02/11/2020');
expect(viewSwitch1.textContent, 'to be', 'February 2020');
expect(getCellIndices(cells1, '.selected'), 'to equal', [16]);
drp.destroy();
input0.value = '';
input1.value = '';
({drp, picker0, picker1} = createDRP(elem));
viewSwitch0 = picker0.querySelector('.view-switch');
viewSwitch1 = picker1.querySelector('.view-switch');
cells0 = getCells(picker0);
cells1 = getCells(picker1);
drp.setDates(undefined, '3/14/2020');
expect(drp.datepickers[0].dates, 'to equal', [dateValue(2020, 2, 14)]);
expect(input0.value, 'to be', '03/14/2020');
expect(viewSwitch0.textContent, 'to be', 'March 2020');
expect(getCellIndices(cells0, '.selected'), 'to equal', [13]);
expect(drp.datepickers[1].dates, 'to equal', [dateValue(2020, 2, 14)]);
expect(input1.value, 'to be', '03/14/2020');
expect(viewSwitch1.textContent, 'to be', 'March 2020');
expect(getCellIndices(cells1, '.selected'), 'to equal', [13]);
drp.destroy();
input0.value = '';
input1.value = '';
});
it('clears both sides if {clear: true} is passed as the last effective argument instrad of a date', function () {
input0.value = '02/11/2020';
input1.value = '02/14/2020';
({drp, picker0, picker1} = createDRP(elem));
viewSwitch0 = picker0.querySelector('.view-switch');
viewSwitch1 = picker1.querySelector('.view-switch');
cells0 = getCells(picker0);
cells1 = getCells(picker1);
// start: clear + end: ineffective (unspecified)
drp.setDates({clear: true});
expect(drp.datepickers[0].dates, 'to equal', []);
expect(input0.value, 'to be', '');
expect(viewSwitch0.textContent, 'to be', 'February 2020');
expect(getCellIndices(cells0, '.selected'), 'to equal', []);
expect(drp.datepickers[1].dates, 'to equal', []);
expect(input1.value, 'to be', '');
expect(viewSwitch1.textContent, 'to be', 'February 2020');
expect(getCellIndices(cells1, '.selected'), 'to equal', []);
drp.destroy();
input0.value = '02/11/2020';
input1.value = '02/14/2020';
({drp, picker0, picker1} = createDRP(elem));
viewSwitch0 = picker0.querySelector('.view-switch');
viewSwitch1 = picker1.querySelector('.view-switch');
cells0 = getCells(picker0);
cells1 = getCells(picker1);
// start: clear + end: ineffective (same date)
drp.setDates({clear: true}, '2/14/2020');
expect(drp.datepickers[0].dates, 'to equal', []);
expect(input0.value, 'to be', '');
expect(viewSwitch0.textContent, 'to be', 'February 2020');
expect(getCellIndices(cells0, '.selected'), 'to equal', []);
expect(drp.datepickers[1].dates, 'to equal', []);
expect(input1.value, 'to be', '');
expect(viewSwitch1.textContent, 'to be', 'February 2020');
expect(getCellIndices(cells1, '.selected'), 'to equal', []);
drp.destroy();
input0.value = '02/11/2020';
input1.value = '02/14/2020';
({drp, picker0, picker1} = createDRP(elem));
viewSwitch0 = picker0.querySelector('.view-switch');
viewSwitch1 = picker1.querySelector('.view-switch');
cells0 = getCells(picker0);
cells1 = getCells(picker1);
// start: valid date + end: clear
drp.setDates('4/20/2020', {clear: true});
expect(drp.datepickers[0].dates, 'to equal', []);
expect(input0.value, 'to be', '');
expect(viewSwitch0.textContent, 'to be', 'February 2020');
expect(getCellIndices(cells0, '.selected'), 'to equal', []);
expect(drp.datepickers[1].dates, 'to equal', []);
expect(input1.value, 'to be', '');
expect(viewSwitch1.textContent, 'to be', 'February 2020');
expect(getCellIndices(cells1, '.selected'), 'to equal', []);
drp.destroy();
input0.value = '02/11/2020';
input1.value = '02/14/2020';
({drp, picker0, picker1} = createDRP(elem));
viewSwitch0 = picker0.querySelector('.view-switch');
viewSwitch1 = picker1.querySelector('.view-switch');
cells0 = getCells(picker0);
cells1 = getCells(picker1);
// start: ineffective (same date) + end: clear
drp.setDates('2/11/2020', {clear: true});
expect(drp.datepickers[0].dates, 'to equal', []);
expect(input0.value, 'to be', '');
expect(viewSwitch0.textContent, 'to be', 'February 2020');
expect(getCellIndices(cells0, '.selected'), 'to equal', []);
expect(drp.datepickers[1].dates, 'to equal', []);
expect(input1.value, 'to be', '');
expect(viewSwitch1.textContent, 'to be', 'February 2020');
expect(getCellIndices(cells1, '.selected'), 'to equal', []);
drp.destroy();
});
it('sets the end date to both sides if {clear: true} is passed to start and an eefective date to end', function () {
input0.value = '02/11/2020';
input1.value = '02/11/2020';
({drp, picker0, picker1} = createDRP(elem));
viewSwitch0 = picker0.querySelector('.view-switch');
viewSwitch1 = picker1.querySelector('.view-switch');
cells0 = getCells(picker0);
cells1 = getCells(picker1);
drp.setDates({clear: true}, '2/14/2020');
expect(drp.datepickers[0].dates, 'to equal', [dateValue(2020, 1, 14)]);
expect(input0.value, 'to be', '02/14/2020');
expect(viewSwitch0.textContent, 'to be', 'February 2020');
expect(getCellIndices(cells0, '.selected'), 'to equal', [19]);
expect(drp.datepickers[1].dates, 'to equal', [dateValue(2020, 1, 14)]);
expect(input1.value, 'to be', '02/14/2020');
expect(viewSwitch1.textContent, 'to be', 'February 2020');
expect(getCellIndices(cells1, '.selected'), 'to equal', [19]);
drp.destroy();
input0.value = '';
input1.value = '';
({drp, picker0, picker1} = createDRP(elem));
viewSwitch0 = picker0.querySelector('.view-switch');
viewSwitch1 = picker1.querySelector('.view-switch');
cells0 = getCells(picker0);
cells1 = getCells(picker1);
drp.setDates({clear: true}, '3/14/2020');
expect(drp.datepickers[0].dates, 'to equal', [dateValue(2020, 2, 14)]);
expect(input0.value, 'to be', '03/14/2020');
expect(viewSwitch0.textContent, 'to be', 'March 2020');
expect(getCellIndices(cells0, '.selected'), 'to equal', [13]);
expect(drp.datepickers[1].dates, 'to equal', [dateValue(2020, 2, 14)]);
expect(input1.value, 'to be', '03/14/2020');
expect(viewSwitch1.textContent, 'to be', 'March 2020');
expect(getCellIndices(cells1, '.selected'), 'to equal', [13]);
drp.destroy();
input0.value = '';
input1.value = '';
});
});
});

View File

@ -0,0 +1,472 @@
describe('DateRangePicker - date selection', function () {
let clock;
let elem;
let input0;
let input1;
//
let drp;
let picker0;
let picker1;
let viewSwitch0;
let viewSwitch1;
let nextBtn0;
let nextBtn1;
let cells0;
let cells1;
before(function () {
clock = sinon.useFakeTimers({now: new Date(2020, 1, 14)});
});
after(function () {
clock.restore();
});
beforeEach(function () {
elem = domUtils.parseHTML('<div><input><input></div>').firstChild;
[input0, input1] = elem.children;
testContainer.appendChild(elem);
});
afterEach(function () {
testContainer.removeChild(elem);
});
it('same date is set to both sides if a date is selected on one side when selections are none', function () {
let selectDate = dateValue(2020, 1, 11);
({drp, picker0, picker1} = createDRP(elem));
cells0 = getCells(picker0);
cells1 = getCells(picker1);
drp.datepickers[0].show();
cells0[16].click();
expect(drp.dates, 'to equal', [selectDate, selectDate]);
expect(input0.value, 'to be', '02/11/2020');
expect(filterCells(cells0, '.selected'), 'to equal', [cells0[16]]);
expect(filterCells(cells0, '.range-start'), 'to equal', [cells0[16]]);
expect(filterCells(cells0, '.range-end'), 'to equal', [cells0[16]]);
expect(filterCells(cells0, '.range'), 'to equal', []);
expect(filterCells(cells0, '.focused'), 'to equal', [cells0[16]]);
expect(input1.value, 'to be', '02/11/2020');
expect(filterCells(cells1, '.selected'), 'to equal', [cells1[16]]);
expect(filterCells(cells1, '.range-start'), 'to equal', [cells1[16]]);
expect(filterCells(cells1, '.range-end'), 'to equal', [cells1[16]]);
expect(filterCells(cells1, '.range'), 'to equal', []);
expect(filterCells(cells1, '.focused'), 'to equal', [cells1[16]]);
drp.destroy();
input0.value = '';
input1.value = '';
({drp, picker0, picker1} = createDRP(elem));
cells0 = getCells(picker0);
cells1 = getCells(picker1);
drp.datepickers[1].show();
cells1[16].click();
expect(drp.dates, 'to equal', [selectDate, selectDate]);
expect(input0.value, 'to be', '02/11/2020');
expect(filterCells(cells0, '.selected'), 'to equal', [cells0[16]]);
expect(filterCells(cells0, '.range-start'), 'to equal', [cells0[16]]);
expect(filterCells(cells0, '.range-end'), 'to equal', [cells0[16]]);
expect(filterCells(cells0, '.range'), 'to equal', []);
expect(filterCells(cells0, '.focused'), 'to equal', [cells0[16]]);
expect(input1.value, 'to be', '02/11/2020');
expect(filterCells(cells1, '.selected'), 'to equal', [cells1[16]]);
expect(filterCells(cells1, '.range-start'), 'to equal', [cells1[16]]);
expect(filterCells(cells1, '.range-end'), 'to equal', [cells1[16]]);
expect(filterCells(cells1, '.range'), 'to equal', []);
expect(filterCells(cells1, '.focused'), 'to equal', [cells1[16]]);
drp.destroy();
input0.value = '';
input1.value = '';
// other month than default view date's
// (issue #17, #19)
let partsClasses = ['.view-switch', '.next-btn'];
selectDate = dateValue(2020, 2, 10);
({drp, picker0, picker1} = createDRP(elem));
[viewSwitch0, nextBtn0] = getParts(picker0, partsClasses);
[viewSwitch1, nextBtn1] = getParts(picker1, partsClasses);
drp.datepickers[0].show();
nextBtn0.click();
getCells(picker0)[9].click();
cells0 = getCells(picker0);
cells1 = getCells(picker1);
expect(drp.dates, 'to equal', [selectDate, selectDate]);
expect(input0.value, 'to be', '03/10/2020');
expect(viewSwitch0.textContent, 'to equal', 'March 2020');
expect(filterCells(cells0, '.selected'), 'to equal', [cells0[9]]);
expect(filterCells(cells0, '.range-start'), 'to equal', [cells0[9]]);
expect(filterCells(cells0, '.range-end'), 'to equal', [cells0[9]]);
expect(filterCells(cells0, '.range'), 'to equal', []);
expect(filterCells(cells0, '.focused'), 'to equal', [cells0[9]]);
expect(input1.value, 'to be', '03/10/2020');
expect(viewSwitch1.textContent, 'to equal', 'March 2020');
expect(filterCells(cells1, '.selected'), 'to equal', [cells1[9]]);
expect(filterCells(cells1, '.range-start'), 'to equal', [cells1[9]]);
expect(filterCells(cells1, '.range-end'), 'to equal', [cells1[9]]);
expect(filterCells(cells1, '.range'), 'to equal', []);
expect(filterCells(cells1, '.focused'), 'to equal', [cells1[9]]);
drp.datepickers[1].show();
nextBtn1.click();
expect(viewSwitch1.textContent, 'to equal', 'April 2020');
drp.destroy();
input0.value = '';
input1.value = '';
({drp, picker0, picker1} = createDRP(elem));
[viewSwitch0, nextBtn0] = getParts(picker0, partsClasses);
[viewSwitch1, nextBtn1] = getParts(picker1, partsClasses);
drp.datepickers[1].show();
nextBtn1.click();
getCells(picker1)[9].click();
cells0 = getCells(picker0);
cells1 = getCells(picker1);
expect(drp.dates, 'to equal', [selectDate, selectDate]);
expect(input0.value, 'to be', '03/10/2020');
expect(viewSwitch0.textContent, 'to equal', 'March 2020');
expect(filterCells(cells0, '.selected'), 'to equal', [cells0[9]]);
expect(filterCells(cells0, '.range-start'), 'to equal', [cells0[9]]);
expect(filterCells(cells0, '.range-end'), 'to equal', [cells0[9]]);
expect(filterCells(cells0, '.range'), 'to equal', []);
expect(filterCells(cells0, '.focused'), 'to equal', [cells0[9]]);
expect(input1.value, 'to be', '03/10/2020');
expect(viewSwitch1.textContent, 'to equal', 'March 2020');
expect(filterCells(cells1, '.selected'), 'to equal', [cells1[9]]);
expect(filterCells(cells1, '.range-start'), 'to equal', [cells1[9]]);
expect(filterCells(cells1, '.range-end'), 'to equal', [cells1[9]]);
expect(filterCells(cells1, '.range'), 'to equal', []);
expect(filterCells(cells1, '.focused'), 'to equal', [cells1[9]]);
drp.datepickers[0].show();
nextBtn0.click();
expect(viewSwitch0.textContent, 'to equal', 'April 2020');
drp.destroy();
input0.value = '';
input1.value = '';
});
it('selections are cleared from both sides if selected date on one side is cleared', function () {
input0.value = '02/11/2020';
input1.value = '02/11/2020';
({drp, picker0, picker1} = createDRP(elem));
cells0 = getCells(picker0);
cells1 = getCells(picker1);
input0.value = '';
simulant.fire(input0, 'keydown', {key: 'Enter'});
expect(drp.dates, 'to equal', [undefined, undefined]);
expect(input0.value, 'to be', '');
expect(filterCells(cells0, '.selected'), 'to equal', []);
expect(filterCells(cells0, '.range-start'), 'to equal', []);
expect(filterCells(cells0, '.range-end'), 'to equal', []);
expect(filterCells(cells0, '.range'), 'to equal', []);
expect(filterCells(cells0, '.focused'), 'to equal', [cells0[19]]);
expect(input1.value, 'to be', '');
expect(filterCells(cells1, '.selected'), 'to equal', []);
expect(filterCells(cells1, '.range-start'), 'to equal', []);
expect(filterCells(cells1, '.range-end'), 'to equal', []);
expect(filterCells(cells1, '.range'), 'to equal', []);
expect(filterCells(cells1, '.focused'), 'to equal', [cells1[19]]);
drp.destroy();
input0.value = '02/11/2020';
input1.value = '02/11/2020';
({drp, picker0, picker1} = createDRP(elem));
cells0 = getCells(picker0);
cells1 = getCells(picker1);
input1.value = '';
simulant.fire(input1, 'keydown', {key: 'Enter'});
expect(drp.dates, 'to equal', [undefined, undefined]);
expect(input0.value, 'to be', '');
expect(filterCells(cells0, '.selected'), 'to equal', []);
expect(filterCells(cells0, '.range-start'), 'to equal', []);
expect(filterCells(cells0, '.range-end'), 'to equal', []);
expect(filterCells(cells0, '.range'), 'to equal', []);
expect(filterCells(cells0, '.focused'), 'to equal', [cells0[19]]);
expect(input1.value, 'to be', '');
expect(filterCells(cells1, '.selected'), 'to equal', []);
expect(filterCells(cells1, '.range-start'), 'to equal', []);
expect(filterCells(cells1, '.range-end'), 'to equal', []);
expect(filterCells(cells1, '.range'), 'to equal', []);
expect(filterCells(cells1, '.focused'), 'to equal', [cells1[19]]);
drp.destroy();
});
it('dates are swapped if a date later than the 2nd picker\'s selection is seleted on the 1st picker', function () {
input0.value = '02/11/2020';
input1.value = '02/11/2020';
({drp, picker0, picker1} = createDRP(elem));
cells0 = getCells(picker0);
cells1 = getCells(picker1);
drp.datepickers[0].show();
cells0[20].click();
expect(drp.dates, 'to equal', [dateValue(2020, 1, 11), dateValue(2020, 1, 15)]);
expect(input0.value, 'to be', '02/11/2020');
expect(filterCells(cells0, '.selected'), 'to equal', [cells0[16]]);
expect(filterCells(cells0, '.range-start'), 'to equal', [cells0[16]]);
expect(filterCells(cells0, '.range-end'), 'to equal', [cells0[20]]);
expect(filterCells(cells0, '.range'), 'to equal', [cells0[17], cells0[18], cells0[19]]);
expect(filterCells(cells0, '.focused'), 'to equal', [cells0[16]]);
expect(input1.value, 'to be', '02/15/2020');
expect(filterCells(cells1, '.selected'), 'to equal', [cells1[20]]);
expect(filterCells(cells1, '.range-start'), 'to equal', [cells1[16]]);
expect(filterCells(cells1, '.range-end'), 'to equal', [cells1[20]]);
expect(filterCells(cells1, '.range'), 'to equal', [cells1[17], cells1[18], cells1[19]]);
expect(filterCells(cells1, '.focused'), 'to equal', [cells1[20]]);
drp.destroy();
input0.value = '';
input1.value = '';
});
it('dates are swapped if a date earlier than the 1st picker\'s selection is seleted on the 2nd picker', function () {
input0.value = '02/11/2020';
input1.value = '02/11/2020';
({drp, picker0, picker1} = createDRP(elem));
cells0 = getCells(picker0);
cells1 = getCells(picker1);
drp.datepickers[1].show();
cells1[12].click();
expect(drp.dates, 'to equal', [dateValue(2020, 1, 7), dateValue(2020, 1, 11)]);
expect(input0.value, 'to be', '02/07/2020');
expect(filterCells(cells0, '.selected'), 'to equal', [cells0[12]]);
expect(filterCells(cells0, '.range-start'), 'to equal', [cells0[12]]);
expect(filterCells(cells0, '.range-end'), 'to equal', [cells0[16]]);
expect(filterCells(cells0, '.range'), 'to equal', [cells0[13], cells0[14], cells0[15]]);
expect(filterCells(cells0, '.focused'), 'to equal', [cells0[12]]);
expect(input1.value, 'to be', '02/11/2020');
expect(filterCells(cells1, '.selected'), 'to equal', [cells1[16]]);
expect(filterCells(cells1, '.range-start'), 'to equal', [cells1[12]]);
expect(filterCells(cells1, '.range-end'), 'to equal', [cells1[16]]);
expect(filterCells(cells1, '.range'), 'to equal', [cells1[13], cells1[14], cells1[15]]);
expect(filterCells(cells1, '.focused'), 'to equal', [cells1[16]]);
drp.destroy();
input0.value = '';
input1.value = '';
});
describe('range between different months', function () {
it('each picker displays the month of corresponding end of the range', function () {
input0.value = '02/25/2020';
input1.value = '03/05/2020';
({drp, picker0, picker1} = createDRP(elem));
viewSwitch0 = picker0.querySelector('.view-switch');
viewSwitch1 = picker1.querySelector('.view-switch');
cells0 = getCells(picker0);
cells1 = getCells(picker1);
expect(viewSwitch0.textContent, 'to be', 'February 2020');
expect(filterCells(cells0, '.selected'), 'to equal', [cells0[30]]);
expect(filterCells(cells0, '.range-start'), 'to equal', [cells0[30]]);
expect(filterCells(cells0, '.range-end'), 'to equal', [cells0[39]]);
expect(filterCells(cells0, '.range'), 'to equal', cells0.slice(31, 39));
expect(viewSwitch1.textContent, 'to be', 'March 2020');
expect(filterCells(cells1, '.selected'), 'to equal', [cells1[4]]);
expect(filterCells(cells1, '.range-start'), 'to equal', []);
expect(filterCells(cells1, '.range-end'), 'to equal', [cells1[4]]);
expect(filterCells(cells1, '.range'), 'to equal', cells1.slice(0, 4));
drp.datepickers[1].show();
picker1.querySelector('.next-btn').click();
cells1 = getCells(picker1);
cells1[24].click();
expect(drp.dates, 'to equal', [dateValue(2020, 1, 25), dateValue(2020, 3, 22)]);
expect(input0.value, 'to be', '02/25/2020');
expect(input1.value, 'to be', '04/22/2020');
expect(viewSwitch0.textContent, 'to be', 'February 2020');
expect(filterCells(cells0, '.selected'), 'to equal', [cells0[30]]);
expect(filterCells(cells0, '.range-start'), 'to equal', [cells0[30]]);
expect(filterCells(cells0, '.range-end'), 'to equal', []);
expect(filterCells(cells0, '.range'), 'to equal', cells0.slice(31));
expect(viewSwitch1.textContent, 'to be', 'April 2020');
expect(filterCells(cells1, '.selected'), 'to equal', [cells1[24]]);
expect(filterCells(cells1, '.range-start'), 'to equal', []);
expect(filterCells(cells1, '.range-end'), 'to equal', [cells1[24]]);
expect(filterCells(cells1, '.range'), 'to equal', cells1.slice(0, 24));
input0.value = '02/14/1998';
simulant.fire(input0, 'keydown', {key: 'Enter'});
cells0 = getCells(picker0);
expect(drp.dates, 'to equal', [dateValue(1998, 1, 14), dateValue(2020, 3, 22)]);
expect(input0.value, 'to be', '02/14/1998');
expect(input1.value, 'to be', '04/22/2020');
expect(viewSwitch0.textContent, 'to be', 'February 1998');
expect(filterCells(cells0, '.selected'), 'to equal', [cells0[13]]);
expect(filterCells(cells0, '.range-start'), 'to equal', [cells0[13]]);
expect(filterCells(cells0, '.range-end'), 'to equal', []);
expect(filterCells(cells0, '.range'), 'to equal', cells0.slice(14));
expect(viewSwitch1.textContent, 'to be', 'April 2020');
expect(filterCells(cells1, '.selected'), 'to equal', [cells1[24]]);
expect(filterCells(cells1, '.range-start'), 'to equal', []);
expect(filterCells(cells1, '.range-end'), 'to equal', [cells1[24]]);
expect(filterCells(cells1, '.range'), 'to equal', cells1.slice(0, 24));
drp.datepickers[0].show();
// months view
viewSwitch0.click();
cells0 = getCells(picker0);
expect(viewSwitch0.textContent, 'to be', '1998');
expect(filterCells(cells0, '.selected'), 'to equal', [cells0[1]]);
viewSwitch1.click();
cells1 = getCells(picker1);
expect(viewSwitch1.textContent, 'to be', '2020');
expect(filterCells(cells1, '.selected'), 'to equal', [cells1[3]]);
// years view
viewSwitch0.click();
cells0 = getCells(picker0);
expect(viewSwitch0.textContent, 'to be', '1990-1999');
expect(filterCells(cells0, '.selected'), 'to equal', [cells0[9]]);
viewSwitch1.click();
cells1 = getCells(picker1);
expect(viewSwitch1.textContent, 'to be', '2020-2029');
expect(filterCells(cells1, '.selected'), 'to equal', [cells1[1]]);
// decades view
viewSwitch0.click();
cells0 = getCells(picker0);
expect(viewSwitch0.textContent, 'to be', '1900-1990');
expect(filterCells(cells0, '.selected'), 'to equal', [cells0[10]]);
viewSwitch1.click();
cells1 = getCells(picker1);
expect(viewSwitch1.textContent, 'to be', '2000-2090');
expect(filterCells(cells1, '.selected'), 'to equal', [cells1[3]]);
drp.destroy();
input0.value = '';
input1.value = '';
});
it('dates are swapped if a date later than the 2nd picker\'s selection is seleted on the 1st picker', function () {
({drp, picker0, picker1} = createDRP(elem));
[viewSwitch0, nextBtn0] = getParts(picker0, ['.view-switch', '.next-btn']);
viewSwitch1 = picker1.querySelector('.view-switch');
drp.datepickers[1].show();
getCells(picker1)[16].click();
drp.datepickers[1].hide();
drp.datepickers[0].show();
expect(viewSwitch0.textContent, 'to equal', 'February 2020');
nextBtn0.click();
expect(viewSwitch0.textContent, 'to equal', 'March 2020');
getCells(picker0)[9].click();
cells0 = getCells(picker0);
cells1 = getCells(picker1);
expect(drp.dates, 'to equal', [dateValue(2020, 1, 11), dateValue(2020, 2, 10)]);
expect(input0.value, 'to be', '02/11/2020');
expect(viewSwitch0.textContent, 'to equal', 'February 2020');
expect(filterCells(cells0, '.selected'), 'to equal', [cells0[16]]);
expect(filterCells(cells0, '.range-start'), 'to equal', [cells0[16]]);
expect(filterCells(cells0, '.range-end'), 'to equal', []);
expect(filterCells(cells0, '.range'), 'to equal', cells0.slice(17));
expect(filterCells(cells0, '.focused'), 'to equal', [cells0[16]]);
expect(input1.value, 'to be', '03/10/2020');
expect(viewSwitch1.textContent, 'to equal', 'March 2020');
expect(filterCells(cells1, '.selected'), 'to equal', [cells1[9]]);
expect(filterCells(cells1, '.range-start'), 'to equal', []);
expect(filterCells(cells1, '.range-end'), 'to equal', [cells1[9]]);
expect(filterCells(cells1, '.range'), 'to equal', cells1.slice(0, 9));
expect(filterCells(cells1, '.focused'), 'to equal', [cells1[9]]);
drp.destroy();
input0.value = '';
input1.value = '';
});
it('dates are swapped if a date earlier than the 1st picker\'s selection is seleted on the 2nd picker', function () {
let prevBtn1;
({drp, picker0, picker1} = createDRP(elem));
[viewSwitch0, nextBtn0] = getParts(picker0, ['.view-switch', '.next-btn']);
[viewSwitch1, prevBtn1] = getParts(picker1, ['.view-switch', '.prev-btn']);
drp.datepickers[0].show();
nextBtn0.click();
getCells(picker0)[9].click();
drp.datepickers[0].hide();
drp.datepickers[1].show();
expect(viewSwitch1.textContent, 'to equal', 'March 2020');
prevBtn1.click();
expect(viewSwitch1.textContent, 'to equal', 'February 2020');
getCells(picker1)[16].click();
cells0 = getCells(picker0);
cells1 = getCells(picker1);
expect(drp.dates, 'to equal', [dateValue(2020, 1, 11), dateValue(2020, 2, 10)]);
expect(input0.value, 'to be', '02/11/2020');
expect(viewSwitch0.textContent, 'to equal', 'February 2020');
expect(filterCells(cells0, '.selected'), 'to equal', [cells0[16]]);
expect(filterCells(cells0, '.range-start'), 'to equal', [cells0[16]]);
expect(filterCells(cells0, '.range-end'), 'to equal', []);
expect(filterCells(cells0, '.range'), 'to equal', cells0.slice(17));
expect(filterCells(cells0, '.focused'), 'to equal', [cells0[16]]);
expect(input1.value, 'to be', '03/10/2020');
expect(viewSwitch1.textContent, 'to equal', 'March 2020');
expect(filterCells(cells1, '.selected'), 'to equal', [cells1[9]]);
expect(filterCells(cells1, '.range-start'), 'to equal', []);
expect(filterCells(cells1, '.range-end'), 'to equal', [cells1[9]]);
expect(filterCells(cells1, '.range'), 'to equal', cells1.slice(0, 9));
expect(filterCells(cells1, '.focused'), 'to equal', [cells1[9]]);
drp.destroy();
input0.value = '';
input1.value = '';
});
});
});

View File

@ -0,0 +1,308 @@
describe('DateRangePicker - options', function () {
let clock;
let elem;
let input0;
let input1;
before(function () {
clock = sinon.useFakeTimers({now: new Date(2020, 1, 14)});
});
after(function () {
clock.restore();
});
beforeEach(function () {
elem = domUtils.parseHTML('<div><input><input></div>').firstChild;
[input0, input1] = elem.children;
testContainer.appendChild(elem);
});
afterEach(function () {
testContainer.removeChild(elem);
});
describe('allowOneSidedRange', function () {
it('disables the requirement for both sides of range to be set/unset', function () {
let {drp, picker0, picker1} = createDRP(elem, {allowOneSidedRange: true});
let cells0 = getCells(picker0);
let cells1 = getCells(picker1);
drp.datepickers[0].show();
cells0[16].click();
expect(drp.dates, 'to equal', [dateValue(2020, 1, 11), undefined]);
expect(drp.getDates(), 'to equal', [new Date(drp.dates[0]), undefined]);
expect(input0.value, 'to be', '02/11/2020');
expect(filterCells(cells0, '.selected'), 'to equal', [cells0[16]]);
expect(filterCells(cells0, '.range-start'), 'to equal', [cells0[16]]);
expect(filterCells(cells0, '.range-end'), 'to equal', []);
expect(filterCells(cells0, '.range'), 'to equal', []);
expect(filterCells(cells0, '.focused'), 'to equal', [cells0[16]]);
expect(input1.value, 'to be', '');
expect(filterCells(cells1, '.selected'), 'to equal', []);
expect(filterCells(cells1, '.range-start'), 'to equal', [cells1[16]]);
expect(filterCells(cells1, '.range-end'), 'to equal', []);
expect(filterCells(cells1, '.range'), 'to equal', []);
expect(filterCells(cells1, '.focused'), 'to equal', [cells1[19]]);
drp.datepickers[1].show();
cells1[25].click();
expect(drp.dates, 'to equal', [dateValue(2020, 1, 11), dateValue(2020, 1, 20)]);
expect(drp.getDates(), 'to equal', drp.dates.map(date => new Date(date)));
expect(input0.value, 'to be', '02/11/2020');
expect(filterCells(cells0, '.selected'), 'to equal', [cells0[16]]);
expect(filterCells(cells0, '.range-start'), 'to equal', [cells0[16]]);
expect(filterCells(cells0, '.range-end'), 'to equal', [cells0[25]]);
expect(filterCells(cells0, '.range'), 'to equal', cells0.slice(17, 25));
expect(filterCells(cells0, '.focused'), 'to equal', [cells0[16]]);
expect(input1.value, 'to be', '02/20/2020');
expect(filterCells(cells1, '.selected'), 'to equal', [cells1[25]]);
expect(filterCells(cells1, '.range-start'), 'to equal', [cells1[16]]);
expect(filterCells(cells1, '.range-end'), 'to equal', [cells1[25]]);
expect(filterCells(cells1, '.range'), 'to equal', cells1.slice(17, 25));
expect(filterCells(cells1, '.focused'), 'to equal', [cells1[25]]);
simulant.fire(input0, 'keydown', {key: 'Escape'});
input0.value = '';
simulant.fire(input0, 'keydown', {key: 'Enter'});
expect(drp.dates, 'to equal', [undefined, dateValue(2020, 1, 20)]);
expect(drp.getDates(), 'to equal', [undefined, new Date(drp.dates[1])]);
expect(input0.value, 'to be', '');
expect(filterCells(cells0, '.selected'), 'to equal', []);
expect(filterCells(cells0, '.range-start'), 'to equal', []);
expect(filterCells(cells0, '.range-end'), 'to equal', [cells0[25]]);
expect(filterCells(cells0, '.range'), 'to equal', []);
expect(filterCells(cells0, '.focused'), 'to equal', [cells0[19]]);
expect(input1.value, 'to be', '02/20/2020');
expect(filterCells(cells1, '.selected'), 'to equal', [cells1[25]]);
expect(filterCells(cells1, '.range-start'), 'to equal', []);
expect(filterCells(cells1, '.range-end'), 'to equal', [cells1[25]]);
expect(filterCells(cells1, '.range'), 'to equal', []);
expect(filterCells(cells1, '.focused'), 'to equal', [cells1[25]]);
drp.destroy();
input0.value = '';
input1.value = '';
// by setDates()
({drp, picker0, picker1} = createDRP(elem, {allowOneSidedRange: true}));
cells0 = getCells(picker0);
cells1 = getCells(picker1);
drp.setDates('02/11/2020');
expect(drp.dates, 'to equal', [dateValue(2020, 1, 11), undefined]);
expect(input0.value, 'to be', '02/11/2020');
expect(filterCells(cells0, '.selected'), 'to equal', [cells0[16]]);
expect(input1.value, 'to be', '');
expect(filterCells(cells1, '.selected'), 'to equal', []);
drp.setDates(undefined, '02/20/2020');
expect(drp.dates, 'to equal', [dateValue(2020, 1, 11), dateValue(2020, 1, 20)]);
expect(input0.value, 'to be', '02/11/2020');
expect(filterCells(cells0, '.selected'), 'to equal', [cells0[16]]);
expect(input1.value, 'to be', '02/20/2020');
expect(filterCells(cells1, '.selected'), 'to equal', [cells1[25]]);
drp.setDates({clear: true});
expect(drp.dates, 'to equal', [undefined, dateValue(2020, 1, 20)]);
expect(input0.value, 'to be', '');
expect(filterCells(cells0, '.selected'), 'to equal', []);
expect(input1.value, 'to be', '02/20/2020');
expect(filterCells(cells1, '.selected'), 'to equal', [cells1[25]]);
drp.setDates('02/11/2020', {clear: true});
expect(drp.dates, 'to equal', [dateValue(2020, 1, 11), undefined]);
expect(input0.value, 'to be', '02/11/2020');
expect(filterCells(cells0, '.selected'), 'to equal', [cells0[16]]);
expect(input1.value, 'to be', '');
expect(filterCells(cells1, '.selected'), 'to equal', []);
drp.setDates({clear: true}, '02/20/2020');
expect(drp.dates, 'to equal', [undefined, dateValue(2020, 1, 20)]);
expect(input0.value, 'to be', '');
expect(filterCells(cells0, '.selected'), 'to equal', []);
expect(input1.value, 'to be', '02/20/2020');
expect(filterCells(cells1, '.selected'), 'to equal', [cells1[25]]);
drp.setDates(undefined, {clear: true});
expect(drp.dates, 'to equal', [undefined, undefined]);
expect(input0.value, 'to be', '');
expect(filterCells(cells0, '.selected'), 'to equal', []);
expect(input1.value, 'to be', '');
expect(filterCells(cells1, '.selected'), 'to equal', []);
drp.destroy();
});
it('can be updated with setOptions()', function () {
const drp = new DateRangePicker(elem);
drp.setOptions({allowOneSidedRange: true});
input0.value = '02/11/2020';
simulant.fire(input0, 'keydown', {key: 'Enter'});
expect(drp.dates, 'to equal', [dateValue(2020, 1, 11), undefined]);
drp.setDates({clear: true}, '02/11/2020');
expect(drp.dates, 'to equal', [undefined, dateValue(2020, 1, 11)]);
drp.setOptions({allowOneSidedRange: false});
input1.value = '02/20/2020';
simulant.fire(input1, 'keydown', {key: 'Enter'});
expect(drp.dates, 'to equal', [dateValue(2020, 1, 20), dateValue(2020, 1, 20)]);
drp.setDates({clear: true});
expect(drp.dates, 'to equal', [undefined, undefined]);
drp.destroy();
});
});
describe('pickLevel', function () {
it('changes the span of range selection to 1st of a month → last day of a month when 1', function () {
input0.value = '2/14/2020';
input1.value = '2/14/2020';
const {drp, picker0, picker1} = createDRP(elem, {pickLevel: 1});
const viewSwitch0 = picker0.querySelector('.view-switch');
const viewSwitch1 = picker1.querySelector('.view-switch');
let cells0 = getCells(picker0);
let cells1 = getCells(picker1);
input0.focus();
expect(drp.dates, 'to equal', [dateValue(2020, 1, 1), dateValue(2020, 1, 29)]);
expect(input0.value, 'to be', '02/01/2020');
expect(viewSwitch0.textContent, 'to be', '2020');
expect(getCellIndices(cells0, '.selected'), 'to equal', [1]);
expect(getCellIndices(cells0, '.range-start'), 'to equal', [1]);
expect(getCellIndices(cells0, '.range-end'), 'to equal', [1]);
expect(getCellIndices(cells0, '.range'), 'to equal', []);
expect(getCellIndices(cells0, '.focused'), 'to equal', [1]);
input1.focus();
expect(input1.value, 'to be', '02/29/2020');
expect(viewSwitch1.textContent, 'to be', '2020');
expect(getCellIndices(cells1, '.selected'), 'to equal', [1]);
expect(getCellIndices(cells1, '.range-start'), 'to equal', [1]);
expect(getCellIndices(cells1, '.range-end'), 'to equal', [1]);
expect(getCellIndices(cells1, '.range'), 'to equal', []);
expect(getCellIndices(cells1, '.focused'), 'to equal', [1]);
// mouse operation
cells0[0].click();
cells1[6].click();
expect(drp.dates, 'to equal', [dateValue(2020, 0, 1), dateValue(2020, 6, 31)]);
expect(input0.value, 'to be', '01/01/2020');
expect(viewSwitch0.textContent, 'to be', '2020');
expect(getCellIndices(cells0, '.selected'), 'to equal', [0]);
expect(getCellIndices(cells0, '.range-start'), 'to equal', [0]);
expect(getCellIndices(cells0, '.range-end'), 'to equal', [6]);
input1.focus();
expect(input1.value, 'to be', '07/31/2020');
expect(viewSwitch1.textContent, 'to be', '2020');
expect(getCellIndices(cells1, '.selected'), 'to equal', [6]);
expect(getCellIndices(cells1, '.range-start'), 'to equal', [0]);
expect(getCellIndices(cells1, '.range-end'), 'to equal', [6]);
// api call
drp.setDates('2/14/2021', '3/14/2020');
expect(drp.dates, 'to equal', [dateValue(2020, 2, 1), dateValue(2021, 1, 28)]);
expect(input0.value, 'to be', '03/01/2020');
expect(viewSwitch0.textContent, 'to be', '2020');
expect(getCellIndices(cells0, '.selected'), 'to equal', [2]);
expect(getCellIndices(cells0, '.range-start'), 'to equal', [2]);
expect(getCellIndices(cells0, '.range-end'), 'to equal', []);
input1.focus();
expect(input1.value, 'to be', '02/28/2021');
expect(viewSwitch1.textContent, 'to be', '2021');
expect(getCellIndices(cells1, '.selected'), 'to equal', [1]);
expect(getCellIndices(cells1, '.range-start'), 'to equal', []);
expect(getCellIndices(cells1, '.range-end'), 'to equal', [1]);
drp.destroy();
});
it('changes the span of range selection to Jan 1st of a month → Dec 31st of a month when 2', function () {
input0.value = '2/14/2020';
input1.value = '2/14/2020';
const {drp, picker0, picker1} = createDRP(elem, {pickLevel: 2});
const viewSwitch0 = picker0.querySelector('.view-switch');
const viewSwitch1 = picker1.querySelector('.view-switch');
let cells0 = getCells(picker0);
let cells1 = getCells(picker1);
input0.focus();
expect(drp.dates, 'to equal', [dateValue(2020, 0, 1), dateValue(2020, 11, 31)]);
expect(input0.value, 'to be', '01/01/2020');
expect(viewSwitch0.textContent, 'to be', '2020-2029');
expect(getCellIndices(cells0, '.selected'), 'to equal', [1]);
expect(getCellIndices(cells0, '.range-start'), 'to equal', [1]);
expect(getCellIndices(cells0, '.range-end'), 'to equal', [1]);
expect(getCellIndices(cells0, '.range'), 'to equal', []);
expect(getCellIndices(cells0, '.focused'), 'to equal', [1]);
input1.focus();
expect(input1.value, 'to be', '12/31/2020');
expect(viewSwitch1.textContent, 'to be', '2020-2029');
expect(getCellIndices(cells1, '.selected'), 'to equal', [1]);
expect(getCellIndices(cells1, '.range-start'), 'to equal', [1]);
expect(getCellIndices(cells1, '.range-end'), 'to equal', [1]);
expect(getCellIndices(cells1, '.range'), 'to equal', []);
expect(getCellIndices(cells1, '.focused'), 'to equal', [1]);
// mouse operation
cells0[0].click();
cells1[3].click();
expect(drp.dates, 'to equal', [dateValue(2019, 0, 1), dateValue(2022, 11, 31)]);
expect(input0.value, 'to be', '01/01/2019');
expect(viewSwitch0.textContent, 'to be', '2010-2019');
expect(getCellIndices(cells0, '.selected'), 'to equal', [10]);
expect(getCellIndices(cells0, '.range-start'), 'to equal', [10]);
expect(getCellIndices(cells0, '.range-end'), 'to equal', []);
input1.focus();
expect(input1.value, 'to be', '12/31/2022');
expect(viewSwitch1.textContent, 'to be', '2020-2029');
expect(getCellIndices(cells1, '.selected'), 'to equal', [3]);
expect(getCellIndices(cells1, '.range-start'), 'to equal', [0]);
expect(getCellIndices(cells1, '.range-end'), 'to equal', [3]);
// api call
drp.setDates('2/14/2025', '3/14/2021');
expect(drp.dates, 'to equal', [dateValue(2021, 0, 1), dateValue(2025, 11, 31)]);
expect(input0.value, 'to be', '01/01/2021');
expect(viewSwitch0.textContent, 'to be', '2020-2029');
expect(getCellIndices(cells0, '.selected'), 'to equal', [2]);
expect(getCellIndices(cells0, '.range-start'), 'to equal', [2]);
expect(getCellIndices(cells0, '.range-end'), 'to equal', [6]);
input1.focus();
expect(input1.value, 'to be', '12/31/2025');
expect(viewSwitch1.textContent, 'to be', '2020-2029');
expect(getCellIndices(cells1, '.selected'), 'to equal', [6]);
expect(getCellIndices(cells1, '.range-start'), 'to equal', [2]);
expect(getCellIndices(cells1, '.range-end'), 'to equal', [6]);
drp.destroy();
});
});
});

View File

@ -0,0 +1,236 @@
describe('Datepicker', function () {
let input;
before(function () {
input = document.createElement('input');
testContainer.appendChild(input);
});
after(function () {
testContainer.removeChild(input);
});
it('input element\'s value is used for the initial date', function () {
input.value = '04/22/2020';
const dp = new Datepicker(input);
expect(dp.dates, 'to equal', [dateValue(2020, 3, 22)]);
dp.destroy();
input.value = '';
});
it('the picker is hidden at start', function () {
const dp = new Datepicker(input);
expect(isVisible(document.querySelector('.datepicker')), 'to be false');
expect(dp.active, 'to be false');
dp.destroy();
});
it('the picker becomes visible when the input element get focused', function () {
const dp = new Datepicker(input);
input.focus();
expect(isVisible(document.querySelector('.datepicker')), 'to be true');
expect(dp.active, 'to be true');
dp.destroy();
});
describe('hide()', function () {
it('makes the picker invisible', function () {
const dp = new Datepicker(input);
input.focus();
dp.hide();
expect(isVisible(document.querySelector('.datepicker')), 'to be false');
expect(dp.active, 'to be false');
dp.destroy();
});
});
describe('show()', function () {
it('makes the picker visible', function () {
const dp = new Datepicker(input);
dp.show();
expect(isVisible(document.querySelector('.datepicker')), 'to be true');
expect(dp.active, 'to be true');
dp.destroy();
});
it('moves the focus onto the input field', function () {
// related to issue #52
const dp = new Datepicker(input);
const spyShow = sinon.spy(dp, 'show');
input.blur();
dp.show();
expect(document.activeElement, 'to be', input);
// the focus listener's calling show() is prevented
expect(spyShow.calledOnce, 'to be true');
spyShow.restore();
dp.destroy();
});
it('adds or removes dir attribute to/from the picker if picker\'s text direction != input\'s', function (done) {
testContainer.dir = 'rtl';
const {dp, picker} = createDP(input);
dp.show();
expect(picker.dir, 'to be', 'rtl');
dp.hide();
testContainer.removeAttribute('dir');
dp.show();
expect(picker.hasAttribute('dir'), 'to be false');
dp.hide();
const htmlElem = document.querySelector('html');
htmlElem.dir = 'rtl';
input.style.direction = 'ltr';
dp.show();
expect(picker.dir, 'to be', 'ltr');
dp.hide();
input.removeAttribute('style');
dp.show();
expect(picker.hasAttribute('dir'), 'to be false');
dp.destroy();
htmlElem.removeAttribute('dir');
htmlElem.style.direction = 'ltr';
const checkDirChange = () => {
if (window.getComputedStyle(htmlElem).direction === 'ltr') {
htmlElem.removeAttribute('style');
done();
} else {
setTimeout(checkDirChange, 10);
}
};
checkDirChange();
});
});
describe('picker', function () {
it('displays current month with current date as focued date if no initial date is provided', function () {
let clock = sinon.useFakeTimers({now: new Date(2020, 1, 14)});
const {dp, picker} = createDP(input);
const days = Array.from(picker.querySelector('.datepicker-grid').children);
dp.show();
expect(getViewSwitch(picker).textContent, 'to be', 'February 2020');
expect(days, 'to have length', 42);
expect(filterCells(days, '.datepicker-cell'), 'to have length', 42);
expect(days[0].textContent, 'to be', '26');
expect(days[0].classList.contains('prev'), 'to be true');
expect(days[0].classList.contains('next'), 'to be false');
expect(days[5].textContent, 'to be', '31');
expect(days[5].classList.contains('prev'), 'to be true');
expect(days[5].classList.contains('next'), 'to be false');
expect(days[6].textContent, 'to be', '1');
expect(days[6].classList.contains('prev'), 'to be false');
expect(days[6].classList.contains('next'), 'to be false');
expect(days[34].textContent, 'to be', '29');
expect(days[34].classList.contains('prev'), 'to be false');
expect(days[34].classList.contains('next'), 'to be false');
expect(days[35].textContent, 'to be', '1');
expect(days[35].classList.contains('prev'), 'to be false');
expect(days[35].classList.contains('next'), 'to be true');
expect(days[41].textContent, 'to be', '7');
expect(days[41].classList.contains('prev'), 'to be false');
expect(days[41].classList.contains('next'), 'to be true');
expect(filterCells(days, '.focused'), 'to equal', [days[19]]);
expect(filterCells(days, '.selected'), 'to be empty');
expect(days[19].textContent, 'to be', '14');
dp.destroy();
clock.restore();
});
it('displays iniial date\'s month with the date as selected and focued date', function () {
input.value = '04/22/2020';
const {dp, picker} = createDP(input);
const days = Array.from(picker.querySelector('.datepicker-grid').children);
dp.show();
expect(getViewSwitch(picker).textContent, 'to be', 'April 2020');
expect(days, 'to have length', 42);
expect(filterCells(days, '.datepicker-cell'), 'to have length', 42);
expect(days[0].textContent, 'to be', '29');
expect(days[0].classList.contains('prev'), 'to be true');
expect(days[0].classList.contains('next'), 'to be false');
expect(days[2].textContent, 'to be', '31');
expect(days[2].classList.contains('prev'), 'to be true');
expect(days[2].classList.contains('next'), 'to be false');
expect(days[3].textContent, 'to be', '1');
expect(days[3].classList.contains('prev'), 'to be false');
expect(days[3].classList.contains('next'), 'to be false');
expect(days[32].textContent, 'to be', '30');
expect(days[32].classList.contains('prev'), 'to be false');
expect(days[32].classList.contains('next'), 'to be false');
expect(days[33].textContent, 'to be', '1');
expect(days[33].classList.contains('prev'), 'to be false');
expect(days[33].classList.contains('next'), 'to be true');
expect(days[41].textContent, 'to be', '9');
expect(days[41].classList.contains('prev'), 'to be false');
expect(days[41].classList.contains('next'), 'to be true');
expect(filterCells(days, '.focused'), 'to equal', [days[24]]);
expect(filterCells(days, '.selected'), 'to equal', [days[24]]);
expect(days[24].textContent, 'to be', '22');
dp.destroy();
input.value = '';
});
it('displays day names of week by default', function () {
const {dp, picker} = createDP(input);
const daysOfWeek = picker.querySelector('.days-of-week');
const days = Array.from(daysOfWeek.children).map(el => el.textContent);
expect(days, 'to equal', ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']);
dp.destroy();
});
it('does not display calendar weeks by default', function () {
const {dp, picker} = createDP(input);
expect(picker.querySelectorAll('.calendar-weeks').length, 'to be', 0);
dp.destroy();
});
it('uses "button" for the main class of button element', function () {
const {dp, picker} = createDP(input);
const [viewSwitch, prevBtn, nextBtn, todayBtn, clearBtn] = getParts(picker, [
'.view-switch',
'.prev-btn',
'.next-btn',
'.today-btn',
'.clear-btn',
]);
expect(viewSwitch.className, 'to be', 'button view-switch');
expect(prevBtn.className, 'to be', 'button prev-btn');
expect(nextBtn.className, 'to be', 'button next-btn');
expect(todayBtn.className, 'to be', 'button today-btn');
expect(clearBtn.className, 'to be', 'button clear-btn');
dp.destroy();
});
});
});

View File

@ -0,0 +1,328 @@
describe('Datepicker - API methods', function () {
let clock;
let input;
let dp;
let picker;
beforeEach(function () {
clock = sinon.useFakeTimers({now: new Date(2020, 2, 14)});
input = parseHTML('<input type="text" value="04/22/2020">').firstChild;
testContainer.appendChild(input);
dp = new Datepicker(input);
picker = document.querySelector('.datepicker');
input.focus(); // Activate for visibility checks
});
afterEach(function () {
if (input.datepicker) {
dp.destroy();
}
testContainer.removeChild(input);
clock.restore();
});
describe('getDate()', function () {
it('returns a Date object of selected date', function () {
const date = dp.getDate();
expect(date, 'to be a date');
expect(date.getTime(), 'to be', dateValue(2020, 3, 22));
});
it('returns a formatted date stirng of selected date if the format is specified', function () {
expect(dp.getDate('yyyy-mm-dd'), 'to be', '2020-04-22');
});
it('returns undefined if no date is selected', function () {
dp.destroy();
input.value = '';
dp = new Datepicker(input);
expect(dp.getDate(), 'to be undefined');
expect(dp.getDate('yyyy-mm-dd'), 'to be undefined');
});
});
describe('setDate()', function () {
it('changes the selected date to given date', function () {
const spyChnageEvent = sinon.spy();
input.addEventListener('change', spyChnageEvent);
const viewSwitdh = getViewSwitch(picker);
const date = new Date(2019, 11, 23);
dp.setDate(date);
expect(dp.dates, 'to equal', [date.getTime()]);
expect(input.value, 'to be', '12/23/2019');
expect(viewSwitdh.textContent, 'to be', 'December 2019');
let cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', [cells[22]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[22]]);
expect(cells[22].textContent, 'to be', '23');
dp.setDate('04/22/2020');
expect(dp.dates, 'to equal', [dateValue(2020, 3, 22)]);
expect(input.value, 'to be', '04/22/2020');
expect(viewSwitdh.textContent, 'to be', 'April 2020');
cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', [cells[24]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[24]]);
expect(cells[24].textContent, 'to be', '22');
// change by api call should not be a trigger of change event
// (issue #24)
expect(spyChnageEvent.called, 'to be false');
input.removeEventListener('change', spyChnageEvent);
// change the view to the selected daye's days view
// (issue #33)
dp.picker.changeFocus(dateValue(2021, 3, 20)).changeView(2).render();
dp.setDate('02/14/2020');
expect(dp.dates, 'to equal', [dateValue(2020, 1, 14)]);
expect(input.value, 'to be', '02/14/2020');
expect(viewSwitdh.textContent, 'to be', 'February 2020');
cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', [cells[19]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
expect(cells[19].textContent, 'to be', '14');
});
it('does nothing if no date or invalid date is given', function () {
const viewSwitdh = getViewSwitch(picker);
const origDates = [dateValue(2020, 3, 22)];
dp.setDate();
expect(dp.dates, 'to equal', origDates);
expect(input.value, 'to be', '04/22/2020');
expect(viewSwitdh.textContent, 'to be', 'April 2020');
const cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', [cells[24]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[24]]);
expect(cells[24].textContent, 'to be', '22');
dp.setDate('');
expect(dp.dates, 'to equal', origDates);
expect(input.value, 'to be', '04/22/2020');
});
it('clears the selection if no dates + clear: true option are given', function () {
const spyChnageEvent = sinon.spy();
input.addEventListener('change', spyChnageEvent);
const viewSwitdh = getViewSwitch(picker);
const today = dateUtils.today();
dp.setDate({clear: true});
expect(dp.dates, 'to equal', []);
expect(input.value, 'to be', '');
expect(viewSwitdh.textContent, 'to be', Datepicker.formatDate(today, 'MM yyyy'));
// view date is changed to the default view date (current date)
const cells = getCells(picker);
const todayCell = filterCells(cells, el => el.dataset.date == today)[0];
expect(todayCell.textContent, 'to be', Datepicker.formatDate(today, 'd'));
expect(filterCells(cells, '.selected'), 'to equal', []);
expect(filterCells(cells, '.focused'), 'to equal', [todayCell]);
// change by api call should not be a trigger of change event
// (issue #24)
expect(spyChnageEvent.called, 'to be false');
input.removeEventListener('change', spyChnageEvent);
});
it('omits updating the picker UI if render option = false', function () {
const date = new Date(2019, 11, 23);
dp.setDate(date, {render: false});
expect(dp.dates, 'to equal', [date.getTime()]);
expect(input.value, 'to be', '12/23/2019');
const cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', [cells[24]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[24]]);
expect(cells[24].textContent, 'to be', '22');
});
it('hides the picker if both render and autohide options are true', function () {
let date = new Date(2019, 11, 23);
dp.setDate(date, {render: false, autohide: true});
expect(dp.dates, 'to equal', [date.getTime()]);
expect(input.value, 'to be', '12/23/2019');
expect(getViewSwitch(picker).textContent, 'to be', 'April 2020');
expect(filterCells(getCells(picker), '.selected')[0].textContent, 'to be', '22');
expect(isVisible(picker), 'to be true');
date = new Date(2018, 6, 14);
dp.setDate(date, {autohide: true});
expect(dp.dates, 'to equal', [date.getTime()]);
expect(input.value, 'to be', '07/14/2018');
expect(getViewSwitch(picker).textContent, 'to be', 'July 2018');
expect(filterCells(getCells(picker), '.selected')[0].textContent, 'to be', '14');
expect(isVisible(picker), 'to be false');
});
});
describe('update()', function () {
it('updates the selected date with the input element\'s value', function () {
const viewSwitdh = getViewSwitch(picker);
const date = new Date(2019, 11, 23);
input.value = '12/23/2019';
dp.update();
expect(dp.dates, 'to equal', [date.getTime()]);
expect(input.value, 'to be', '12/23/2019');
expect(viewSwitdh.textContent, 'to be', 'December 2019');
let cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', [cells[22]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[22]]);
expect(cells[22].textContent, 'to be', '23');
// change the view to the selected daye's days view
// (issue #33)
dp.picker.changeFocus(dateValue(2021, 3, 20)).changeView(2).render();
input.value = '02/14/2020';
dp.update();
expect(dp.dates, 'to equal', [dateValue(2020, 1, 14)]);
expect(input.value, 'to be', '02/14/2020');
expect(viewSwitdh.textContent, 'to be', 'February 2020');
cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', [cells[19]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
expect(cells[19].textContent, 'to be', '14');
});
it('notmalizes iput text\'s format', function () {
const date = new Date(2020, 6, 4);
input.value = '7 4 2020';
dp.update();
expect(dp.dates, 'to equal', [date.getTime()]);
expect(input.value, 'to be', '07/04/2020');
expect(getViewSwitch(picker).textContent, 'to be', 'July 2020');
expect(filterCells(getCells(picker), '.selected')[0].textContent, 'to be', '4');
});
});
describe('refresh()', function () {
it('refreshes the input element and picker UI to refrect the internal data', function () {
const spyChnageEvent = sinon.spy();
input.addEventListener('change', spyChnageEvent);
dp.dates = [dateValue(2020, 1, 14)];
dp.refresh();
expect(input.value, 'to be', '02/14/2020');
expect(getViewSwitch(picker).textContent, 'to be', 'February 2020');
const cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', [cells[19]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
expect(cells[19].textContent, 'to be', '14');
// change by api call should not be a trigger of change event
// (issue #24)
expect(spyChnageEvent.called, 'to be false');
input.removeEventListener('change', spyChnageEvent);
});
it('also changes the view back to the selected date\'s days view', function () {
dp.dates = [dateValue(2020, 1, 14)];
dp.picker.changeFocus(dateValue(2021, 3, 20)).changeView(2).render();
dp.refresh();
expect(input.value, 'to be', '02/14/2020');
expect(getViewSwitch(picker).textContent, 'to be', 'February 2020');
let cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', [cells[19]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
expect(cells[19].textContent, 'to be', '14');
// go back to the current date's days view if no date is selected
dp.dates = [];
dp.picker.changeFocus(dateValue(2019, 10, 22)).update().changeView(1).render();
dp.refresh();
expect(input.value, 'to be', '');
expect(getViewSwitch(picker).textContent, 'to be', 'March 2020');
cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', []);
expect(filterCells(cells, '.focused'), 'to equal', [cells[13]]);
expect(cells[13].textContent, 'to be', '14');
clock.restore();
});
it('refresh only picker UI if target: "picker" is passed', function () {
dp.dates = [dateValue(2020, 1, 14)];
dp.refresh('picker');
expect(input.value, 'to be', '04/22/2020');
expect(getViewSwitch(picker).textContent, 'to be', 'February 2020');
const cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', [cells[19]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
expect(cells[19].textContent, 'to be', '14');
});
it('refresh only input element if target: "input" is passed', function () {
dp.dates = [dateValue(2020, 1, 14)];
dp.refresh('input');
expect(input.value, 'to be', '02/14/2020');
expect(getViewSwitch(picker).textContent, 'to be', 'April 2020');
const cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', [cells[24]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[24]]);
expect(cells[24].textContent, 'to be', '22');
});
it('re-renders the picker regardless of its state if forceRender true is passed', function () {
let cells = getCells(picker);
cells[16].classList.add('foo');
cells[12].textContent = '♥︎';
dp.dates = [dateValue(2020, 3, 10)];
dp.refresh('picker');
cells = getCells(picker);
expect(input.value, 'to be', '04/22/2020');
expect(getViewSwitch(picker).textContent, 'to be', 'April 2020');
expect(filterCells(cells, '.selected'), 'to equal', [cells[12]]);
expect(filterCells(cells, '.foo'), 'to equal', [cells[16]]);
expect(cells[12].textContent, 'to be', '♥︎');
dp.refresh('picker', true);
cells = getCells(picker);
expect(input.value, 'to be', '04/22/2020');
expect(getViewSwitch(picker).textContent, 'to be', 'April 2020');
expect(filterCells(cells, '.selected'), 'to equal', [cells[12]]);
expect(filterCells(cells, '.foo'), 'to equal', []);
expect(cells[12].textContent, 'to be', '10');
cells[16].classList.add('foo');
cells[12].textContent = '♥︎';
dp.refresh(true);
cells = getCells(picker);
expect(input.value, 'to be', '04/10/2020');
expect(getViewSwitch(picker).textContent, 'to be', 'April 2020');
expect(filterCells(cells, '.selected'), 'to equal', [cells[12]]);
expect(filterCells(cells, '.foo'), 'to equal', []);
expect(cells[12].textContent, 'to be', '10');
});
});
});

102
node_modules/flowbite-datepicker/test/_utils/date.js generated vendored Normal file
View File

@ -0,0 +1,102 @@
var dateUtils = (function (exports) {
'use strict';
function stripTime(timeValue) {
return new Date(timeValue).setHours(0, 0, 0, 0);
}
function today() {
return new Date().setHours(0, 0, 0, 0);
}
// Get the time value of the start of given date or year, month and day
function dateValue(...args) {
switch (args.length) {
case 0:
return today();
case 1:
return stripTime(args[0]);
}
// use setFullYear() to keep 2-digit year from being mapped to 1900-1999
const newDate = new Date(0);
newDate.setFullYear(...args);
return newDate.setHours(0, 0, 0, 0);
}
function addDays(date, amount) {
const newDate = new Date(date);
return newDate.setDate(newDate.getDate() + amount);
}
function addWeeks(date, amount) {
return addDays(date, amount * 7);
}
function addMonths(date, amount) {
// If the day of the date is not in the new month, the last day of the new
// month will be returned. e.g. Jan 31 + 1 month → Feb 28 (not Mar 03)
const newDate = new Date(date);
const monthsToSet = newDate.getMonth() + amount;
let expectedMonth = monthsToSet % 12;
if (expectedMonth < 0) {
expectedMonth += 12;
}
const time = newDate.setMonth(monthsToSet);
return newDate.getMonth() !== expectedMonth ? newDate.setDate(0) : time;
}
function addYears(date, amount) {
// If the date is Feb 29 and the new year is not a leap year, Feb 28 of the
// new year will be returned.
const newDate = new Date(date);
const expectedMonth = newDate.getMonth();
const time = newDate.setFullYear(newDate.getFullYear() + amount);
return expectedMonth === 1 && newDate.getMonth() === 2 ? newDate.setDate(0) : time;
}
// Calculate the distance bettwen 2 days of the week
function dayDiff(day, from) {
return (day - from + 7) % 7;
}
// Get the date of the specified day of the week of given base date
function dayOfTheWeekOf(baseDate, dayOfWeek, weekStart = 0) {
const baseDay = new Date(baseDate).getDay();
return addDays(baseDate, dayDiff(dayOfWeek, weekStart) - dayDiff(baseDay, weekStart));
}
// Get the ISO week of a date
function getWeek(date) {
// start of ISO week is Monday
const thuOfTheWeek = dayOfTheWeekOf(date, 4, 1);
// 1st week == the week where the 4th of January is in
const firstThu = dayOfTheWeekOf(new Date(thuOfTheWeek).setMonth(0, 4), 4, 1);
return Math.round((thuOfTheWeek - firstThu) / 604800000) + 1;
}
// Get the start year of the period of years that includes given date
// years: length of the year period
function startOfYearPeriod(date, years) {
/* @see https://en.wikipedia.org/wiki/Year_zero#ISO_8601 */
const year = new Date(date).getFullYear();
return Math.floor(year / years) * years;
}
exports.addDays = addDays;
exports.addMonths = addMonths;
exports.addWeeks = addWeeks;
exports.addYears = addYears;
exports.dateValue = dateValue;
exports.dayOfTheWeekOf = dayOfTheWeekOf;
exports.getWeek = getWeek;
exports.startOfYearPeriod = startOfYearPeriod;
exports.stripTime = stripTime;
exports.today = today;
Object.defineProperty(exports, '__esModule', { value: true });
return exports;
})({});

70
node_modules/flowbite-datepicker/test/_utils/dom.js generated vendored Normal file
View File

@ -0,0 +1,70 @@
var domUtils = (function (exports) {
'use strict';
const range = document.createRange();
function parseHTML(html) {
return range.createContextualFragment(html);
}
// equivalent to jQuery's :visble
function isVisible(el) {
return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length);
}
function hideElement(el) {
if (el.style.display === 'none') {
return;
}
// back up the existing display setting in data-style-display
if (el.style.display) {
el.dataset.styleDisplay = el.style.display;
}
el.style.display = 'none';
}
function showElement(el) {
if (el.style.display !== 'none') {
return;
}
if (el.dataset.styleDisplay) {
// restore backed-up dispay property
el.style.display = el.dataset.styleDisplay;
delete el.dataset.styleDisplay;
} else {
el.style.display = '';
}
}
function emptyChildNodes(el) {
if (el.firstChild) {
el.removeChild(el.firstChild);
emptyChildNodes(el);
}
}
function replaceChildNodes(el, newChildNodes) {
emptyChildNodes(el);
if (newChildNodes instanceof DocumentFragment) {
el.appendChild(newChildNodes);
} else if (typeof newChildNodes === 'string') {
el.appendChild(parseHTML(newChildNodes));
} else if (typeof newChildNodes.forEach === 'function') {
newChildNodes.forEach((node) => {
el.appendChild(node);
});
}
}
exports.emptyChildNodes = emptyChildNodes;
exports.hideElement = hideElement;
exports.isVisible = isVisible;
exports.parseHTML = parseHTML;
exports.replaceChildNodes = replaceChildNodes;
exports.showElement = showElement;
Object.defineProperty(exports, '__esModule', { value: true });
return exports;
})({});

785
node_modules/flowbite-datepicker/test/events.js generated vendored Normal file
View File

@ -0,0 +1,785 @@
describe('events', function () {
let clock;
let input;
let dp;
let picker;
let viewSwitch;
before(function () {
clock = sinon.useFakeTimers({now: new Date(2020, 1, 14)});
input = document.createElement('input');
testContainer.appendChild(input);
({dp, picker} = createDP(input));
viewSwitch = getViewSwitch(picker);
});
after(function () {
dp.destroy();
testContainer.removeChild(input);
clock.restore();
});
describe('changeDate', function () {
it('is triggered when the selection is changed', function () {
const spyChangeDate = sinon.spy();
input.addEventListener('changeDate', spyChangeDate);
// by setDate()
dp.setDate('2/14/2020');
expect(spyChangeDate.calledOnce, 'to be true');
spyChangeDate.resetHistory();
// by update()
input.value = '4/22/2020';
dp.update();
expect(spyChangeDate.calledOnce, 'to be true');
spyChangeDate.resetHistory();
// by clicking on a day cell
getCells(picker)[12].click();
expect(spyChangeDate.calledOnce, 'to be true');
spyChangeDate.resetHistory();
// by hitting enter in edit mode
dp.enterEditMode();
input.value = '2/4/2020';
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(spyChangeDate.calledOnce, 'to be true');
spyChangeDate.resetHistory();
// by hittin enter when the picker is hidden
dp.hide();
input.value = '3/20/2020';
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(spyChangeDate.calledOnce, 'to be true');
input.removeEventListener('changeDate', spyChangeDate);
dp.setDate({clear: true});
});
it('is triggered when the selection is cleared', function () {
const spyChangeDate = sinon.spy();
dp.setDate('2/14/2020');
input.addEventListener('changeDate', spyChangeDate);
// by setDate()
dp.setDate({clear: true});
expect(spyChangeDate.calledOnce, 'to be true');
dp.setDate('2/14/2020');
spyChangeDate.resetHistory();
// by update()
input.value = '';
dp.update();
expect(spyChangeDate.calledOnce, 'to be true');
dp.setDate('2/14/2020');
spyChangeDate.resetHistory();
// by hitting enter in edit mode
dp.enterEditMode();
input.value = '';
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(spyChangeDate.calledOnce, 'to be true');
dp.setDate('2/14/2020');
spyChangeDate.resetHistory();
// by hittin enter when the picker is hidden
dp.hide();
input.value = '';
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(spyChangeDate.calledOnce, 'to be true');
input.removeEventListener('changeDate', spyChangeDate);
});
it('is not triggered when trying to update with the current value', function () {
const spyChangeDate = sinon.spy();
dp.setDate('2/14/2020');
input.addEventListener('changeDate', spyChangeDate);
// by setDate()
dp.setDate('2/14/2020');
expect(spyChangeDate.called, 'to be false');
// by update()
dp.update();
expect(spyChangeDate.called, 'to be false');
// by clicking on a day cell
getCells(picker)[19].click();
expect(spyChangeDate.called, 'to be false');
// by hitting enter in edit mode
dp.enterEditMode();
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(spyChangeDate.called, 'to be false');
// by hittin enter when the picker is hidden
dp.hide();
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(spyChangeDate.called, 'to be false');
input.removeEventListener('changeDate', spyChangeDate);
dp.setDate({clear: true});
});
});
describe('changeMonth', function () {
let spyChangeMonth;
beforeEach(function () {
dp.show();
spyChangeMonth = sinon.spy();
input.addEventListener('changeMonth', spyChangeMonth);
});
afterEach(function () {
input.removeEventListener('changeMonth', spyChangeMonth);
dp.hide();
});
it('is triggered when prevBtn or nextBtn is clicked on days view', function () {
const [prevBtn, nextBtn] = getParts(picker, ['.prev-btn', '.next-btn']);
prevBtn.click();
expect(spyChangeMonth.calledOnce, 'to be true');
nextBtn.click();
expect(spyChangeMonth.calledTwice, 'to be true');
spyChangeMonth.resetHistory();
// months view
viewSwitch.click();
prevBtn.click();
expect(spyChangeMonth.called, 'to be false');
nextBtn.click();
expect(spyChangeMonth.called, 'to be false');
// years view
viewSwitch.click();
prevBtn.click();
expect(spyChangeMonth.called, 'to be false');
nextBtn.click();
expect(spyChangeMonth.called, 'to be false');
// decades view
viewSwitch.click();
prevBtn.click();
expect(spyChangeMonth.called, 'to be false');
nextBtn.click();
expect(spyChangeMonth.called, 'to be false');
});
it('is triggered when ctrl + arrow lett/right is pressed on days view', function () {
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
expect(spyChangeMonth.called, 'to be false');
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
expect(spyChangeMonth.called, 'to be false');
simulant.fire(input, 'keydown', {key: 'ArrowLeft', ctrlKey: true});
expect(spyChangeMonth.calledOnce, 'to be true');
simulant.fire(input, 'keydown', {key: 'ArrowRight', ctrlKey: true});
expect(spyChangeMonth.calledTwice, 'to be true');
spyChangeMonth.resetHistory();
// months view
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowLeft', ctrlKey: true});
expect(spyChangeMonth.called, 'to be false');
simulant.fire(input, 'keydown', {key: 'ArrowRight', ctrlKey: true});
expect(spyChangeMonth.called, 'to be false');
// years view
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowLeft', ctrlKey: true});
expect(spyChangeMonth.called, 'to be false');
simulant.fire(input, 'keydown', {key: 'ArrowRight', ctrlKey: true});
expect(spyChangeMonth.called, 'to be false');
// decades view
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowLeft', ctrlKey: true});
expect(spyChangeMonth.called, 'to be false');
simulant.fire(input, 'keydown', {key: 'ArrowRight', ctrlKey: true});
expect(spyChangeMonth.called, 'to be false');
});
it('is triggered when a previous or next month\'s day is clicked', function () {
getCells(picker)[19].click();
expect(spyChangeMonth.called, 'to be false');
getCells(picker)[2].click();
expect(spyChangeMonth.calledOnce, 'to be true');
getCells(picker)[40].click();
expect(spyChangeMonth.calledTwice, 'to be true');
dp.setDate({clear: true});
});
it('is triggered when view date is moved to a previous or next month\'s day by arrow keys', function () {
// move to 2/1/2020
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
// go to 1/31
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
expect(spyChangeMonth.calledOnce, 'to be true');
// go back to 2/1
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
expect(spyChangeMonth.calledTwice, 'to be true');
spyChangeMonth.resetHistory();
// move to 2/3/2020
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
// go to 1/27
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(spyChangeMonth.calledOnce, 'to be true');
// go back to 2/3
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
expect(spyChangeMonth.calledTwice, 'to be true');
});
it('is triggered when a different month is seleced on months view', function () {
viewSwitch.click();
getCells(picker)[1].click();
expect(spyChangeMonth.called, 'to be false');
viewSwitch.click();
getCells(picker)[2].click();
expect(spyChangeMonth.calledOnce, 'to be true');
});
it('is triggered when moving month by arrow keys on months view', function () {
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
expect(spyChangeMonth.callCount, 'to be', 1);
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
expect(spyChangeMonth.callCount, 'to be', 2);
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
expect(spyChangeMonth.callCount, 'to be', 3);
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(spyChangeMonth.callCount, 'to be', 4);
});
it('is triggered when the selection is updated to a different month by API calls', function () {
dp.setDate('2/22/2020');
expect(spyChangeMonth.called, 'to be false');
dp.setDate('4/22/2020');
expect(spyChangeMonth.calledOnce, 'to be true');
input.value = '3/14/2020';
dp.update();
expect(spyChangeMonth.calledTwice, 'to be true');
});
it('is triggered when the selection is cleard from a date of a different month from default view date', function () {
dp.setDate('2/22/2020');
spyChangeMonth.resetHistory();
dp.setDate({clear: true});
expect(spyChangeMonth.called, 'to be false');
dp.setDate('4/22/2020');
spyChangeMonth.resetHistory();
input.value = '';
dp.update();
expect(spyChangeMonth.calledOnce, 'to be true');
dp.setDate('4/22/2020');
spyChangeMonth.resetHistory();
dp.enterEditMode();
input.value = '';
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(spyChangeMonth.calledOnce, 'to be true');
});
it('is triggered before changeDate when triggered on change of the selection', function () {
const spyChangeDate = sinon.spy();
input.addEventListener('changeDate', spyChangeDate);
dp.setDate('4/22/2020');
expect(spyChangeDate.called, 'to be true');
expect(spyChangeMonth.called, 'to be true');
expect(spyChangeMonth.calledBefore(spyChangeDate), 'to be true');
input.removeEventListener('changeDate', spyChangeDate);
dp.setDate({clear: true});
});
it('is triggered when view is reset from different month from default view date on hide', function () {
picker.querySelector('.next-btn').click();
spyChangeMonth.resetHistory();
dp.hide();
expect(spyChangeMonth.calledOnce, 'to be true');
});
it('is not triggered when view date is changed to the same month of different year', function () {
viewSwitch.click();
viewSwitch.click();
// years view
getCells(picker)[3].click();
expect(spyChangeMonth.called, 'to be false');
// months view
getCells(picker)[1].click();
expect(spyChangeMonth.called, 'to be false');
viewSwitch.click();
viewSwitch.click();
// years view
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(spyChangeMonth.called, 'to be false');
// months view
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(spyChangeMonth.called, 'to be false');
});
});
describe('changeYear', function () {
let spyChangeYear;
beforeEach(function () {
dp.show();
spyChangeYear = sinon.spy();
input.addEventListener('changeYear', spyChangeYear);
});
afterEach(function () {
input.removeEventListener('changeYear', spyChangeYear);
dp.hide();
});
it('is triggered when prevBtn on January on days view or nextBtn on December is clicked', function () {
const [prevBtn, nextBtn] = getParts(picker, ['.prev-btn', '.next-btn']);
// move to 1/15
prevBtn.click();
spyChangeYear.resetHistory();
prevBtn.click();
expect(spyChangeYear.calledOnce, 'to be true');
nextBtn.click();
expect(spyChangeYear.calledTwice, 'to be true');
});
it('is triggered when ctrl + arrow lett is pressed on January on days view or right on December', function () {
// move to 1/15
picker.querySelector('.prev-btn').click();
spyChangeYear.resetHistory();
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
expect(spyChangeYear.called, 'to be false');
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
expect(spyChangeYear.called, 'to be false');
simulant.fire(input, 'keydown', {key: 'ArrowLeft', ctrlKey: true});
expect(spyChangeYear.calledOnce, 'to be true');
simulant.fire(input, 'keydown', {key: 'ArrowRight', ctrlKey: true});
expect(spyChangeYear.calledTwice, 'to be true');
});
it('is triggered when a previous month\'s day on January or a next month\'s on December is clicked', function () {
// move to 1/15
picker.querySelector('.prev-btn').click();
spyChangeYear.resetHistory();
getCells(picker)[19].click();
expect(spyChangeYear.called, 'to be false');
getCells(picker)[2].click();
expect(spyChangeYear.calledOnce, 'to be true');
getCells(picker)[40].click();
expect(spyChangeYear.calledTwice, 'to be true');
dp.setDate({clear: true});
});
it('is triggered when prevBtn or nextBtn is clicked on months view', function () {
const [prevBtn, nextBtn] = getParts(picker, ['.prev-btn', '.next-btn']);
viewSwitch.click();
prevBtn.click();
expect(spyChangeYear.calledOnce, 'to be true');
nextBtn.click();
expect(spyChangeYear.calledTwice, 'to be true');
});
it('is triggered when view month is moved to a previous or next year\'s by arrow keys', function () {
viewSwitch.click();
// move to january
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
// go to last year's December
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
expect(spyChangeYear.calledOnce, 'to be true');
// go back to January
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
expect(spyChangeYear.calledTwice, 'to be true');
spyChangeYear.resetHistory();
// go to last year's September
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(spyChangeYear.calledOnce, 'to be true');
// go back to January
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
expect(spyChangeYear.calledTwice, 'to be true');
});
it('is triggered when a different year/decade is seleced on years/decades view', function () {
viewSwitch.click();
viewSwitch.click();
viewSwitch.click();
// decades view
getCells(picker)[0].click();
expect(spyChangeYear.calledOnce, 'to be true');
// years view
getCells(picker)[2].click();
expect(spyChangeYear.calledTwice, 'to be true');
viewSwitch.click();
viewSwitch.click();
spyChangeYear.resetHistory();
// decades view
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(spyChangeYear.calledOnce, 'to be true');
// years view
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(spyChangeYear.calledTwice, 'to be true');
});
it('is triggered when moving year/decade by arrow keys on years/decades view', function () {
viewSwitch.click();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
expect(spyChangeYear.callCount, 'to be', 1);
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
expect(spyChangeYear.callCount, 'to be', 2);
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
expect(spyChangeYear.callCount, 'to be', 3);
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(spyChangeYear.callCount, 'to be', 4);
viewSwitch.click();
spyChangeYear.resetHistory();
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
expect(spyChangeYear.callCount, 'to be', 1);
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
expect(spyChangeYear.callCount, 'to be', 2);
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
expect(spyChangeYear.callCount, 'to be', 3);
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(spyChangeYear.callCount, 'to be', 4);
});
it('is triggered when the selection is updated to a different year by API calls', function () {
dp.setDate('2/22/2020');
expect(spyChangeYear.called, 'to be false');
dp.setDate('4/22/2022');
expect(spyChangeYear.calledOnce, 'to be true');
input.value = '3/14/2018';
dp.update();
expect(spyChangeYear.calledTwice, 'to be true');
});
it('is triggered when the selection is cleard from a date of a different year from default view date', function () {
dp.setDate('2/22/2020');
spyChangeYear.resetHistory();
dp.setDate({clear: true});
expect(spyChangeYear.called, 'to be false');
dp.setDate('4/22/2022');
spyChangeYear.resetHistory();
input.value = '';
dp.update();
expect(spyChangeYear.calledOnce, 'to be true');
dp.setDate('4/22/2022');
spyChangeYear.resetHistory();
dp.enterEditMode();
input.value = '';
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(spyChangeYear.calledOnce, 'to be true');
});
it('is triggered before changeDate when triggered on change of the selection', function () {
const spyChangeDate = sinon.spy();
input.addEventListener('changeDate', spyChangeDate);
dp.setDate('4/22/2022');
expect(spyChangeDate.called, 'to be true');
expect(spyChangeYear.called, 'to be true');
expect(spyChangeYear.calledBefore(spyChangeDate), 'to be true');
input.removeEventListener('changeDate', spyChangeDate);
dp.setDate({clear: true});
});
it('is triggered when view is reset from different year from default view date on hide', function () {
picker.querySelector('.prev-btn').click();
picker.querySelector('.prev-btn').click();
spyChangeYear.resetHistory();
dp.hide();
expect(spyChangeYear.calledOnce, 'to be true');
});
});
describe('changeView', function () {
let spyChangeView;
beforeEach(function () {
dp.show();
spyChangeView = sinon.spy();
input.addEventListener('changeView', spyChangeView);
});
afterEach(function () {
input.removeEventListener('changeView', spyChangeView);
dp.hide();
});
it('is triggered when view is changed by clicking view switch', function () {
viewSwitch.click();
expect(spyChangeView.calledOnce, 'to be true');
// on months view
viewSwitch.click();
expect(spyChangeView.calledTwice, 'to be true');
// on years view
viewSwitch.click();
expect(spyChangeView.calledThrice, 'to be true');
// on decades view
viewSwitch.click();
expect(spyChangeView.calledThrice, 'to be true');
});
it('is triggered when view is changed by pressing ctrl + arrow up', function () {
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(spyChangeView.called, 'to be false');
simulant.fire(input, 'keydown', {key: 'ArrowUp', ctrlKey: true});
expect(spyChangeView.calledOnce, 'to be true');
// on months view
simulant.fire(input, 'keydown', {key: 'ArrowUp', ctrlKey: true});
expect(spyChangeView.calledTwice, 'to be true');
// on years view
simulant.fire(input, 'keydown', {key: 'ArrowUp', ctrlKey: true});
expect(spyChangeView.calledThrice, 'to be true');
// on decades view
simulant.fire(input, 'keydown', {key: 'ArrowUp', ctrlKey: true});
expect(spyChangeView.calledThrice, 'to be true');
});
it('is triggered when view is changed by seleting a decade/year/month on decades/years/months view', function () {
viewSwitch.click();
viewSwitch.click();
viewSwitch.click();
spyChangeView.resetHistory();
// on decades view
getCells(picker)[2].click();
expect(spyChangeView.calledOnce, 'to be true');
// on years view
getCells(picker)[2].click();
expect(spyChangeView.calledTwice, 'to be true');
// on months view
getCells(picker)[2].click();
expect(spyChangeView.calledThrice, 'to be true');
// on days view
getCells(picker)[12].click();
expect(spyChangeView.calledThrice, 'to be true');
viewSwitch.click();
viewSwitch.click();
viewSwitch.click();
spyChangeView.resetHistory();
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(spyChangeView.calledOnce, 'to be true');
// on decades view
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(spyChangeView.calledTwice, 'to be true');
// on years view
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(spyChangeView.calledThrice, 'to be true');
// on months view
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(spyChangeView.calledThrice, 'to be true');
// on days view
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(spyChangeView.calledThrice, 'to be true');
});
it('is triggered when view is reset on hide', function () {
viewSwitch.click();
spyChangeView.resetHistory();
dp.hide();
expect(spyChangeView.calledOnce, 'to be true');
});
});
describe('show', function () {
let spyShow;
beforeEach(function () {
dp.show();
spyShow = sinon.spy();
input.addEventListener('show', spyShow);
});
afterEach(function () {
input.removeEventListener('show', spyShow);
dp.hide();
});
it('is triggered when the picker becomes visible', function () {
// not triggered if already shown
dp.show();
expect(spyShow.called, 'to be false');
dp.hide();
// by API call
dp.show();
expect(spyShow.calledOnce, 'to be true');
dp.hide();
input.blur();
// by getting focus
input.focus();
expect(spyShow.calledTwice, 'to be true');
// by toggling visibility by Esc key
simulant.fire(input, 'keydown', {key: 'Escape'});
expect(spyShow.calledTwice, 'to be true');
simulant.fire(input, 'keydown', {key: 'Escape'});
expect(spyShow.calledThrice, 'to be true');
});
});
describe('hide', function () {
let spyHide;
beforeEach(function () {
dp.show();
spyHide = sinon.spy();
input.addEventListener('hide', spyHide);
});
afterEach(function () {
input.removeEventListener('hide', spyHide);
dp.hide();
});
it('is triggered when the picker becomes hidden', function () {
// by API call
dp.hide();
expect(spyHide.callCount, 'to be', 1);
dp.show();
// by clicking outside
simulant.fire(testContainer, 'mousedown');
expect(spyHide.callCount, 'to be', 2);
dp.show();
// by pressing tab key
simulant.fire(input, 'keydown', {key: 'Tab'});
expect(spyHide.callCount, 'to be', 3);
dp.show();
// by toggling visibility by Esc key
simulant.fire(input, 'keydown', {key: 'Escape'});
expect(spyHide.callCount, 'to be', 4);
});
});
describe('event object', function () {
const stubChangeDate = (ev) => {
eventObj = ev;
};
let eventObj;
before(function () {
input.addEventListener('changeDate', stubChangeDate);
dp.setDate('2/14/2020');
});
after(function () {
input.removeEventListener('changeDate', stubChangeDate);
});
it('is a custom event object', function () {
expect(eventObj, 'to be a', CustomEvent);
});
it('has the result of getDate() in detail.date', function () {
expect(eventObj.detail.date, 'to equal', dp.getDate());
});
it('has a date object of view date in detail.viewDate', function () {
expect(eventObj.detail.viewDate, 'to be a date');
expect(eventObj.detail.viewDate.getTime(), 'to be', dateValue(2020, 1, 14));
});
it('has view mode of current view in detail.viewId', function () {
expect(eventObj.detail.viewId, 'to be', 0);
});
it('has the Datepicker instance in detail.datepicker', function () {
expect(eventObj.detail.datepicker, 'to be', dp);
});
});
});

45
node_modules/flowbite-datepicker/test/inline-mode.js generated vendored Normal file
View File

@ -0,0 +1,45 @@
describe('inline mode', function () {
let element;
let dp;
let picker;
beforeEach(function () {
element = parseHTML('<div data-date="04/22/2020"></div>').firstChild;
testContainer.appendChild(element);
dp = new Datepicker(element, {container: 'body'});
picker = document.querySelector('.datepicker');
});
afterEach(function () {
dp.destroy();
testContainer.removeChild(element);
});
it('uses the bound element for the container regardless of the container option', function () {
expect(picker.parentElement, 'to be', element);
});
it('does not add datepicker-input class to the bound element', function () {
expect(element.classList.contains('datepicker-input'), 'to be false');
});
it('shows the picker on construction', function () {
expect(isVisible(picker), 'to be true');
});
it('uses the data-date attribute for the initial date(s)', function () {
expect(dp.dates[0], 'to be', dateValue(2020, 3, 22));
expect(getViewSwitch(picker).textContent, 'to be', 'April 2020');
expect(picker.querySelector('.datepicker-cell.selected').textContent, 'to be', '22');
});
it('hide() takes no effect', function () {
dp.hide();
expect(isVisible(picker), 'to be true');
});
it('enterEditMode() takes no effect', function () {
dp.enterEditMode();
expect(dp.editMode, 'to be undefined');
});
});

View File

@ -0,0 +1,293 @@
describe('keyboard operation - arrow-down', function () {
const replaceInput = () => {
const newInput = document.createElement('input');
testContainer.replaceChild(newInput, input);
return newInput;
};
let input;
beforeEach(function () {
input = document.createElement('input');
testContainer.appendChild(input);
});
afterEach(function () {
testContainer.removeChild(input);
});
it('shows the picker if it is hidden', function () {
const {dp, picker} = createDP(input);
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
expect(isVisible(picker), 'to be true');
dp.destroy();
});
it('moves the view date/month/year/decade to 1 step down side', function () {
const clock = sinon.useFakeTimers({now: new Date(2044, 5, 15)});
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
input.focus();
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
expect(viewSwitch.textContent, 'to be', 'June 2044');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[24]]);
expect(cells[24].textContent, 'to be', '22');
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
expect(viewSwitch.textContent, 'to be', '2044');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[9]]);
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
expect(viewSwitch.textContent, 'to be', '2040-2049');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[9]]);
expect(cells[9].textContent, 'to be', '2048');
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
expect(viewSwitch.textContent, 'to be', '2000-2090');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[9]]);
expect(cells[9].textContent, 'to be', '2080');
dp.destroy();
clock.restore();
});
it('also changes month of the days view if the current view date >= last 7 days of month', function () {
let clock = sinon.useFakeTimers({now: new Date(2020, 1, 23)});
let {dp, picker} = createDP(input);
let viewSwitch = getViewSwitch(picker);
input.focus();
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
expect(viewSwitch.textContent, 'to be', 'March 2020');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[0]]);
expect(cells[0].textContent, 'to be', '1');
dp.destroy();
clock.restore();
input = replaceInput();
clock = sinon.useFakeTimers({now: new Date(2020, 1, 26)});
({dp, picker} = createDP(input));
viewSwitch = getViewSwitch(picker);
input.focus();
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
expect(viewSwitch.textContent, 'to be', 'March 2020');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[3]]);
expect(cells[3].textContent, 'to be', '4');
dp.destroy();
clock.restore();
input = replaceInput();
clock = sinon.useFakeTimers({now: new Date(2020, 1, 29)});
({dp, picker} = createDP(input));
viewSwitch = getViewSwitch(picker);
input.focus();
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
expect(viewSwitch.textContent, 'to be', 'March 2020');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[6]]);
expect(cells[6].textContent, 'to be', '7');
dp.destroy();
clock.restore();
});
it('also changes year of the months view if the current view month is Sep/Oct/Npv/Dec', function () {
let clock = sinon.useFakeTimers({now: new Date(2020, 8, 1)});
let {dp, picker} = createDP(input);
let viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
expect(viewSwitch.textContent, 'to be', '2021');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[0]]);
dp.destroy();
clock.restore();
input = replaceInput();
clock = sinon.useFakeTimers({now: new Date(2020, 9, 1)});
({dp, picker} = createDP(input));
viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
expect(viewSwitch.textContent, 'to be', '2021');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
dp.destroy();
clock.restore();
input = replaceInput();
clock = sinon.useFakeTimers({now: new Date(2020, 10, 1)});
({dp, picker} = createDP(input));
viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
expect(viewSwitch.textContent, 'to be', '2021');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[2]]);
dp.destroy();
clock.restore();
input = replaceInput();
clock = sinon.useFakeTimers({now: new Date(2020, 11, 1)});
({dp, picker} = createDP(input));
viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
expect(viewSwitch.textContent, 'to be', '2021');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[3]]);
dp.destroy();
clock.restore();
});
it('also changes decade of the years view if the current view year is the first 4 of the decade', function () {
let clock = sinon.useFakeTimers({now: new Date(2016, 1, 1)});
let {dp, picker} = createDP(input);
let viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
expect(viewSwitch.textContent, 'to be', '2020-2029');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
expect(cells[1].textContent, 'to be', '2020');
dp.destroy();
clock.restore();
input = replaceInput();
clock = sinon.useFakeTimers({now: new Date(2018, 1, 1)});
({dp, picker} = createDP(input));
viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
expect(viewSwitch.textContent, 'to be', '2020-2029');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[3]]);
expect(cells[3].textContent, 'to be', '2022');
dp.destroy();
clock.restore();
input = replaceInput();
clock = sinon.useFakeTimers({now: new Date(2019, 1, 1)});
({dp, picker} = createDP(input));
viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
expect(viewSwitch.textContent, 'to be', '2020-2029');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[4]]);
expect(cells[4].textContent, 'to be', '2023');
dp.destroy();
clock.restore();
});
it('also changes century of the decades view if the current view decade is the first 4 of the century', function () {
let clock = sinon.useFakeTimers({now: new Date(1960, 1, 1)});
let {dp, picker} = createDP(input);
let viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
viewSwitch.click();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
expect(viewSwitch.textContent, 'to be', '2000-2090');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
expect(cells[1].textContent, 'to be', '2000');
dp.destroy();
clock.restore();
input = replaceInput();
clock = sinon.useFakeTimers({now: new Date(1980, 1, 1)});
({dp, picker} = createDP(input));
viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
viewSwitch.click();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
expect(viewSwitch.textContent, 'to be', '2000-2090');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[3]]);
expect(cells[3].textContent, 'to be', '2020');
dp.destroy();
clock.restore();
input = replaceInput();
clock = sinon.useFakeTimers({now: new Date(1990, 1, 1)});
({dp, picker} = createDP(input));
viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
viewSwitch.click();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
expect(viewSwitch.textContent, 'to be', '2000-2090');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[4]]);
expect(cells[4].textContent, 'to be', '2030');
dp.destroy();
clock.restore();
});
});

View File

@ -0,0 +1,255 @@
describe('keyboard operation - arrow-left', function () {
let input;
beforeEach(function () {
input = document.createElement('input');
testContainer.appendChild(input);
});
afterEach(function () {
testContainer.removeChild(input);
});
it('moves the view date/month/year/decade to 1 step left side', function () {
const clock = sinon.useFakeTimers({now: new Date(2024, 5, 12)});
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
input.focus();
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
expect(viewSwitch.textContent, 'to be', 'June 2024');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[16]]);
expect(cells[16].textContent, 'to be', '11');
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
expect(viewSwitch.textContent, 'to be', '2024');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[4]]);
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
expect(viewSwitch.textContent, 'to be', '2020-2029');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[4]]);
expect(cells[4].textContent, 'to be', '2023');
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
expect(viewSwitch.textContent, 'to be', '2000-2090');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[2]]);
expect(cells[2].textContent, 'to be', '2010');
clock.restore();
dp.destroy();
});
it('also changes month of the days view if the current view date is the 1st', function () {
const clock = sinon.useFakeTimers({now: new Date(2020, 2, 1)});
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
input.focus();
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
expect(viewSwitch.textContent, 'to be', 'February 2020');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[34]]);
expect(cells[34].textContent, 'to be', '29');
dp.destroy();
clock.restore();
});
it('also changes year of the months view if the current view month is January', function () {
const clock = sinon.useFakeTimers({now: new Date(2020, 0, 1)});
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
expect(viewSwitch.textContent, 'to be', '2019');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[11]]);
dp.destroy();
clock.restore();
});
it('also changes decade of the years view if the current view year is the start of the decade', function () {
const clock = sinon.useFakeTimers({now: new Date(2020, 1, 1)});
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
expect(viewSwitch.textContent, 'to be', '2010-2019');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[10]]);
expect(cells[10].textContent, 'to be', '2019');
dp.destroy();
clock.restore();
});
it('also changes century of the decades view if the current view decade is the start of the century', function () {
const clock = sinon.useFakeTimers({now: new Date(2000, 1, 1)});
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
viewSwitch.click();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
expect(viewSwitch.textContent, 'to be', '1900-1990');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[10]]);
expect(cells[10].textContent, 'to be', '1990');
dp.destroy();
clock.restore();
});
it('does nothing if the view date is 0000-01-01', function () {
input.value = '01/01/0000';
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
input.focus();
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
expect(viewSwitch.textContent, 'to be', 'January 0');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[6]]);
expect(cells[6].textContent, 'to be', '1');
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
expect(viewSwitch.textContent, 'to be', '0');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[0]]);
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
expect(viewSwitch.textContent, 'to be', '0-9');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
expect(cells[1].textContent, 'to be', '0');
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
expect(viewSwitch.textContent, 'to be', '0-90');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
expect(cells[1].textContent, 'to be', '0');
dp.destroy();
});
describe('with control', function () {
it('functions as the shortcut key of the prev button', function () {
const clock = sinon.useFakeTimers({now: new Date(2020, 3, 22)});
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
input.focus();
simulant.fire(input, 'keydown', {key: 'ArrowLeft', ctrlKey: true});
expect(viewSwitch.textContent, 'to be', 'March 2020');
// view date is changed to the same day of the previous month
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[21]]);
expect(cells[21].textContent, 'to be', '22');
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowLeft', ctrlKey: true});
expect(viewSwitch.textContent, 'to be', '2019');
// view date is changed to the same month of the previous year
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[2]]);
expect(filterCells(cells, '.selected'), 'to equal', []);
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowLeft', ctrlKey: true});
expect(viewSwitch.textContent, 'to be', '2000-2009');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[10]]);
expect(cells[10].textContent, 'to be', '2009');
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowLeft', ctrlKey: true});
expect(viewSwitch.textContent, 'to be', '1900-1990');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
expect(cells[1].textContent, 'to be', '1900');
dp.destroy();
clock.reset();
});
});
describe('with meta', function () {
it('functions as a substitute for the "+ctrl" key combination', function () {
let clock = sinon.useFakeTimers({now: new Date(2020, 3, 22)});
let {dp, picker} = createDP(input);
let viewSwitch = getViewSwitch(picker);
input.focus();
simulant.fire(input, 'keydown', {key: 'ArrowLeft', metaKey: true});
expect(viewSwitch.textContent, 'to be', 'March 2020');
// view date is changed to the same day of the previous month
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[21]]);
expect(cells[21].textContent, 'to be', '22');
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowLeft', metaKey: true});
expect(viewSwitch.textContent, 'to be', '2019');
// view date is changed to the same month of the previous year
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[2]]);
expect(filterCells(cells, '.selected'), 'to equal', []);
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowLeft', metaKey: true});
expect(viewSwitch.textContent, 'to be', '2000-2009');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[10]]);
expect(cells[10].textContent, 'to be', '2009');
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowLeft', metaKey: true});
expect(viewSwitch.textContent, 'to be', '1900-1990');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
expect(cells[1].textContent, 'to be', '1900');
dp.destroy();
clock.restore();
});
});
});

View File

@ -0,0 +1,215 @@
describe('keyboard operation - arrow-right', function () {
let input;
beforeEach(function () {
input = document.createElement('input');
testContainer.appendChild(input);
});
afterEach(function () {
testContainer.removeChild(input);
});
it('moves the view date/month/year/decade to 1 step right side', function () {
const clock = sinon.useFakeTimers({now: new Date(2024, 5, 12)});
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
input.focus();
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
expect(viewSwitch.textContent, 'to be', 'June 2024');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[10]]);
expect(cells[18].textContent, 'to be', '13');
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
expect(viewSwitch.textContent, 'to be', '2024');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[6]]);
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
expect(viewSwitch.textContent, 'to be', '2020-2029');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[6]]);
expect(cells[6].textContent, 'to be', '2025');
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
expect(viewSwitch.textContent, 'to be', '2000-2090');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[4]]);
expect(cells[4].textContent, 'to be', '2030');
dp.destroy();
clock.restore();
});
it('also changes month of the days view if the current view date is the last day', function () {
const clock = sinon.useFakeTimers({now: new Date(2020, 1, 29)});
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
input.focus();
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
expect(viewSwitch.textContent, 'to be', 'March 2020');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[0]]);
expect(cells[0].textContent, 'to be', '1');
dp.destroy();
clock.restore();
});
it('also changes year of the months view if the current view month is December', function () {
const clock = sinon.useFakeTimers({now: new Date(2020, 11, 1)});
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
expect(viewSwitch.textContent, 'to be', '2021');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[0]]);
dp.destroy();
clock.restore();
});
it('also changes decade of the years view if the current view year is the end of the decade', function () {
const clock = sinon.useFakeTimers({now: new Date(2019, 1, 1)});
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
expect(viewSwitch.textContent, 'to be', '2020-2029');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
expect(cells[1].textContent, 'to be', '2020');
dp.destroy();
clock.restore();
});
it('also changes century of the decades view if the current view decade is the end of the century', function () {
const clock = sinon.useFakeTimers({now: new Date(1990, 1, 1)});
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
viewSwitch.click();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
expect(viewSwitch.textContent, 'to be', '2000-2090');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
expect(cells[1].textContent, 'to be', '2000');
dp.destroy();
clock.restore();
});
describe('with control', function () {
it('functions as the shortcut key of the next button', function () {
const clock = sinon.useFakeTimers({now: new Date(2020, 3, 22)});
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
input.focus();
simulant.fire(input, 'keydown', {key: 'ArrowRight', ctrlKey: true});
expect(viewSwitch.textContent, 'to be', 'May 2020');
// view date is changed to the same day of the next month
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[26]]);
expect(cells[26].textContent, 'to be', '22');
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowRight', ctrlKey: true});
expect(viewSwitch.textContent, 'to be', '2021');
// view date is changed to the same month of the previous year
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[4]]);
expect(filterCells(cells, '.selected'), 'to equal', []);
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowRight', ctrlKey: true});
expect(viewSwitch.textContent, 'to be', '2030-2039');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[2]]);
expect(cells[2].textContent, 'to be', '2031');
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowRight', ctrlKey: true});
expect(viewSwitch.textContent, 'to be', '2100-2190');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[2]]);
expect(cells[4].textContent, 'to be', '2130');
dp.destroy();
clock.reset();
});
});
describe('with meta', function () {
it('functions as a substitute for the "+ctrl" key combination', function () {
let clock = sinon.useFakeTimers({now: new Date(2020, 3, 22)});
let {dp, picker} = createDP(input);
let viewSwitch = getViewSwitch(picker);
input.focus();
simulant.fire(input, 'keydown', {key: 'ArrowRight', metaKey: true});
expect(viewSwitch.textContent, 'to be', 'May 2020');
// view date is changed to the same day of the next month
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[26]]);
expect(cells[26].textContent, 'to be', '22');
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowRight', metaKey: true});
expect(viewSwitch.textContent, 'to be', '2021');
// view date is changed to the same month of the previous year
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[4]]);
expect(filterCells(cells, '.selected'), 'to equal', []);
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowRight', metaKey: true});
expect(viewSwitch.textContent, 'to be', '2030-2039');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[2]]);
expect(cells[2].textContent, 'to be', '2031');
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowRight', metaKey: true});
expect(viewSwitch.textContent, 'to be', '2100-2190');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[2]]);
expect(cells[4].textContent, 'to be', '2130');
dp.destroy();
clock.restore();
});
});
});

View File

@ -0,0 +1,461 @@
describe('keyboard operation - arrow-up', function () {
const replaceInput = () => {
const newInput = document.createElement('input');
testContainer.replaceChild(newInput, input);
return newInput;
};
let input;
beforeEach(function () {
input = document.createElement('input');
testContainer.appendChild(input);
});
afterEach(function () {
testContainer.removeChild(input);
});
it('moves the view date/month/year/decade to 1 step up side', function () {
const clock = sinon.useFakeTimers({now: new Date(2044, 5, 15)});
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
input.focus();
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(viewSwitch.textContent, 'to be', 'June 2044');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[10]]);
expect(cells[10].textContent, 'to be', '8');
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(viewSwitch.textContent, 'to be', '2044');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(viewSwitch.textContent, 'to be', '2040-2049');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
expect(cells[1].textContent, 'to be', '2040');
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(viewSwitch.textContent, 'to be', '2000-2090');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
expect(cells[1].textContent, 'to be', '2000');
dp.destroy();
clock.restore();
});
it('also changes month of the days view if the current view date <= 7th', function () {
let clock = sinon.useFakeTimers({now: new Date(2020, 2, 1)});
let {dp, picker} = createDP(input);
let viewSwitch = getViewSwitch(picker);
input.focus();
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(viewSwitch.textContent, 'to be', 'February 2020');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[28]]);
expect(cells[28].textContent, 'to be', '23');
dp.destroy();
clock.restore();
input = replaceInput();
clock = sinon.useFakeTimers({now: new Date(2020, 2, 4)});
({dp, picker} = createDP(input));
viewSwitch = getViewSwitch(picker);
input.focus();
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(viewSwitch.textContent, 'to be', 'February 2020');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[31]]);
expect(cells[31].textContent, 'to be', '26');
dp.destroy();
clock.restore();
input = replaceInput();
clock = sinon.useFakeTimers({now: new Date(2020, 2, 7)});
({dp, picker} = createDP(input));
viewSwitch = getViewSwitch(picker);
input.focus();
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(viewSwitch.textContent, 'to be', 'February 2020');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[34]]);
expect(cells[34].textContent, 'to be', '29');
dp.destroy();
clock.restore();
});
it('also changes year of the months view if the current view month is Jan/Feb/Mar/Apr', function () {
let clock = sinon.useFakeTimers({now: new Date(2020, 0, 1)});
let {dp, picker} = createDP(input);
let viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(viewSwitch.textContent, 'to be', '2019');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[8]]);
dp.destroy();
clock.restore();
input = replaceInput();
clock = sinon.useFakeTimers({now: new Date(2020, 1, 1)});
({dp, picker} = createDP(input));
viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(viewSwitch.textContent, 'to be', '2019');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[9]]);
dp.destroy();
clock.restore();
input = replaceInput();
clock = sinon.useFakeTimers({now: new Date(2020, 2, 1)});
({dp, picker} = createDP(input));
viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(viewSwitch.textContent, 'to be', '2019');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[10]]);
dp.destroy();
clock.restore();
input = replaceInput();
clock = sinon.useFakeTimers({now: new Date(2020, 3, 1)});
({dp, picker} = createDP(input));
viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(viewSwitch.textContent, 'to be', '2019');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[11]]);
dp.destroy();
clock.restore();
});
it('also changes decade of the years view if the current view year is the first 4 of the decade', function () {
let clock = sinon.useFakeTimers({now: new Date(2020, 1, 1)});
let {dp, picker} = createDP(input);
let viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(viewSwitch.textContent, 'to be', '2010-2019');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[7]]);
expect(cells[7].textContent, 'to be', '2016');
dp.destroy();
clock.restore();
input = replaceInput();
clock = sinon.useFakeTimers({now: new Date(2022, 1, 1)});
({dp, picker} = createDP(input));
viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(viewSwitch.textContent, 'to be', '2010-2019');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[9]]);
expect(cells[9].textContent, 'to be', '2018');
dp.destroy();
clock.restore();
input = replaceInput();
clock = sinon.useFakeTimers({now: new Date(2023, 1, 1)});
({dp, picker} = createDP(input));
viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(viewSwitch.textContent, 'to be', '2010-2019');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[10]]);
expect(cells[10].textContent, 'to be', '2019');
dp.destroy();
clock.restore();
});
it('also changes century of the decades view if the current view decade is the first 4 of the century', function () {
let clock = sinon.useFakeTimers({now: new Date(2000, 1, 1)});
let {dp, picker} = createDP(input);
let viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
viewSwitch.click();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(viewSwitch.textContent, 'to be', '1900-1990');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[7]]);
expect(cells[7].textContent, 'to be', '1960');
dp.destroy();
clock.restore();
input = replaceInput();
clock = sinon.useFakeTimers({now: new Date(2020, 1, 1)});
({dp, picker} = createDP(input));
viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
viewSwitch.click();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(viewSwitch.textContent, 'to be', '1900-1990');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[9]]);
expect(cells[9].textContent, 'to be', '1980');
dp.destroy();
clock.restore();
input = replaceInput();
clock = sinon.useFakeTimers({now: new Date(2030, 1, 1)});
({dp, picker} = createDP(input));
viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
viewSwitch.click();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(viewSwitch.textContent, 'to be', '1900-1990');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[10]]);
expect(cells[10].textContent, 'to be', '1990');
dp.destroy();
clock.restore();
});
it('does nothing if the current view date <= 0000-01-07 in the days view', function () {
input.value = '01/01/0000';
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
input.focus();
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(viewSwitch.textContent, 'to be', 'January 0');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[6]]);
expect(cells[6].textContent, 'to be', '1');
dp.setDate('01/07/0000');
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(viewSwitch.textContent, 'to be', 'January 0');
expect(filterCells(cells, '.focused'), 'to equal', [cells[12]]);
expect(cells[12].textContent, 'to be', '7');
dp.destroy();
});
it('does nothing if the current view month <= April 0000 in the months view', function () {
input.value = '01/01/0000';
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(viewSwitch.textContent, 'to be', '0');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[0]]);
dp.setDate('04/07/0000');
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(viewSwitch.textContent, 'to be', '0');
expect(filterCells(cells, '.focused'), 'to equal', [cells[3]]);
dp.destroy();
});
it('does nothing if the current view year <= 0004 in the years view', function () {
input.value = '01/01/0000';
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(viewSwitch.textContent, 'to be', '0-9');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
expect(cells[1].textContent, 'to be', '0');
dp.setDate('04/07/0004');
viewSwitch.click();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(viewSwitch.textContent, 'to be', '0-9');
expect(filterCells(cells, '.focused'), 'to equal', [cells[5]]);
expect(cells[5].textContent, 'to be', '4');
dp.destroy();
});
it('does nothing if the current view decade <= 0040 in the decades view', function () {
input.value = '01/01/0000';
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
viewSwitch.click();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
expect(viewSwitch.textContent, 'to be', '0-90');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
expect(cells[1].textContent, 'to be', '0');
dp.setDate('04/07/0047');
viewSwitch.click();
viewSwitch.click();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(viewSwitch.textContent, 'to be', '0-90');
expect(filterCells(cells, '.focused'), 'to equal', [cells[5]]);
expect(cells[5].textContent, 'to be', '40');
dp.destroy();
});
describe('with control', function () {
it('functions as the shortcut key of the view switch', function () {
const clock = sinon.useFakeTimers({now: new Date(2020, 3, 22)});
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
input.focus();
simulant.fire(input, 'keydown', {key: 'ArrowUp', ctrlKey: true});
expect(viewSwitch.textContent, 'to be', '2020');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[3]]);
simulant.fire(input, 'keydown', {key: 'ArrowUp', ctrlKey: true});
expect(viewSwitch.textContent, 'to be', '2020-2029');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
expect(cells[1].textContent, 'to be', '2020');
simulant.fire(input, 'keydown', {key: 'ArrowUp', ctrlKey: true});
expect(viewSwitch.textContent, 'to be', '2000-2090');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[3]]);
expect(cells[3].textContent, 'to be', '2020');
// does nothig if the view has reached to the max view
simulant.fire(input, 'keydown', {key: 'ArrowUp', ctrlKey: true});
expect(viewSwitch.textContent, 'to be', '2000-2090');
dp.destroy();
clock.reset();
});
});
describe('with meta', function () {
it('functions as a substitute for the "+ctrl" key combination', function () {
const clock = sinon.useFakeTimers({now: new Date(2020, 3, 22)});
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
input.focus();
simulant.fire(input, 'keydown', {key: 'ArrowUp', metaKey: true});
expect(viewSwitch.textContent, 'to be', '2020');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[3]]);
simulant.fire(input, 'keydown', {key: 'ArrowUp', metaKey: true});
expect(viewSwitch.textContent, 'to be', '2020-2029');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
expect(cells[1].textContent, 'to be', '2020');
simulant.fire(input, 'keydown', {key: 'ArrowUp', metaKey: true});
expect(viewSwitch.textContent, 'to be', '2000-2090');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[3]]);
expect(cells[3].textContent, 'to be', '2020');
// does nothig if the view has reached to the max view
simulant.fire(input, 'keydown', {key: 'ArrowUp', metaKey: true});
expect(viewSwitch.textContent, 'to be', '2000-2090');
dp.destroy();
clock.reset();
});
});
});

View File

@ -0,0 +1,458 @@
describe('keyboard operation - edit mode', function () {
let input;
beforeEach(function () {
input = document.createElement('input');
testContainer.appendChild(input);
});
afterEach(function () {
testContainer.removeChild(input);
});
it('turns on when Datepicker.enterEditMode() is called', function () {
const dp = new Datepicker(input);
input.focus();
dp.enterEditMode();
expect(dp.editMode, 'to be true');
expect(input.classList.contains('in-edit'), 'to be true');
dp.destroy();
input.classList.remove('in-edit');
});
it('turns on when a printable letter, backspace or delete key is pressed without ctrl/meta', function () {
const dp = new Datepicker(input);
input.focus();
simulant.fire(input, 'keydown', {key: '1'});
expect(dp.editMode, 'to be true');
delete dp.editMode;
input.classList.remove('in-edit');
simulant.fire(input, 'keydown', {key: 'J'});
expect(dp.editMode, 'to be true');
delete dp.editMode;
input.classList.remove('in-edit');
simulant.fire(input, 'keydown', {key: '/'});
expect(dp.editMode, 'to be true');
delete dp.editMode;
input.classList.remove('in-edit');
simulant.fire(input, 'keydown', {key: ' '});
expect(dp.editMode, 'to be true');
delete dp.editMode;
input.classList.remove('in-edit');
simulant.fire(input, 'keydown', {key: 'Backspace'});
expect(dp.editMode, 'to be true');
delete dp.editMode;
input.classList.remove('in-edit');
simulant.fire(input, 'keydown', {key: 'Delete'});
expect(dp.editMode, 'to be true');
delete dp.editMode;
input.classList.remove('in-edit');
// with modifier key
simulant.fire(input, 'keydown', {key: '1', shiftKey: true});
expect(dp.editMode, 'to be true');
delete dp.editMode;
input.classList.remove('in-edit');
simulant.fire(input, 'keydown', {key: '1', altKey: true});
expect(dp.editMode, 'to be true');
delete dp.editMode;
input.classList.remove('in-edit');
simulant.fire(input, 'keydown', {key: '1', ctrlKey: true});
expect(dp.editMode, 'to be undefined');
expect(input.classList.contains('in-edit'), 'to be false');
simulant.fire(input, 'keydown', {key: '1', metaKey: true});
expect(dp.editMode, 'to be undefined');
expect(input.classList.contains('in-edit'), 'to be false');
// non-pritable-letter key
simulant.fire(input, 'keydown', {key: 'PageDown'});
expect(dp.editMode, 'to be undefined');
expect(input.classList.contains('in-edit'), 'to be false');
simulant.fire(input, 'keydown', {key: 'Escape', ctrlKey: true});
expect(dp.editMode, 'to be undefined');
dp.destroy();
});
it('turns on when shift + either of arrow keys is pressed without ctrl/meta', function () {
const dp = new Datepicker(input);
input.focus();
// shift + arrow
simulant.fire(input, 'keydown', {key: 'ArrowLeft', shiftKey: true});
expect(dp.editMode, 'to be true');
delete dp.editMode;
input.classList.remove('in-edit');
simulant.fire(input, 'keydown', {key: 'ArrowRight', shiftKey: true});
expect(dp.editMode, 'to be true');
delete dp.editMode;
input.classList.remove('in-edit');
simulant.fire(input, 'keydown', {key: 'ArrowUp', shiftKey: true});
expect(dp.editMode, 'to be true');
delete dp.editMode;
input.classList.remove('in-edit');
simulant.fire(input, 'keydown', {key: 'ArrowDown', shiftKey: true});
expect(dp.editMode, 'to be true');
delete dp.editMode;
input.classList.remove('in-edit');
// arrow + other modifire key
// arrow-left
simulant.fire(input, 'keydown', {key: 'ArrowLeft', altKey: true});
expect(dp.editMode, 'to be undefined');
simulant.fire(input, 'keydown', {key: 'ArrowLeft', ctrlKey: true});
expect(dp.editMode, 'to be undefined');
simulant.fire(input, 'keydown', {key: 'ArrowLeft', metaKey: true});
expect(dp.editMode, 'to be undefined');
// arrow-right
simulant.fire(input, 'keydown', {key: 'ArrowRight', altKey: true});
expect(dp.editMode, 'to be undefined');
simulant.fire(input, 'keydown', {key: 'ArrowRight', ctrlKey: true});
expect(dp.editMode, 'to be undefined');
simulant.fire(input, 'keydown', {key: 'ArrowRight', metaKey: true});
expect(dp.editMode, 'to be undefined');
// arrow-up
simulant.fire(input, 'keydown', {key: 'ArrowUp', altKey: true});
expect(dp.editMode, 'to be undefined');
simulant.fire(input, 'keydown', {key: 'ArrowUp', ctrlKey: true});
expect(dp.editMode, 'to be undefined');
simulant.fire(input, 'keydown', {key: 'ArrowUp', metaKey: true});
expect(dp.editMode, 'to be undefined');
// arrow-down
simulant.fire(input, 'keydown', {key: 'ArrowDown', altKey: true});
expect(dp.editMode, 'to be undefined');
simulant.fire(input, 'keydown', {key: 'ArrowDown', ctrlKey: true});
expect(dp.editMode, 'to be undefined');
simulant.fire(input, 'keydown', {key: 'ArrowDown', metaKey: true});
expect(dp.editMode, 'to be undefined');
// shift + arrow with other modifier key
// arrow-left
simulant.fire(input, 'keydown', {key: 'ArrowLeft', shiftKey: true, altKey: true});
expect(dp.editMode, 'to be true');
delete dp.editMode;
input.classList.remove('in-edit');
simulant.fire(input, 'keydown', {key: 'ArrowLeft', shiftKey: true, ctrlKey: true});
expect(dp.editMode, 'to be undefined');
simulant.fire(input, 'keydown', {key: 'ArrowLeft', shiftKey: true, metaKey: true});
expect(dp.editMode, 'to be undefined');
// arrow-right
simulant.fire(input, 'keydown', {key: 'ArrowRight', shiftKey: true, altKey: true});
expect(dp.editMode, 'to be true');
delete dp.editMode;
input.classList.remove('in-edit');
simulant.fire(input, 'keydown', {key: 'ArrowRight', shiftKey: true, ctrlKey: true});
expect(dp.editMode, 'to be undefined');
simulant.fire(input, 'keydown', {key: 'ArrowRight', shiftKey: true, metaKey: true});
expect(dp.editMode, 'to be undefined');
// arrow-up
simulant.fire(input, 'keydown', {key: 'ArrowUp', shiftKey: true, altKey: true});
expect(dp.editMode, 'to be true');
delete dp.editMode;
input.classList.remove('in-edit');
simulant.fire(input, 'keydown', {key: 'ArrowUp', shiftKey: true, ctrlKey: true});
expect(dp.editMode, 'to be undefined');
simulant.fire(input, 'keydown', {key: 'ArrowUp', shiftKey: true, metaKey: true});
expect(dp.editMode, 'to be undefined');
// arrow-down
simulant.fire(input, 'keydown', {key: 'ArrowDown', shiftKey: true, altKey: true});
expect(dp.editMode, 'to be true');
delete dp.editMode;
input.classList.remove('in-edit');
simulant.fire(input, 'keydown', {key: 'ArrowDown', shiftKey: true, ctrlKey: true});
expect(dp.editMode, 'to be undefined');
simulant.fire(input, 'keydown', {key: 'ArrowDown', shiftKey: true, metaKey: true});
expect(dp.editMode, 'to be undefined');
dp.destroy();
});
it('turns on when input is clicked', function () {
const dp = new Datepicker(input);
input.focus();
simulant.fire(input, 'mousedown');
input.click();
expect(dp.editMode, 'to be true');
expect(input.classList.contains('in-edit'), 'to be true');
dp.destroy();
input.classList.remove('in-edit');
});
it('does not turn on when the picker is hidden', function () {
const dp = new Datepicker(input);
dp.enterEditMode();
expect(dp.editMode, 'to be undefined');
expect(input.classList.contains('in-edit'), 'to be false');
simulant.fire(input, 'keydown', {key: '1'});
expect(dp.editMode, 'to be undefined');
simulant.fire(input, 'keydown', {key: 'J'});
expect(dp.editMode, 'to be undefined');
simulant.fire(input, 'mousedown');
input.click();
expect(dp.editMode, 'to be undefined');
dp.destroy();
});
it('disables the arrow-key operation of the picker', function () {
const clock = sinon.useFakeTimers({now: new Date(2020, 1, 14)});
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
input.focus();
dp.enterEditMode();
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
expect(viewSwitch.textContent, 'to be', 'February 2020');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
expect(cells[19].textContent, 'to be', '14');
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
expect(viewSwitch.textContent, 'to be', 'February 2020');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(viewSwitch.textContent, 'to be', 'February 2020');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
simulant.fire(input, 'keydown', {key: 'ArrowDownt'});
expect(viewSwitch.textContent, 'to be', 'February 2020');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
expect(viewSwitch.textContent, 'to be', '2020');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
expect(viewSwitch.textContent, 'to be', '2020-2029');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
expect(viewSwitch.textContent, 'to be', '2000-2090');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[3]]);
dp.destroy();
clock.restore();
});
it('turns off when Datepicker.exitEditMode() is called', function () {
const dp = new Datepicker(input);
input.focus();
dp.enterEditMode();
dp.exitEditMode();
expect(dp.editMode, 'to be undefined');
expect(input.classList.contains('in-edit'), 'to be false');
dp.destroy();
});
it('turns off when the picker hides', function () {
const {dp, picker} = createDP(input);
input.focus();
dp.enterEditMode();
dp.hide();
expect(dp.editMode, 'to be undefined');
expect(input.classList.contains('in-edit'), 'to be false');
dp.destroy();
});
it('turns off when escape key is pressed', function () {
const dp = new Datepicker(input);
input.focus();
dp.enterEditMode();
simulant.fire(input, 'keydown', {key: 'Escape'});
expect(dp.editMode, 'to be undefined');
expect(input.classList.contains('in-edit'), 'to be false');
dp.destroy();
});
it('leaves the edit on the input as-is by default when turning off', function () {
const dp = new Datepicker(input);
const date = dateValue(2020, 1, 14);
dp.setDate(date);
input.focus();
dp.enterEditMode();
input.value = '4/22/2020';
dp.exitEditMode();
expect(input.value, 'to be', '4/22/2020');
expect(dp.dates, 'to equal', [date]);
dp.show();
dp.enterEditMode();
input.value = '3/8/2020';
dp.hide();
expect(input.value, 'to be', '3/8/2020');
expect(dp.dates, 'to equal', [date]);
dp.show();
dp.enterEditMode();
input.value = '02/14/2020';
simulant.fire(input, 'keydown', {key: 'Escape'});
expect(input.value, 'to be', '02/14/2020');
expect(dp.dates, 'to equal', [date]);
dp.destroy();
});
it('hides the picker when turning off by escape key press', function () {
const {dp, picker} = createDP(input);
input.focus();
dp.enterEditMode();
simulant.fire(input, 'keydown', {key: 'Escape'});
expect(isVisible(picker), 'to be false');
dp.show();
dp.enterEditMode();
dp.exitEditMode();
expect(isVisible(picker), 'to be true');
dp.destroy();
});
it('updates the selection with the input when turning off by exitEditMode() call with update: true option', function () {
const dp = new Datepicker(input);
const date = dateValue(2020, 3, 22);
dp.setDate('02/14/2020');
input.focus();
dp.enterEditMode();
input.value = '4/22/2020';
dp.exitEditMode({update: true});
expect(dp.editMode, 'to be undefined');
expect(input.classList.contains('in-edit'), 'to be false');
expect(input.value, 'to be', '04/22/2020');
expect(dp.dates, 'to equal', [date]);
dp.destroy();
});
it('updates the selection with the input when turning off by enter key press', function () {
const dp = new Datepicker(input);
const date = dateValue(2020, 3, 22);
dp.setDate('02/14/2020');
input.focus();
dp.enterEditMode();
input.value = '4/22/2020';
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(dp.editMode, 'to be undefined');
expect(input.classList.contains('in-edit'), 'to be false');
expect(input.value, 'to be', '04/22/2020');
expect(dp.dates, 'to equal', [date]);
dp.destroy();
});
it('updates the selection with the input when turning off being induced by unfocusing input element', function () {
const outsider = document.createElement('p');
testContainer.appendChild(outsider);
const dp = new Datepicker(input);
const date = dateValue(2020, 3, 22);
// by tab key-press
dp.setDate('02/14/2020');
input.focus();
dp.enterEditMode();
input.value = '4/22/2020';
simulant.fire(input, 'keydown', {key: 'Tab'});
expect(dp.editMode, 'to be undefined');
expect(input.classList.contains('in-edit'), 'to be false');
expect(input.value, 'to be', '04/22/2020');
expect(dp.dates, 'to equal', [date]);
//by clicking outside
dp.setDate('02/14/2020');
dp.show();
dp.enterEditMode();
input.value = '4/22/2020';
simulant.fire(outsider, 'mousedown');
expect(dp.editMode, 'to be undefined');
expect(input.classList.contains('in-edit'), 'to be false');
expect(input.value, 'to be', '04/22/2020');
expect(dp.dates, 'to equal', [date]);
dp.destroy();
testContainer.removeChild(outsider);
});
});

View File

@ -0,0 +1,146 @@
describe('keyboard operation', function () {
let input;
beforeEach(function () {
input = document.createElement('input');
testContainer.appendChild(input);
});
afterEach(function () {
testContainer.removeChild(input);
});
describe('tab', function () {
it('hides the picker', function () {
const {dp, picker} = createDP(input);
input.focus();
simulant.fire(input, 'keydown', {key: 'Tab'});
expect(isVisible(picker), 'to be false');
dp.destroy();
});
it('updates the selected date with the input\'s value', function () {
const clock = sinon.useFakeTimers({now: new Date(2020, 1, 14)});
const dp = new Datepicker(input);
// when picker is shown
input.focus();
input.value = 'foo';
simulant.fire(input, 'keydown', {key: 'Tab'});
expect(input.value, 'to be', '02/14/2020');
expect(dp.getDate().getTime(), 'to be', dateValue(2020, 1, 14));
// when picker is hidden
input.focus();
input.value = '04/22/2020';
simulant.fire(input, 'keydown', {key: 'Tab'});
expect(input.value, 'to be', '04/22/2020');
expect(dp.getDate().getTime(), 'to be', dateValue(2020, 3, 22));
input.focus();
input.value = '';
simulant.fire(input, 'keydown', {key: 'Tab'});
expect(input.value, 'to be', '');
expect(dp.getDate(), 'to be undefined');
dp.destroy();
clock.restore();
});
});
describe('escape', function () {
it('shows or hides the picker', function () {
const {dp, picker} = createDP(input);
simulant.fire(input, 'keydown', {key: 'Escape'});
expect(isVisible(picker), 'to be true');
simulant.fire(input, 'keydown', {key: 'Escape'});
expect(isVisible(picker), 'to be false');
dp.destroy();
});
});
describe('enter', function () {
it('sets the view date to the selection if the current view is days', function () {
const clock = sinon.useFakeTimers({now: new Date(2020, 1, 14)});
const {dp, picker} = createDP(input);
input.focus();
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(dp.dates, 'to equal', [dateValue(2020, 1, 14)]);
expect(input.value, 'to be', '02/14/2020');
let cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', [cells[19]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
expect(cells[19].textContent, 'to be', '14');
dp.destroy();
clock.reset();
});
it('changes the view to the next minor one if the current view is not days', function () {
const clock = sinon.useFakeTimers({now: new Date(2020, 3, 22)});
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
input.focus();
viewSwitch.click();
viewSwitch.click();
viewSwitch.click();
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(viewSwitch.textContent, 'to be', '2020-2029');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
expect(cells[1].textContent, 'to be', '2020');
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(viewSwitch.textContent, 'to be', '2020');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[3]]);
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(viewSwitch.textContent, 'to be', 'April 2020');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[24]]);
expect(cells[24].textContent, 'to be', '22');
// does nothig if the view has reached to the min view
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(viewSwitch.textContent, 'to be', 'April 2020');
dp.destroy();
clock.reset();
});
it('updates the selection with the input text if the picker is hidden', function () {
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
input.value = '7/4/2020';
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(dp.dates, 'to equal', [dateValue(2020, 6, 4)]);
expect(input.value, 'to be', '07/04/2020');
dp.show();
expect(viewSwitch.textContent, 'to be', 'July 2020');
let cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', [cells[6]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[6]]);
expect(cells[6].textContent, 'to be', '4');
dp.destroy();
});
});
});

View File

@ -0,0 +1,580 @@
describe('mouse operation', function () {
let clock;
let input;
before(function () {
clock = sinon.useFakeTimers({now: new Date(2020, 1, 14)});
input = document.createElement('input');
testContainer.appendChild(input);
});
after(function () {
clock.restore();
testContainer.removeChild(input);
});
it('picker hides if mouse is pressed outside the picker or the input', function () {
const outsider = document.createElement('p');
testContainer.appendChild(outsider);
const {dp, picker} = createDP(input);
input.focus();
simulant.fire(picker.querySelector('.dow'), 'mousedown');
expect(isVisible(picker), 'to be true');
simulant.fire(input, 'mousedown');
expect(isVisible(picker), 'to be true');
simulant.fire(outsider, 'mousedown');
expect(isVisible(picker), 'to be false');
// hide() should not called when picker is hidden
// (issue #45)
const spyHide = sinon.spy(dp, 'hide');
input.blur();
simulant.fire(outsider, 'mousedown');
expect(spyHide.called, 'to be false');
spyHide.restore();
// picker shown programmatically should be closed by clicking outside
// (issue #52)
dp.show();
simulant.fire(outsider, 'mousedown');
expect(isVisible(picker), 'to be false');
dp.destroy();
testContainer.removeChild(outsider);
});
it('selection is updated with input\'s value if mouse is pressed outside the input', function () {
const outsider = document.createElement('p');
testContainer.appendChild(outsider);
const {dp, picker} = createDP(input);
// when picker is shown
input.focus();
input.value = 'foo';
simulant.fire(picker.querySelector('.dow'), 'mousedown');
expect(input.value, 'to be', 'foo');
simulant.fire(input, 'mousedown');
expect(input.value, 'to be', 'foo');
simulant.fire(outsider, 'mousedown');
expect(input.value, 'to be', '02/14/2020');
expect(dp.getDate().getTime(), 'to be', dateValue(2020, 1, 14));
// when picker is hidden
input.focus();
input.value = '04/22/2020';
simulant.fire(outsider, 'mousedown');
expect(input.value, 'to be', '04/22/2020');
expect(dp.getDate().getTime(), 'to be', dateValue(2020, 3, 22));
input.focus();
input.value = '';
simulant.fire(outsider, 'mousedown');
expect(input.value, 'to be', '');
expect(dp.getDate(), 'to be undefined');
dp.destroy();
testContainer.removeChild(outsider);
});
it('picker shows up if input field is clicked wheh picker is hidden', function () {
const {dp, picker} = createDP(input);
// when input field is not focued
simulant.fire(input, 'mousedown');
input.click();
expect(isVisible(picker), 'to be true');
dp.hide();
// when input has focus
simulant.fire(input, 'mousedown');
input.click();
expect(isVisible(picker), 'to be true');
dp.destroy();
});
describe('view-switch', function () {
it('changes the view to the next greater one', function () {
input.value = '04/22/2020';
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
dp.show();
viewSwitch.click();
expect(viewSwitch.textContent, 'to be', '2020');
expect(input.value, 'to be', '04/22/2020');
let cells = getCells(picker);
expect(cells.map(el => el.textContent), 'to equal', Datepicker.locales.en.monthsShort);
expect(cells[3].classList.contains('selected'), 'to be true');
expect(cells[3].classList.contains('focused'), 'to be true');
viewSwitch.click();
expect(viewSwitch.textContent, 'to be', '2020-2029');
expect(input.value, 'to be', '04/22/2020');
cells = getCells(picker);
expect(cells, 'to have length', 12);
expect(cells[0].textContent, 'to be', '2019');
expect(cells[0].classList.contains('prev'), 'to be true');
expect(cells[0].classList.contains('next'), 'to be false');
expect(cells[1].textContent, 'to be', '2020');
expect(cells[1].classList.contains('prev'), 'to be false');
expect(cells[1].classList.contains('next'), 'to be false');
expect(cells[10].textContent, 'to be', '2029');
expect(cells[10].classList.contains('prev'), 'to be false');
expect(cells[10].classList.contains('next'), 'to be false');
expect(cells[11].textContent, 'to be', '2030');
expect(cells[11].classList.contains('prev'), 'to be false');
expect(cells[11].classList.contains('next'), 'to be true');
expect(filterCells(cells, '.selected'), 'to equal', [cells[1]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
viewSwitch.click();
expect(viewSwitch.textContent, 'to be', '2000-2090');
expect(input.value, 'to be', '04/22/2020');
cells = getCells(picker);
expect(cells, 'to have length', 12);
expect(cells[0].textContent, 'to be', '1990');
expect(cells[0].classList.contains('prev'), 'to be true');
expect(cells[0].classList.contains('next'), 'to be false');
expect(cells[1].textContent, 'to be', '2000');
expect(cells[1].classList.contains('prev'), 'to be false');
expect(cells[1].classList.contains('next'), 'to be false');
expect(cells[10].textContent, 'to be', '2090');
expect(cells[10].classList.contains('prev'), 'to be false');
expect(cells[10].classList.contains('next'), 'to be false');
expect(cells[11].textContent, 'to be', '2100');
expect(cells[11].classList.contains('prev'), 'to be false');
expect(cells[11].classList.contains('next'), 'to be true');
expect(filterCells(cells, '.selected'), 'to equal', [cells[3]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[3]]);
expect(cells[3].textContent, 'to be', '2020');
// does nothig if the view has reached to the max view
viewSwitch.click();
expect(viewSwitch.textContent, 'to be', '2000-2090');
dp.destroy();
input.value = '';
});
});
describe('prev-btn', function () {
it('changes the month/year/decade/century of the view to the previouse one', function () {
input.value = '04/22/2020';
const {dp, picker} = createDP(input);
const [viewSwitch, prevBtn] = getParts(picker, ['.view-switch', '.prev-btn']);
dp.show();
prevBtn.click();
expect(viewSwitch.textContent, 'to be', 'March 2020');
expect(input.value, 'to be', '04/22/2020');
// view date is changed to the same day of the previous month
let cells = getCells(picker);
expect(cells, 'to have length', 42);
expect(cells[0].textContent, 'to be', '1');
expect(cells[0].classList.contains('prev'), 'to be false');
expect(cells[0].classList.contains('next'), 'to be false');
expect(cells[30].textContent, 'to be', '31');
expect(cells[30].classList.contains('prev'), 'to be false');
expect(cells[30].classList.contains('next'), 'to be false');
expect(cells[31].textContent, 'to be', '1');
expect(cells[31].classList.contains('prev'), 'to be false');
expect(cells[31].classList.contains('next'), 'to be true');
expect(cells[41].textContent, 'to be', '11');
expect(cells[41].classList.contains('prev'), 'to be false');
expect(cells[41].classList.contains('next'), 'to be true');
expect(filterCells(cells, '.selected'), 'to equal', []);
expect(filterCells(cells, '.focused'), 'to equal', [cells[21]]);
expect(cells[21].textContent, 'to be', '22');
viewSwitch.click();
expect(viewSwitch.textContent, 'to be', '2020');
cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', [cells[3]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[2]]);
prevBtn.click();
expect(viewSwitch.textContent, 'to be', '2019');
expect(input.value, 'to be', '04/22/2020');
// view date is changed to the same month of the previous year
cells = getCells(picker);
expect(cells.map(el => el.textContent), 'to equal', Datepicker.locales.en.monthsShort);
expect(filterCells(cells, '.selected'), 'to equal', []);
expect(filterCells(cells, '.focused'), 'to equal', [cells[2]]);
viewSwitch.click();
expect(viewSwitch.textContent, 'to be', '2010-2019');
cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', [cells[11]]);
expect(cells[11].textContent, 'to be', '2020');
expect(filterCells(cells, '.focused'), 'to equal', [cells[10]]);
expect(cells[10].textContent, 'to be', '2019');
prevBtn.click();
expect(viewSwitch.textContent, 'to be', '2000-2009');
expect(input.value, 'to be', '04/22/2020');
cells = getCells(picker);
expect(cells, 'to have length', 12);
expect(cells[0].textContent, 'to be', '1999');
expect(cells[1].textContent, 'to be', '2000');
expect(cells[10].textContent, 'to be', '2009');
expect(cells[11].textContent, 'to be', '2010');
expect(filterCells(cells, '.selected'), 'to equal', []);
expect(filterCells(cells, '.focused'), 'to equal', [cells[10]]);
viewSwitch.click();
expect(viewSwitch.textContent, 'to be', '2000-2090');
cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', [cells[3]]);
expect(cells[3].textContent, 'to be', '2020');
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
expect(cells[1].textContent, 'to be', '2000');
prevBtn.click();
expect(viewSwitch.textContent, 'to be', '1900-1990');
expect(input.value, 'to be', '04/22/2020');
cells = getCells(picker);
expect(cells, 'to have length', 12);
expect(cells[0].textContent, 'to be', '1890');
expect(cells[1].textContent, 'to be', '1900');
expect(cells[10].textContent, 'to be', '1990');
expect(cells[11].textContent, 'to be', '2000');
expect(filterCells(cells, '.selected'), 'to equal', []);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
dp.destroy();
input.value = '';
});
it('controls the view date in days view to be in the prev month when moving from a longer month to shorter', function () {
input.value = '03/31/2019';
const {dp, picker} = createDP(input);
const [viewSwitch, prevBtn] = getParts(picker, ['.view-switch', '.prev-btn']);
dp.show();
prevBtn.click();
expect(viewSwitch.textContent, 'to be', 'February 2019');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[32]]);
expect(cells[32].textContent, 'to be', '28');
input.value = '03/31/2020';
dp.update();
prevBtn.click();
expect(viewSwitch.textContent, 'to be', 'February 2020');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[34]]);
expect(cells[34].textContent, 'to be', '29');
input.value = '10/31/2020';
dp.update();
prevBtn.click();
expect(viewSwitch.textContent, 'to be', 'September 2020');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[31]]);
expect(cells[31].textContent, 'to be', '30');
dp.destroy();
input.value = '';
});
it('becomes disabled if the view includes the decade/year/month/day of 0000-01-01', function () {
input.value = '01/04/0000';
const {dp, picker} = createDP(input);
const [viewSwitch, prevBtn] = getParts(picker, ['.view-switch', '.prev-btn']);
dp.show();
expect(prevBtn.disabled, 'to be true');
prevBtn.click();
expect(viewSwitch.textContent, 'to be', 'January 0');
viewSwitch.click();
expect(prevBtn.disabled, 'to be true');
prevBtn.click();
expect(viewSwitch.textContent, 'to be', '0');
viewSwitch.click();
expect(prevBtn.disabled, 'to be true');
prevBtn.click();
expect(viewSwitch.textContent, 'to be', '0-9');
viewSwitch.click();
expect(prevBtn.disabled, 'to be true');
prevBtn.click();
expect(viewSwitch.textContent, 'to be', '0-90');
dp.destroy();
input.value = '';
});
});
describe('next-btn', function () {
it('changes the month/year/decade/century of the view to the next one', function () {
input.value = '04/22/2020';
const {dp, picker} = createDP(input);
const [viewSwitch, nextBtn] = getParts(picker, ['.view-switch', '.next-btn']);
dp.show();
nextBtn.click();
expect(viewSwitch.textContent, 'to be', 'May 2020');
expect(input.value, 'to be', '04/22/2020');
// view date is changed to the same day of the next month
let cells = getCells(picker);
expect(cells, 'to have length', 42);
expect(cells[0].textContent, 'to be', '26');
expect(cells[0].classList.contains('prev'), 'to be true');
expect(cells[0].classList.contains('next'), 'to be false');
expect(cells[4].textContent, 'to be', '30');
expect(cells[4].classList.contains('prev'), 'to be true');
expect(cells[4].classList.contains('next'), 'to be false');
expect(cells[5].textContent, 'to be', '1');
expect(cells[5].classList.contains('prev'), 'to be false');
expect(cells[5].classList.contains('next'), 'to be false');
expect(cells[35].textContent, 'to be', '31');
expect(cells[35].classList.contains('prev'), 'to be false');
expect(cells[35].classList.contains('next'), 'to be false');
expect(cells[36].textContent, 'to be', '1');
expect(cells[36].classList.contains('prev'), 'to be false');
expect(cells[36].classList.contains('next'), 'to be true');
expect(cells[41].textContent, 'to be', '6');
expect(cells[41].classList.contains('prev'), 'to be false');
expect(cells[41].classList.contains('next'), 'to be true');
expect(filterCells(cells, '.selected'), 'to equal', []);
expect(filterCells(cells, '.focused'), 'to equal', [cells[26]]);
expect(cells[26].textContent, 'to be', '22');
viewSwitch.click();
expect(viewSwitch.textContent, 'to be', '2020');
cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', [cells[3]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[4]]);
nextBtn.click();
expect(viewSwitch.textContent, 'to be', '2021');
expect(input.value, 'to be', '04/22/2020');
// view date is changed to the same month of the previous year
cells = getCells(picker);
expect(cells.map(el => el.textContent), 'to equal', Datepicker.locales.en.monthsShort);
expect(filterCells(cells, '.selected'), 'to equal', []);
expect(filterCells(cells, '.focused'), 'to equal', [cells[4]]);
viewSwitch.click();
expect(viewSwitch.textContent, 'to be', '2020-2029');
cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', [cells[1]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[2]]);
expect(cells[1].textContent, 'to be', '2020');
expect(cells[2].textContent, 'to be', '2021');
nextBtn.click();
expect(viewSwitch.textContent, 'to be', '2030-2039');
expect(input.value, 'to be', '04/22/2020');
cells = getCells(picker);
expect(cells, 'to have length', 12);
expect(cells[0].textContent, 'to be', '2029');
expect(cells[1].textContent, 'to be', '2030');
expect(cells[10].textContent, 'to be', '2039');
expect(cells[11].textContent, 'to be', '2040');
expect(filterCells(cells, '.selected'), 'to equal', []);
expect(filterCells(cells, '.focused'), 'to equal', [cells[2]]);
expect(cells[2].textContent, 'to be', '2031');
viewSwitch.click();
expect(viewSwitch.textContent, 'to be', '2000-2090');
cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', [cells[3]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[4]]);
expect(cells[3].textContent, 'to be', '2020');
expect(cells[4].textContent, 'to be', '2030');
nextBtn.click();
expect(viewSwitch.textContent, 'to be', '2100-2190');
expect(input.value, 'to be', '04/22/2020');
cells = getCells(picker);
expect(cells, 'to have length', 12);
expect(cells[0].textContent, 'to be', '2090');
expect(cells[1].textContent, 'to be', '2100');
expect(cells[10].textContent, 'to be', '2190');
expect(cells[11].textContent, 'to be', '2200');
expect(filterCells(cells, '.selected'), 'to equal', []);
expect(filterCells(cells, '.focused'), 'to equal', [cells[4]]);
expect(cells[4].textContent, 'to be', '2130');
dp.destroy();
input.value = '';
});
it('controls the view date in days view to be in the next month when moving from a longer month to shorter', function () {
input.value = '01/31/2019';
const {dp, picker} = createDP(input);
const [viewSwitch, nextBtn] = getParts(picker, ['.view-switch', '.next-btn']);
dp.show();
nextBtn.click();
expect(viewSwitch.textContent, 'to be', 'February 2019');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[32]]);
expect(cells[32].textContent, 'to be', '28');
input.value = '01/31/2020';
dp.update();
nextBtn.click();
expect(viewSwitch.textContent, 'to be', 'February 2020');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[34]]);
expect(cells[34].textContent, 'to be', '29');
input.value = '08/31/2020';
dp.update();
nextBtn.click();
expect(viewSwitch.textContent, 'to be', 'September 2020');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[31]]);
expect(cells[31].textContent, 'to be', '30');
dp.destroy();
input.value = '';
});
});
describe('datepicker-cell', function () {
let dp;
let picker;
beforeEach(function () {
({dp, picker} = createDP(input));
dp.show();
});
afterEach(function () {
dp.destroy();
});
it('changes the selection to the clicked date if the current view = days', function () {
const targetCell = getCells(picker)[19];
targetCell.click();
expect(dp.dates, 'to equal', [new Date(2020, 1, 14).getTime()]);
expect(input.value, 'to be', '02/14/2020');
expect(getViewSwitch(picker).textContent, 'to be', 'February 2020');
expect(targetCell.classList.contains('selected'), 'to be true');
expect(targetCell.classList.contains('focused'), 'to be true');
dp.setDate({clear: true});
});
it('also changes the month of the view if a date of previous or next month is clicked', function () {
const viewSwitch = getViewSwitch(picker);
getCells(picker)[1].click();
expect(dp.dates, 'to equal', [new Date(2020, 0, 27).getTime()]);
expect(input.value, 'to be', '01/27/2020');
expect(viewSwitch.textContent, 'to be', 'January 2020');
let cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', [cells[29]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[29]]);
expect(cells[29].textContent, 'to be', '27');
expect(cells[40].textContent, 'to be', '7');
cells[40].click();
expect(dp.dates, 'to equal', [dateValue(2020, 1, 7)]);
expect(input.value, 'to be', '02/07/2020');
expect(viewSwitch.textContent, 'to be', 'February 2020');
cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', [cells[12]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[12]]);
expect(cells[12].textContent, 'to be', '7');
dp.setDate({clear: true});
});
it('changes the view year or month to the clicked one and moves to the next minor view if the current view != days', function () {
const viewSwitch = getViewSwitch(picker);
viewSwitch.click();
viewSwitch.click();
viewSwitch.click();
viewSwitch.click();
// on decades view: 2000-2090
let cells = getCells(picker);
// click "2010"
cells[2].click();
expect(dp.dates, 'to equal', []);
expect(input.value, 'to be', '');
expect(getViewSwitch(picker).textContent, 'to be', '2010-2019');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
expect(cells[1].textContent, 'to be', '2010');
// click "2017"
cells[8].click();
expect(dp.dates, 'to equal', []);
expect(input.value, 'to be', '');
expect(getViewSwitch(picker).textContent, 'to be', '2017');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
expect(cells[1].textContent, 'to be', 'Feb');
// click "Oct"
cells[9].click();
expect(dp.dates, 'to equal', []);
expect(input.value, 'to be', '');
expect(getViewSwitch(picker).textContent, 'to be', 'October 2017');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
expect(cells[10].textContent, 'to be', '11');
});
});
});

View File

@ -0,0 +1,635 @@
describe('options - beforeShow hooks', function () {
let clock;
let input;
beforeEach(function () {
clock = sinon.useFakeTimers({now: new Date(2020, 1, 14)});
input = document.createElement('input');
testContainer.appendChild(input);
});
afterEach(function () {
testContainer.removeChild(input);
clock.restore();
});
describe('beforeShowDay', function () {
it('disables the date when it returns false', function () {
const beforeShowDay = date => !!(date.getDate() % 10);
const {dp, picker} = createDP(input, {beforeShowDay});
let cells = getCells(picker);
let disabledCells = filterCells(cells, '.disabled');
expect(disabledCells, 'to equal', [cells[4], cells[15], cells[25]]);
expect(disabledCells.map(el => el.textContent), 'to equal', ['30', '10', '20']);
picker.querySelector('.next-btn').click();
cells = getCells(picker);
disabledCells = filterCells(cells, '.disabled');
expect(disabledCells, 'to equal', [cells[9], cells[19], cells[29], cells[40]]);
expect(disabledCells.map(el => el.textContent), 'to equal', ['10', '20', '30', '10']);
dp.destroy();
});
it('adds classes to the date when it returns spece separated classes', function () {
const beforeShowDay = date => date.getDate() % 10 ? undefined : 'foo bar';
const {dp, picker} = createDP(input, {beforeShowDay});
let cells = getCells(picker);
let fooCells = filterCells(cells, '.foo');
let barCells = filterCells(cells, '.bar');
expect(fooCells, 'to equal', [cells[4], cells[15], cells[25]]);
expect(barCells, 'to equal', fooCells);
expect(fooCells.map(el => el.textContent), 'to equal', ['30', '10', '20']);
picker.querySelector('.next-btn').click();
cells = getCells(picker);
fooCells = filterCells(cells, '.foo');
barCells = filterCells(cells, '.bar');
expect(fooCells, 'to equal', [cells[9], cells[19], cells[29], cells[40]]);
expect(barCells, 'to equal', fooCells);
expect(fooCells.map(el => el.textContent), 'to equal', ['10', '20', '30', '10']);
dp.destroy();
});
it('disables the date when the return contains enabled: false', function () {
const beforeShowDay = date => ({enabled: !!(date.getDate() % 10)});
const {dp, picker} = createDP(input, {beforeShowDay});
let cells = getCells(picker);
let disabledCells = filterCells(cells, '.disabled');
expect(disabledCells, 'to equal', [cells[4], cells[15], cells[25]]);
picker.querySelector('.next-btn').click();
cells = getCells(picker);
disabledCells = filterCells(cells, '.disabled');
expect(disabledCells, 'to equal', [cells[9], cells[19], cells[29], cells[40]]);
dp.destroy();
});
it('adds classes to the date when the return contains space separated classes in the classes property', function () {
const beforeShowDay = date => date.getDate() % 10 ? undefined : {classes: 'foo bar'};
const {dp, picker} = createDP(input, {beforeShowDay});
let cells = getCells(picker);
let fooCells = filterCells(cells, '.foo');
let barCells = filterCells(cells, '.bar');
expect(fooCells, 'to equal', [cells[4], cells[15], cells[25]]);
expect(barCells, 'to equal', fooCells);
picker.querySelector('.next-btn').click();
cells = getCells(picker);
fooCells = filterCells(cells, '.foo');
barCells = filterCells(cells, '.bar');
expect(fooCells, 'to equal', [cells[9], cells[19], cells[29], cells[40]]);
expect(barCells, 'to equal', fooCells);
dp.destroy();
});
it('uses custom content to the date cell when the return contains text/html in the content property', function () {
const beforeShowDay = (date) => date.getDate() % 10 === 4 ? {content: '<em>❤️</em>'} : undefined;
const {dp, picker} = createDP(input, {beforeShowDay});
let cells = getCells(picker);
let ccCells = cells.filter(el => el.children.length > 0);
expect(ccCells, 'to equal', [cells[9], cells[19], cells[29], cells[38]]);
ccCells.forEach((cell) => {
expect(cell.innerHTML, 'to be', '<em>❤️</em>');
});
picker.querySelector('.next-btn').click();
cells = getCells(picker);
ccCells = cells.filter(el => el.children.length > 0);
expect(ccCells, 'to equal', [cells[3], cells[13], cells[23], cells[34]]);
ccCells.forEach((cell) => {
expect(cell.innerHTML, 'to be', '<em>❤️</em>');
});
dp.destroy();
});
it('can be updated with setOptions()', function () {
const {dp, picker} = createDP(input);
dp.setOptions({beforeShowDay: date => !!(date.getDate() % 10)});
dp.show();
let cells = getCells(picker);
let disabledCells = filterCells(cells, '.disabled');
expect(disabledCells, 'to equal', [cells[4], cells[15], cells[25]]);
dp.hide();
dp.setOptions({beforeShowDay: null});
dp.show();
cells = getCells(picker);
disabledCells = filterCells(cells, '.disabled');
expect(disabledCells, 'to equal', []);
dp.destroy();
});
});
describe('beforeShowMonth', function () {
it('disables the month on months view when it returns false', function () {
const beforeShowMonth = date => !!(date.getMonth() % 5);
const {dp, picker} = createDP(input, {beforeShowMonth});
const viewSwitch = getViewSwitch(picker);
dp.show();
viewSwitch.click();
let cells = getCells(picker);
let disabledCells = filterCells(cells, '.disabled');
expect(disabledCells, 'to equal', [cells[0], cells[5], cells[10]]);
expect(disabledCells.map(el => el.textContent), 'to equal', ['Jan', 'Jun', 'Nov']);
picker.querySelector('.next-btn').click();
cells = getCells(picker);
disabledCells = filterCells(cells, '.disabled');
expect(disabledCells, 'to equal', [cells[0], cells[5], cells[10]]);
expect(disabledCells.map(el => el.textContent), 'to equal', ['Jan', 'Jun', 'Nov']);
dp.destroy();
});
it('adds classes to the month on months view when it returns spece separated classes', function () {
const beforeShowMonth = date => date.getMonth() % 5 ? undefined : 'foo bar';
const {dp, picker} = createDP(input, {beforeShowMonth});
const viewSwitch = getViewSwitch(picker);
dp.show();
viewSwitch.click();
let cells = getCells(picker);
let fooCells = filterCells(cells, '.foo');
let barCells = filterCells(cells, '.bar');
expect(fooCells, 'to equal', [cells[0], cells[5], cells[10]]);
expect(barCells, 'to equal', fooCells);
expect(fooCells.map(el => el.textContent), 'to equal', ['Jan', 'Jun', 'Nov']);
picker.querySelector('.next-btn').click();
cells = getCells(picker);
fooCells = filterCells(cells, '.foo');
barCells = filterCells(cells, '.bar');
expect(fooCells, 'to equal', [cells[0], cells[5], cells[10]]);
expect(barCells, 'to equal', fooCells);
expect(fooCells.map(el => el.textContent), 'to equal', ['Jan', 'Jun', 'Nov']);
dp.destroy();
});
it('disables the month on months view when the return contains enabled: false', function () {
const beforeShowMonth = date => ({enabled: !!(date.getMonth() % 5)});
const {dp, picker} = createDP(input, {beforeShowMonth});
const viewSwitch = getViewSwitch(picker);
dp.show();
viewSwitch.click();
let cells = getCells(picker);
let disabledCells = filterCells(cells, '.disabled');
expect(disabledCells, 'to equal', [cells[0], cells[5], cells[10]]);
picker.querySelector('.next-btn').click();
cells = getCells(picker);
disabledCells = filterCells(cells, '.disabled');
expect(disabledCells, 'to equal', [cells[0], cells[5], cells[10]]);
dp.destroy();
});
it('adds classes to the month on months view when the return contains space separated classes in the classes property', function () {
const beforeShowMonth = date => date.getMonth() % 5 ? undefined : {classes: 'foo bar'};
const {dp, picker} = createDP(input, {beforeShowMonth});
const viewSwitch = getViewSwitch(picker);
dp.show();
viewSwitch.click();
let cells = getCells(picker);
let fooCells = filterCells(cells, '.foo');
let barCells = filterCells(cells, '.bar');
expect(fooCells, 'to equal', [cells[0], cells[5], cells[10]]);
expect(barCells, 'to equal', fooCells);
picker.querySelector('.next-btn').click();
cells = getCells(picker);
fooCells = filterCells(cells, '.foo');
barCells = filterCells(cells, '.bar');
expect(fooCells, 'to equal', [cells[0], cells[5], cells[10]]);
expect(barCells, 'to equal', fooCells);
dp.destroy();
});
it('uses custom content to the month cell when the return contains text/html in the content property', function () {
const beforeShowMonth = (date) => (date.getMonth() + date.getFullYear() % 10) % 10 ? undefined : {content: '🍀'};
const {dp, picker} = createDP(input, {beforeShowMonth});
const viewSwitch = getViewSwitch(picker);
dp.show();
viewSwitch.click();
let cells = getCells(picker);
let ccCells = cells.filter(el => el.textContent.length < 3);
expect(ccCells, 'to equal', [cells[0], cells[10]]);
ccCells.forEach((cell) => {
expect(cell.textContent, 'to be', '🍀');
});
picker.querySelector('.next-btn').click();
cells = getCells(picker);
ccCells = cells.filter(el => el.textContent.length < 3);
expect(ccCells, 'to equal', [cells[9]]);
ccCells.forEach((cell) => {
expect(cell.textContent, 'to be', '🍀');
});
dp.destroy();
});
it('can be updated with setOptions()', function () {
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
dp.setOptions({beforeShowMonth: date => !!(date.getMonth() % 5)});
dp.show();
viewSwitch.click();
let cells = getCells(picker);
let disabledCells = filterCells(cells, '.disabled');
expect(disabledCells, 'to equal', [cells[0], cells[5], cells[10]]);
dp.hide();
dp.setOptions({beforeShowMonth: null});
dp.show();
viewSwitch.click();
cells = getCells(picker);
disabledCells = filterCells(cells, '.disabled');
expect(disabledCells, 'to equal', []);
dp.destroy();
});
});
describe('beforeShowYear', function () {
it('disables the year on years view when it returns false', function () {
const beforeShowYear = date => !!(date.getFullYear() % 4);
const {dp, picker} = createDP(input, {beforeShowYear});
const viewSwitch = getViewSwitch(picker);
dp.show();
viewSwitch.click();
viewSwitch.click();
let cells = getCells(picker);
let disabledCells = filterCells(cells, '.disabled');
expect(disabledCells, 'to equal', [cells[1], cells[5], cells[9]]);
expect(disabledCells.map(el => el.textContent), 'to equal', ['2020', '2024', '2028',]);
picker.querySelector('.next-btn').click();
cells = getCells(picker);
disabledCells = filterCells(cells, '.disabled');
expect(disabledCells, 'to equal', [cells[3], cells[7], cells[11]]);
expect(disabledCells.map(el => el.textContent), 'to equal', ['2032', '2036', '2040']);
dp.destroy();
});
it('adds classes to the year on years view when it returns spece separated classes', function () {
const beforeShowYear = date => date.getFullYear() % 4 ? undefined : 'foo bar';
const {dp, picker} = createDP(input, {beforeShowYear});
const viewSwitch = getViewSwitch(picker);
dp.show();
viewSwitch.click();
viewSwitch.click();
let cells = getCells(picker);
let fooCells = filterCells(cells, '.foo');
let barCells = filterCells(cells, '.bar');
expect(fooCells, 'to equal', [cells[1], cells[5], cells[9]]);
expect(barCells, 'to equal', fooCells);
expect(fooCells.map(el => el.textContent), 'to equal', ['2020', '2024', '2028']);
picker.querySelector('.next-btn').click();
cells = getCells(picker);
fooCells = filterCells(cells, '.foo');
barCells = filterCells(cells, '.bar');
expect(fooCells, 'to equal', [cells[3], cells[7], cells[11]]);
expect(barCells, 'to equal', fooCells);
expect(fooCells.map(el => el.textContent), 'to equal', ['2032', '2036', '2040']);
dp.destroy();
});
it('disables the year on years view when the return contains enabled: false', function () {
const beforeShowYear = date => ({enabled: !!(date.getFullYear() % 4)});
const {dp, picker} = createDP(input, {beforeShowYear});
const viewSwitch = getViewSwitch(picker);
dp.show();
viewSwitch.click();
viewSwitch.click();
let cells = getCells(picker);
let disabledCells = filterCells(cells, '.disabled');
expect(disabledCells, 'to equal', [cells[1], cells[5], cells[9]]);
picker.querySelector('.next-btn').click();
cells = getCells(picker);
disabledCells = filterCells(cells, '.disabled');
expect(disabledCells, 'to equal', [cells[3], cells[7], cells[11]]);
dp.destroy();
});
it('adds classes to the year on years view when the return contains space separated classes in the classes property', function () {
const beforeShowYear = date => date.getFullYear() % 4 ? undefined : {classes: 'foo bar'};
const {dp, picker} = createDP(input, {beforeShowYear});
const viewSwitch = getViewSwitch(picker);
dp.show();
viewSwitch.click();
viewSwitch.click();
let cells = getCells(picker);
let fooCells = filterCells(cells, '.foo');
let barCells = filterCells(cells, '.bar');
expect(fooCells, 'to equal', [cells[1], cells[5], cells[9]]);
expect(barCells, 'to equal', fooCells);
picker.querySelector('.next-btn').click();
cells = getCells(picker);
fooCells = filterCells(cells, '.foo');
barCells = filterCells(cells, '.bar');
expect(fooCells, 'to equal', [cells[3], cells[7], cells[11]]);
expect(barCells, 'to equal', fooCells);
dp.destroy();
});
it('uses custom content to the year cell when the return contains text/html in the content property', function () {
const beforeShowYear = (date) => {
const year = date.getFullYear();
return (year + Math.floor(year / 10) % 10) % 4 ? undefined : {content: '<i class="icn-x"></i>'};
};
const {dp, picker} = createDP(input, {beforeShowYear});
const viewSwitch = getViewSwitch(picker);
dp.show();
viewSwitch.click();
viewSwitch.click();
let cells = getCells(picker);
let ccCells = cells.filter(el => el.children.length > 0);
expect(ccCells, 'to equal', [cells[1], cells[5], cells[9]]);
ccCells.forEach((cell) => {
expect(cell.innerHTML, 'to be', '<i class="icn-x"></i>');
});
picker.querySelector('.next-btn').click();
cells = getCells(picker);
ccCells = cells.filter(el => el.children.length > 0);
expect(ccCells, 'to equal', [cells[2], cells[6], cells[10]]);
ccCells.forEach((cell) => {
expect(cell.innerHTML, 'to be', '<i class="icn-x"></i>');
});
dp.destroy();
});
it('can be updated with setOptions()', function () {
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
dp.setOptions({beforeShowYear: date => !!(date.getFullYear() % 4)});
dp.show();
viewSwitch.click();
viewSwitch.click();
let cells = getCells(picker);
let disabledCells = filterCells(cells, '.disabled');
expect(disabledCells, 'to equal', [cells[1], cells[5], cells[9]]);
dp.hide();
dp.setOptions({beforeShowYear: null});
dp.show();
viewSwitch.click();
viewSwitch.click();
cells = getCells(picker);
disabledCells = filterCells(cells, '.disabled');
expect(disabledCells, 'to equal', []);
dp.destroy();
});
});
describe('beforeShowDecade', function () {
it('disables the decade on decades view when it returns false', function () {
const beforeShowDecade = date => !!((date.getFullYear() / 10) % 4);
const {dp, picker} = createDP(input, {beforeShowDecade});
const viewSwitch = getViewSwitch(picker);
dp.show();
viewSwitch.click();
viewSwitch.click();
viewSwitch.click();
let cells = getCells(picker);
let disabledCells = filterCells(cells, '.disabled');
expect(disabledCells, 'to equal', [cells[1], cells[5], cells[9]]);
expect(disabledCells.map(el => el.textContent), 'to equal', ['2000', '2040', '2080',]);
picker.querySelector('.next-btn').click();
cells = getCells(picker);
disabledCells = filterCells(cells, '.disabled');
expect(disabledCells, 'to equal', [cells[3], cells[7], cells[11]]);
expect(disabledCells.map(el => el.textContent), 'to equal', ['2120', '2160', '2200']);
dp.destroy();
});
it('adds classes to the decade on decades view when it returns spece separated classes', function () {
const beforeShowDecade = date => (date.getFullYear() / 10) % 4 ? undefined : 'foo bar';
const {dp, picker} = createDP(input, {beforeShowDecade});
const viewSwitch = getViewSwitch(picker);
dp.show();
viewSwitch.click();
viewSwitch.click();
viewSwitch.click();
let cells = getCells(picker);
let fooCells = filterCells(cells, '.foo');
let barCells = filterCells(cells, '.bar');
expect(fooCells, 'to equal', [cells[1], cells[5], cells[9]]);
expect(barCells, 'to equal', fooCells);
expect(fooCells.map(el => el.textContent), 'to equal', ['2000', '2040', '2080']);
picker.querySelector('.next-btn').click();
cells = getCells(picker);
fooCells = filterCells(cells, '.foo');
barCells = filterCells(cells, '.bar');
expect(fooCells, 'to equal', [cells[3], cells[7], cells[11]]);
expect(barCells, 'to equal', fooCells);
expect(fooCells.map(el => el.textContent), 'to equal', ['2120', '2160', '2200']);
dp.destroy();
});
it('disables the decade on decades view when the return contains enabled: false', function () {
const beforeShowDecade = date => ({enabled: !!((date.getFullYear() / 10) % 4)});
const {dp, picker} = createDP(input, {beforeShowDecade});
const viewSwitch = getViewSwitch(picker);
dp.show();
viewSwitch.click();
viewSwitch.click();
viewSwitch.click();
let cells = getCells(picker);
let disabledCells = filterCells(cells, '.disabled');
expect(disabledCells, 'to equal', [cells[1], cells[5], cells[9]]);
picker.querySelector('.next-btn').click();
cells = getCells(picker);
disabledCells = filterCells(cells, '.disabled');
expect(disabledCells, 'to equal', [cells[3], cells[7], cells[11]]);
dp.destroy();
});
it('adds classes to the decade on decades view when the return contains space separated classes in the classes property', function () {
const beforeShowDecade = date => (date.getFullYear() / 10) % 4 ? undefined : {classes: 'foo bar'};
const {dp, picker} = createDP(input, {beforeShowDecade});
const viewSwitch = getViewSwitch(picker);
dp.show();
viewSwitch.click();
viewSwitch.click();
viewSwitch.click();
let cells = getCells(picker);
let fooCells = filterCells(cells, '.foo');
let barCells = filterCells(cells, '.bar');
expect(fooCells, 'to equal', [cells[1], cells[5], cells[9]]);
expect(barCells, 'to equal', fooCells);
picker.querySelector('.next-btn').click();
cells = getCells(picker);
fooCells = filterCells(cells, '.foo');
barCells = filterCells(cells, '.bar');
expect(fooCells, 'to equal', [cells[3], cells[7], cells[11]]);
expect(barCells, 'to equal', fooCells);
dp.destroy();
});
it('uses custom content to the decade cell when the return contains text/html in the content property', function () {
const beforeShowDecade = (date) => {
const dec = date.getFullYear() / 10;
return (dec + Math.floor(dec / 10) % 10) % 5 ? undefined : {content: '<strong>X</strong>'};
};
const {dp, picker} = createDP(input, {beforeShowDecade});
const viewSwitch = getViewSwitch(picker);
dp.show();
viewSwitch.click();
viewSwitch.click();
viewSwitch.click();
let cells = getCells(picker);
let ccCells = cells.filter(el => el.children.length > 0);
expect(ccCells, 'to equal', [cells[1], cells[6]]);
ccCells.forEach((cell) => {
expect(cell.innerHTML, 'to be', '<strong>X</strong>');
});
picker.querySelector('.next-btn').click();
cells = getCells(picker);
ccCells = cells.filter(el => el.children.length > 0);
expect(ccCells, 'to equal', [cells[5], cells[10]]);
ccCells.forEach((cell) => {
expect(cell.innerHTML, 'to be', '<strong>X</strong>');
});
dp.destroy();
});
it('can be updated with setOptions()', function () {
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
dp.setOptions({beforeShowDecade: date => !!((date.getFullYear() / 10) % 4)});
dp.show();
viewSwitch.click();
viewSwitch.click();
viewSwitch.click();
let cells = getCells(picker);
let disabledCells = filterCells(cells, '.disabled');
expect(disabledCells, 'to equal', [cells[1], cells[5], cells[9]]);
dp.hide();
dp.setOptions({beforeShowDecade: null});
dp.show();
viewSwitch.click();
viewSwitch.click();
viewSwitch.click();
cells = getCells(picker);
disabledCells = filterCells(cells, '.disabled');
expect(disabledCells, 'to equal', []);
dp.destroy();
});
});
});

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,383 @@
describe('options - buttons', function () {
let clock;
let input;
beforeEach(function () {
clock = sinon.useFakeTimers({now: new Date(2020, 1, 14)});
input = document.createElement('input');
testContainer.appendChild(input);
});
afterEach(function () {
testContainer.removeChild(input);
clock.restore();
});
describe('clearBtn', function () {
it('displays a button to clear the selection when true', function () {
const {dp, picker} = createDP(input, {clearBtn: true});
const [viewSwitch, clearBtn] = getParts(picker, ['.view-switch', '.clear-btn']);
dp.show();
expect(isVisible(clearBtn), 'to be true');
expect(clearBtn.textContent, 'to be', 'Clear');
// months view
viewSwitch.click();
expect(isVisible(clearBtn), 'to be true');
// years view
viewSwitch.click();
expect(isVisible(clearBtn), 'to be true');
// decades view
viewSwitch.click();
expect(isVisible(clearBtn), 'to be true');
dp.destroy();
});
it('can be updated with setOptions()', function () {
const {dp, picker} = createDP(input);
dp.setOptions({clearBtn: true});
dp.show();
const clearBtn = picker.querySelector('.clear-btn');
expect(isVisible(clearBtn), 'to be true');
dp.setOptions({clearBtn: false});
expect(isVisible(clearBtn), 'to be false');
dp.destroy();
});
describe('clear button', function () {
let dp;
let picker;
let clearBtn;
beforeEach(function () {
({dp, picker} = createDP(input, {clearBtn: true}));
clearBtn = picker.querySelector('.clear-btn');
dp.show();
});
afterEach(function () {
dp.destroy();
});
it('clears the selection', function () {
dp.setDate('2/14/2020');
clearBtn.click();
expect(dp.dates, 'to equal', []);
expect(input.value, 'to be', '');
const viewSwitch = getViewSwitch(picker);
// months view
dp.setDate('2/14/2020');
viewSwitch.click();
clearBtn.click();
expect(dp.dates, 'to equal', []);
// years view
dp.setDate('2/14/2020');
viewSwitch.click();
clearBtn.click();
expect(dp.dates, 'to equal', []);
// decades view
dp.setDate('2/14/2020');
viewSwitch.click();
clearBtn.click();
expect(dp.dates, 'to equal', []);
});
it('hides the picker as well when autohide = true', function () {
dp.setDate('2/14/2020');
dp.setOptions({autohide: true});
clearBtn.click();
expect(isVisible(picker), 'to be false');
});
});
});
describe('todayBtn', function () {
it('displays a button to change the view date to current date when true', function () {
const {dp, picker} = createDP(input, {todayBtn: true});
const [viewSwitch, todayBtn] = getParts(picker, ['.view-switch', '.today-btn']);
dp.show();
expect(isVisible(todayBtn), 'to be true');
expect(todayBtn.textContent, 'to be', 'Today');
// months view
viewSwitch.click();
expect(isVisible(todayBtn), 'to be true');
// years view
viewSwitch.click();
expect(isVisible(todayBtn), 'to be true');
// decades view
viewSwitch.click();
expect(isVisible(todayBtn), 'to be true');
dp.destroy();
});
it('today will be disabled if the current date is out of the range of minDate/maxDate', function () {
const {dp, picker} = createDP(input, {todayBtn: true});
const todayBtn = picker.querySelector('.today-btn');
dp.show();
expect(todayBtn.disabled, 'to be false');
dp.setOptions({minDate: '2/20/2020'});
expect(todayBtn.disabled, 'to be true');
dp.setOptions({minDate: null, maxDate: '2/10/2020'});
expect(todayBtn.disabled, 'to be true');
dp.setOptions({minDate: '2/1/2020', maxDate: '2/29/2020'});
expect(todayBtn.disabled, 'to be false');
dp.destroy();
});
it('can be updated with setOptions()', function () {
const {dp, picker} = createDP(input);
dp.setOptions({todayBtn: true});
dp.show();
const todayBtn = picker.querySelector('.today-btn');
expect(isVisible(todayBtn), 'to be true');
dp.setOptions({todayBtn: false});
expect(isVisible(todayBtn), 'to be false');
dp.setOptions({todayBtn: 'true'});
expect(isVisible(todayBtn), 'to be true');
dp.destroy();
});
});
describe('todayBtnMode', function () {
let dp;
let picker;
let viewSwitch;
let todayBtn;
let cells;
beforeEach(function () {
({dp, picker} = createDP(input, {todayBtn: true}));
[viewSwitch, todayBtn] = getParts(picker, ['.view-switch', '.today-btn']);
dp.show();
});
afterEach(function () {
dp.destroy();
});
it('specifies the behavior of the today buton', function () {
const date = dateValue(2020, 1, 11);
// defualt to 0: focus-on (change view date)
dp.setDate(date);
todayBtn.click();
cells = getCells(picker);
expect(cells[19].textContent, 'to be', '14');
expect(cells[19].classList.contains('focused'), 'to be true');
expect(cells[16].classList.contains('selected'), 'to be true');
expect(dp.dates, 'to equal', [date]);
dp.destroy();
// 1: select (change the selection)
({dp, picker} = createDP(input, {todayBtn: true, todayBtnMode: 1}));
todayBtn = picker.querySelector('.today-btn');
dp.setDate(date);
dp.show();
todayBtn.click();
cells = getCells(picker);
expect(cells[19].textContent, 'to be', '14');
expect(cells[19].classList.contains('focused'), 'to be true');
expect(cells[19].classList.contains('selected'), 'to be true');
expect(dp.dates, 'to equal', [dateValue(2020, 1, 14)]);
});
it('can be updated with setOptions()', function () {
const date = dateValue(2020, 1, 11);
dp.setDate(date);
dp.setOptions({todayBtnMode: 1});
todayBtn.click();
cells = getCells(picker);
expect(cells[19].textContent, 'to be', '14');
expect(cells[19].classList.contains('focused'), 'to be true');
expect(cells[19].classList.contains('selected'), 'to be true');
expect(dp.dates, 'to equal', [dateValue(2020, 1, 14)]);
dp.setDate(date);
dp.setOptions({todayBtnMode: 0});
todayBtn.click();
expect(cells[19].textContent, 'to be', '14');
expect(cells[19].classList.contains('focused'), 'to be true');
expect(cells[16].classList.contains('selected'), 'to be true');
expect(dp.dates, 'to equal', [date]);
});
describe('today button', function () {
it('changes the view date to the current date when todayBtnMode = 0', function () {
dp.setDate('4/22/2020');
todayBtn.click();
expect(viewSwitch.textContent, 'to be', 'February 2020');
cells = getCells(picker);
expect(cells[19].textContent, 'to be', '14');
expect(cells[19].classList.contains('focused'), 'to be true');
expect(cells.find(el => el.classList.contains('selected')), 'to be undefined');
expect(dp.dates, 'to equal', [dateValue(2020, 3, 22)]);
expect(input.value, 'to be', '04/22/2020');
dp.setDate({clear: true});
});
it('also changes the view to days view when todayBtnMode = 0', function () {
// months view
dp.setDate('4/22/2020');
viewSwitch.click();
todayBtn.click();
expect(viewSwitch.textContent, 'to be', 'February 2020');
// years view
dp.setDate({clear: true});
dp.setDate('4/22/2020');
viewSwitch.click();
viewSwitch.click();
todayBtn.click();
expect(viewSwitch.textContent, 'to be', 'February 2020');
// decades view
dp.setDate({clear: true});
dp.setDate('4/22/2020');
viewSwitch.click();
viewSwitch.click();
viewSwitch.click();
todayBtn.click();
expect(viewSwitch.textContent, 'to be', 'February 2020');
dp.setDate({clear: true});
});
it('changes the selection to the current date when todayBtnMode = 1', function () {
dp.setOptions({todayBtnMode: 1});
dp.setDate('4/22/2020');
todayBtn.click();
expect(viewSwitch.textContent, 'to be', 'February 2020');
cells = getCells(picker);
expect(cells[19].textContent, 'to be', '14');
expect(cells[19].classList.contains('focused'), 'to be true');
expect(cells[19].classList.contains('selected'), 'to be true');
expect(dp.dates, 'to equal', [dateValue(2020, 1, 14)]);
expect(input.value, 'to be', '02/14/2020');
dp.setDate({clear: true});
dp.setDate('4/22/2020');
viewSwitch.click();
viewSwitch.click();
todayBtn.click();
expect(viewSwitch.textContent, 'to be', 'February 2020');
expect(dp.dates, 'to equal', [dateValue(2020, 1, 14)]);
dp.setDate({clear: true});
});
it('also hides the picker when todayBtnMode = 1 and autohide = true', function () {
dp.setOptions({todayBtnMode: 1, autohide: true});
dp.setDate('4/22/2020');
todayBtn.click();
expect(isVisible(picker), 'to be false');
dp.setDate({clear: true});
});
it('always changes the view to current date\'s days view when todayBtnMode = 1', function () {
const nextBtn = picker.querySelector('.next-btn');
dp.setOptions({todayBtnMode: 1});
// after moving other month or view while the current date is selected already
// (issue #11)
todayBtn.click();
nextBtn.click();
todayBtn.click();
cells = getCells(picker);
expect(viewSwitch.textContent, 'to be', 'February 2020');
expect(cells[19].classList.contains('focused'), 'to be true');
expect(cells[19].classList.contains('selected'), 'to be true');
expect(dp.dates, 'to equal', [dateValue(2020, 1, 14)]);
viewSwitch.click();
nextBtn.click();
todayBtn.click();
cells = getCells(picker);
expect(viewSwitch.textContent, 'to be', 'February 2020');
expect(cells[19].classList.contains('focused'), 'to be true');
expect(cells[19].classList.contains('selected'), 'to be true');
expect(dp.dates, 'to equal', [dateValue(2020, 1, 14)]);
viewSwitch.click();
viewSwitch.click();
nextBtn.click();
nextBtn.click();
todayBtn.click();
cells = getCells(picker);
expect(viewSwitch.textContent, 'to be', 'February 2020');
expect(cells[19].classList.contains('focused'), 'to be true');
expect(cells[19].classList.contains('selected'), 'to be true');
expect(dp.dates, 'to equal', [dateValue(2020, 1, 14)]);
// when current date is deslected by toggling in multi-date mode
dp.setOptions({maxNumberOfDates: 3});
nextBtn.click();
getCells(picker)[20].click();
todayBtn.click();
cells = getCells(picker);
expect(viewSwitch.textContent, 'to be', 'February 2020');
expect(cells[19].classList.contains('focused'), 'to be true');
expect(cells[19].classList.contains('selected'), 'to be false');
expect(dp.dates, 'to equal', [dateValue(2020, 2, 21)]);
nextBtn.click();
todayBtn.click();
cells = getCells(picker);
expect(viewSwitch.textContent, 'to be', 'February 2020');
expect(cells[19].classList.contains('selected'), 'to be true');
expect(dp.dates, 'to equal', [dateValue(2020, 2, 21), dateValue(2020, 1, 14)]);
viewSwitch.click();
nextBtn.click();
todayBtn.click();
cells = getCells(picker);
expect(viewSwitch.textContent, 'to be', 'February 2020');
expect(cells[19].classList.contains('focused'), 'to be true');
expect(cells[19].classList.contains('selected'), 'to be false');
expect(dp.dates, 'to equal', [dateValue(2020, 2, 21)]);
dp.setDate({clear: true});
});
});
});
});

View File

@ -0,0 +1,802 @@
describe('options - date restrictions', function () {
const getDisabled = cells => filterCells(cells, '.disabled').map(el => [el, el.textContent]);
let input;
beforeEach(function () {
input = document.createElement('input');
testContainer.appendChild(input);
});
afterEach(function () {
testContainer.removeChild(input);
});
describe('datesDisabled', function () {
let clock;
beforeEach(function () {
clock = sinon.useFakeTimers({now: new Date(2020, 1, 14)});
});
afterEach(function () {
clock.restore();
});
it('specifies unselectable dates', function () {
const dp = new Datepicker(input, {
datesDisabled: [new Date(2020, 1, 12), '2/13/2020', new Date(2020, 1, 13), '2/20/2020'],
});
const picker = document.querySelector('.datepicker');
dp.show();
expect(picker.querySelector('.prev-btn').disabled, 'to be false');
expect(picker.querySelector('.next-btn').disabled, 'to be false');
let cells = getCells(picker);
expect(getDisabled(cells), 'to equal', [
[cells[17], '12'],
[cells[18], '13'],
[cells[25], '20'],
]);
cells[17].click();
expect(dp.dates, 'to equal', []);
expect(input.value, 'to be', '');
expect(filterCells(cells, '.selected'), 'to equal', []);
dp.setDate(new Date(2020, 1, 12));
expect(dp.dates, 'to equal', []);
expect(input.value, 'to be', '');
expect(filterCells(cells, '.selected'), 'to equal', []);
input.value = '2/12/2020';
dp.update();
expect(dp.dates, 'to equal', []);
expect(input.value, 'to be', '2/12/2020');
expect(filterCells(cells, '.selected'), 'to equal', []);
cells[16].click();
expect(dp.dates, 'to equal', [dateValue(2020, 1, 11)]);
expect(input.value, 'to be', '02/11/2020');
expect(filterCells(cells, '.selected'), 'to equal', [cells[16]]);
dp.enterEditMode();
input.value = '2/12/2020';
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(dp.dates, 'to equal', [dateValue(2020, 1, 11)]);
expect(input.value, 'to be', '2/12/2020');
expect(filterCells(cells, '.selected'), 'to equal', [cells[16]]);
dp.destroy();
});
it('makes the picker prevent those dates becoming view date', function () {
const dp = new Datepicker(input, {
datesDisabled: ['2/11/2020', '2/12/2020', '2/13/2020', '2/20/2020'],
});
const picker = document.querySelector('.datepicker');
const cells = getCells(picker);
dp.show();
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
expect(filterCells(cells, '.focused'), 'to equal', [cells[15]]);
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
// on 5th
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
// on 27th
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(filterCells(cells, '.focused'), 'to equal', [cells[24]]);
// on 19th
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(filterCells(cells, '.focused'), 'to equal', [cells[15]]);
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
// on 4th
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
dp.destroy();
});
it('can be updated with setOptions()', function () {
const {dp, picker} = createDP(input);
dp.setOptions({datesDisabled: [new Date(2020, 1, 11), new Date(2020, 1, 26)]});
dp.show();
let cells = getCells(picker);
expect(getDisabled(cells), 'to equal', [
[cells[16], '11'],
[cells[31], '26'],
]);
dp.setOptions({datesDisabled: []});
cells = getCells(picker);
expect(getDisabled(cells), 'to equal', []);
dp.destroy();
});
});
describe('daysOfWeekDisabled', function () {
let clock;
beforeEach(function () {
clock = sinon.useFakeTimers({now: new Date(2020, 1, 14)});
});
afterEach(function () {
clock.restore();
});
it('specifies unselectable days of week', function () {
const {dp, picker} = createDP(input, {daysOfWeekDisabled: [0, 6]});
dp.show();
expect(picker.querySelector('.prev-btn').disabled, 'to be false');
expect(picker.querySelector('.next-btn').disabled, 'to be false');
let cells = getCells(picker);
expect(getDisabled(cells), 'to equal', [
[cells[0], '26'],
[cells[6], '1'],
[cells[7], '2'],
[cells[13], '8'],
[cells[14], '9'],
[cells[20], '15'],
[cells[21], '16'],
[cells[27], '22'],
[cells[28], '23'],
[cells[34], '29'],
[cells[35], '1'],
[cells[41], '7'],
]);
cells[14].click();
expect(dp.dates, 'to equal', []);
expect(input.value, 'to be', '');
expect(filterCells(cells, '.selected'), 'to equal', []);
dp.setDate(new Date(2020, 1, 9));
expect(dp.dates, 'to equal', []);
expect(input.value, 'to be', '');
expect(filterCells(cells, '.selected'), 'to equal', []);
input.value = '2/9/2020';
dp.update();
expect(dp.dates, 'to equal', []);
expect(input.value, 'to be', '2/9/2020');
expect(filterCells(cells, '.selected'), 'to equal', []);
cells[15].click();
expect(dp.dates, 'to equal', [dateValue(2020, 1, 10)]);
expect(input.value, 'to be', '02/10/2020');
expect(filterCells(cells, '.selected'), 'to equal', [cells[15]]);
dp.enterEditMode();
input.value = '2/9/2020';
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(dp.dates, 'to equal', [dateValue(2020, 1, 10)]);
expect(input.value, 'to be', '2/9/2020');
expect(filterCells(cells, '.selected'), 'to equal', [cells[15]]);
dp.destroy();
});
it('makes the picker prevent those dates becoming view date', function () {
const {dp, picker} = createDP(input, {daysOfWeekDisabled: [0, 6]});
const cells = getCells(picker);
dp.show();
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
expect(filterCells(cells, '.focused'), 'to equal', [cells[22]]);
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
// on 7th
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
expect(filterCells(cells, '.focused'), 'to equal', [cells[15]]);
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
expect(filterCells(cells, '.focused'), 'to equal', [cells[12]]);
dp.destroy();
});
it('can be updated with setOptions()', function () {
const {dp, picker} = createDP(input);
dp.setOptions({daysOfWeekDisabled: [4]});
dp.show();
let cells = getCells(picker);
expect(getDisabled(cells), 'to equal', [
[cells[4], '30'],
[cells[11], '6'],
[cells[18], '13'],
[cells[25], '20'],
[cells[32], '27'],
[cells[39], '5'],
]);
dp.setOptions({daysOfWeekDisabled: []});
cells = getCells(picker);
expect(getDisabled(cells), 'to equal', []);
dp.destroy();
});
});
describe('maxDate', function () {
let clock;
beforeEach(function () {
clock = sinon.useFakeTimers({now: new Date(2020, 1, 14)});
});
afterEach(function () {
clock.restore();
});
it('specifies the maximum selectable date', function () {
const {dp, picker} = createDP(input, {maxDate: new Date(2020, 1, 25)});
const viewSwitch = getViewSwitch(picker);
dp.show();
let cells = getCells(picker);
expect(getDisabled(cells), 'to equal', [
[cells[31], '26'],
[cells[32], '27'],
[cells[33], '28'],
[cells[34], '29'],
[cells[35], '1'],
[cells[36], '2'],
[cells[37], '3'],
[cells[38], '4'],
[cells[39], '5'],
[cells[40], '6'],
[cells[41], '7'],
]);
viewSwitch.click();
cells = getCells(picker);
expect(getDisabled(cells), 'to equal', [
[cells[2], 'Mar'],
[cells[3], 'Apr'],
[cells[4], 'May'],
[cells[5], 'Jun'],
[cells[6], 'Jul'],
[cells[7], 'Aug'],
[cells[8], 'Sep'],
[cells[9], 'Oct'],
[cells[10], 'Nov'],
[cells[11], 'Dec'],
]);
viewSwitch.click();
cells = getCells(picker);
expect(getDisabled(cells), 'to equal', [
[cells[2], '2021'],
[cells[3], '2022'],
[cells[4], '2023'],
[cells[5], '2024'],
[cells[6], '2025'],
[cells[7], '2026'],
[cells[8], '2027'],
[cells[9], '2028'],
[cells[10], '2029'],
[cells[11], '2030'],
]);
viewSwitch.click();
cells = getCells(picker);
expect(getDisabled(cells), 'to equal', [
[cells[4], '2030'],
[cells[5], '2040'],
[cells[6], '2050'],
[cells[7], '2060'],
[cells[8], '2070'],
[cells[9], '2080'],
[cells[10], '2090'],
[cells[11], '2100'],
]);
dp.hide();
dp.show();
cells = getCells(picker);
cells[31].click();
expect(dp.dates, 'to equal', []);
expect(input.value, 'to be', '');
expect(filterCells(cells, '.selected'), 'to equal', []);
dp.setDate(new Date(2020, 1, 26));
expect(dp.dates, 'to equal', []);
expect(input.value, 'to be', '');
expect(filterCells(cells, '.selected'), 'to equal', []);
input.value = '2/26/2020';
dp.update();
expect(dp.dates, 'to equal', []);
expect(input.value, 'to be', '2/26/2020');
expect(filterCells(cells, '.selected'), 'to equal', []);
cells[30].click();
expect(dp.dates, 'to equal', [dateValue(2020, 1, 25)]);
expect(input.value, 'to be', '02/25/2020');
expect(filterCells(cells, '.selected'), 'to equal', [cells[30]]);
dp.enterEditMode();
input.value = '2/26/2020';
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(dp.dates, 'to equal', [dateValue(2020, 1, 25)]);
expect(input.value, 'to be', '2/26/2020');
expect(filterCells(cells, '.selected'), 'to equal', [cells[30]]);
dp.destroy();
});
it('makes the picker disallow to navigate to after the max date', function () {
const {dp, picker} = createDP(input, {maxDate: '2/14/2020'});
const [viewSwitch, prevBtn, nextBtn] = getParts(picker, ['.view-switch', '.prev-btn', '.next-btn']);
dp.show();
expect(prevBtn.disabled, 'to be false');
expect(nextBtn.disabled, 'to be true');
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
simulant.fire(input, 'keydown', {key: 'ArrowRight', ctrlKey: true});
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
expect(filterCells(cells, '.focused'), 'to equal', [cells[13]]);
prevBtn.click();
expect(prevBtn.disabled, 'to be false');
expect(nextBtn.disabled, 'to be false');
// move to Jan 22nd
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
nextBtn.click();
// view date is limited to the max date
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
// the same goes for ctrl + ArrowRight key
prevBtn.click();
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
simulant.fire(input, 'keydown', {key: 'ArrowRight', ctrlKey: true});
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
// months view
viewSwitch.click();
expect(prevBtn.disabled, 'to be false');
expect(nextBtn.disabled, 'to be true');
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
// on prev year's Nov
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[10]]);
prevBtn.click();
expect(prevBtn.disabled, 'to be false');
expect(nextBtn.disabled, 'to be false');
// move to Mar
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
nextBtn.click();
// view date is limited to the Feb
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
// the same goes for ctrl + ArrowRight key
prevBtn.click();
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
simulant.fire(input, 'keydown', {key: 'ArrowRight', ctrlKey: true});
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
// years view
viewSwitch.click();
expect(prevBtn.disabled, 'to be false');
expect(nextBtn.disabled, 'to be true');
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
// on 2017
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[8]]);
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
prevBtn.click();
expect(prevBtn.disabled, 'to be false');
expect(nextBtn.disabled, 'to be false');
// move to 2011
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
nextBtn.click();
// view year is limited to 2020
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
// the same goes for ctrl + ArrowRight key
prevBtn.click();
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
simulant.fire(input, 'keydown', {key: 'ArrowRight', ctrlKey: true});
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
// decades view
viewSwitch.click();
expect(prevBtn.disabled, 'to be false');
expect(nextBtn.disabled, 'to be true');
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[3]]);
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
// on 1990
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[10]]);
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
prevBtn.click();
expect(prevBtn.disabled, 'to be false');
expect(nextBtn.disabled, 'to be false');
// move to 1930
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
nextBtn.click();
// view decade is limited to 2020
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[3]]);
// the same goes for ctrl + ArrowRight key
prevBtn.click();
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
simulant.fire(input, 'keydown', {key: 'ArrowRight', ctrlKey: true});
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[3]]);
dp.destroy();
});
it('can be updated with setOptions()', function () {
const {dp, picker} = createDP(input);
dp.setOptions({maxDate: new Date(2020, 1, 28)});
dp.show();
let cells = getCells(picker);
expect(getDisabled(cells), 'to equal', [
[cells[34], '29'],
[cells[35], '1'],
[cells[36], '2'],
[cells[37], '3'],
[cells[38], '4'],
[cells[39], '5'],
[cells[40], '6'],
[cells[41], '7'],
]);
dp.setOptions({maxDate: null});
cells = getCells(picker);
expect(getDisabled(cells), 'to equal', []);
dp.destroy();
});
});
describe('minDate', function () {
let clock;
beforeEach(function () {
clock = sinon.useFakeTimers({now: new Date(2022, 6, 14)});
});
afterEach(function () {
clock.restore();
});
it('specifies the minimum selectable date', function () {
const {dp, picker} = createDP(input, {minDate: new Date(2022, 6, 4)});
const viewSwitch = getViewSwitch(picker);
dp.show();
let cells = getCells(picker);
expect(getDisabled(cells), 'to equal', [
[cells[0], '26'],
[cells[1], '27'],
[cells[2], '28'],
[cells[3], '29'],
[cells[4], '30'],
[cells[5], '1'],
[cells[6], '2'],
[cells[7], '3'],
]);
viewSwitch.click();
cells = getCells(picker);
expect(getDisabled(cells), 'to equal', [
[cells[0], 'Jan'],
[cells[1], 'Feb'],
[cells[2], 'Mar'],
[cells[3], 'Apr'],
[cells[4], 'May'],
[cells[5], 'Jun'],
]);
viewSwitch.click();
cells = getCells(picker);
expect(getDisabled(cells), 'to equal', [
[cells[0], '2019'],
[cells[1], '2020'],
[cells[2], '2021'],
]);
viewSwitch.click();
cells = getCells(picker);
expect(getDisabled(cells), 'to equal', [
[cells[0], '1990'],
[cells[1], '2000'],
[cells[2], '2010'],
]);
dp.hide();
dp.show();
cells = getCells(picker);
cells[7].click();
expect(dp.dates, 'to equal', []);
expect(input.value, 'to be', '');
expect(filterCells(cells, '.selected'), 'to equal', []);
dp.setDate(new Date(2022, 6, 3));
expect(dp.dates, 'to equal', []);
expect(input.value, 'to be', '');
expect(filterCells(cells, '.selected'), 'to equal', []);
input.value = '7/3/2022';
dp.update();
expect(dp.dates, 'to equal', []);
expect(input.value, 'to be', '7/3/2022');
expect(filterCells(cells, '.selected'), 'to equal', []);
cells[8].click();
expect(dp.dates, 'to equal', [dateValue(2022, 6, 4)]);
expect(input.value, 'to be', '07/04/2022');
expect(filterCells(cells, '.selected'), 'to equal', [cells[8]]);
dp.enterEditMode();
input.value = '7/3/2022';
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(dp.dates, 'to equal', [dateValue(2022, 6, 4)]);
expect(input.value, 'to be', '7/3/2022');
expect(filterCells(cells, '.selected'), 'to equal', [cells[8]]);
dp.destroy();
});
it('makes the picker disallow to navigate to before the min date', function () {
const {dp, picker} = createDP(input, {minDate: '7/14/2022'});
const [viewSwitch, prevBtn, nextBtn] = getParts(picker, ['.view-switch', '.prev-btn', '.next-btn']);
dp.show();
expect(prevBtn.disabled, 'to be true');
expect(nextBtn.disabled, 'to be false');
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[18]]);
simulant.fire(input, 'keydown', {key: 'ArrowLeft', ctrlKey: true});
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[18]]);
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
expect(filterCells(cells, '.focused'), 'to equal', [cells[24]]);
nextBtn.click();
expect(prevBtn.disabled, 'to be false');
expect(nextBtn.disabled, 'to be false');
// move to Aug 13th
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
prevBtn.click();
// view date is limited to min date
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[18]]);
// the same goes for ctrl + ArrowLeft key
prevBtn.click();
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
simulant.fire(input, 'keydown', {key: 'ArrowLeft', ctrlKey: true});
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[18]]);
// months view
viewSwitch.click();
expect(prevBtn.disabled, 'to be true');
expect(nextBtn.disabled, 'to be false');
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[6]]);
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
// on Oct
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[9]]);
nextBtn.click();
expect(prevBtn.disabled, 'to be false');
expect(nextBtn.disabled, 'to be false');
// move to Jun
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
prevBtn.click();
// view date is limited to Jul
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[6]]);
// the same goes for ctrl + ArrowLeft key
prevBtn.click();
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
simulant.fire(input, 'keydown', {key: 'ArrowLeft', ctrlKey: true});
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[6]]);
// years view
viewSwitch.click();
expect(prevBtn.disabled, 'to be true');
expect(nextBtn.disabled, 'to be false');
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[3]]);
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
// on 2025
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[6]]);
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
nextBtn.click();
expect(prevBtn.disabled, 'to be false');
expect(nextBtn.disabled, 'to be false');
// move to 2031
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
prevBtn.click();
// view year is limited to 2022
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[3]]);
// the same goes for ctrl + ArrowLeft key
prevBtn.click();
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
simulant.fire(input, 'keydown', {key: 'ArrowLeft', ctrlKey: true});
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[3]]);
// decades view
viewSwitch.click();
expect(prevBtn.disabled, 'to be true');
expect(nextBtn.disabled, 'to be false');
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[3]]);
simulant.fire(input, 'keydown', {key: 'ArrowDown'});
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
// on 2050
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[6]]);
simulant.fire(input, 'keydown', {key: 'ArrowRight'});
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
nextBtn.click();
expect(prevBtn.disabled, 'to be false');
expect(nextBtn.disabled, 'to be false');
// move to 2110
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
prevBtn.click();
// view decade is limited to 2020
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[3]]);
// the same goes for ctrl + ArrowLeft key
prevBtn.click();
simulant.fire(input, 'keydown', {key: 'ArrowUp'});
simulant.fire(input, 'keydown', {key: 'ArrowLeft', ctrlKey: true});
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[3]]);
dp.destroy();
});
it('can be updated with setOptions()', function () {
const {dp, picker} = createDP(input);
dp.setOptions({minDate: new Date(2022, 6, 2)});
dp.show();
let cells = getCells(picker);
expect(getDisabled(cells), 'to equal', [
[cells[0], '26'],
[cells[1], '27'],
[cells[2], '28'],
[cells[3], '29'],
[cells[4], '30'],
[cells[5], '1'],
]);
dp.setOptions({minDate: null});
cells = getCells(picker);
expect(getDisabled(cells), 'to equal', []);
dp.destroy();
});
});
});

281
node_modules/flowbite-datepicker/test/options/format.js generated vendored Normal file
View File

@ -0,0 +1,281 @@
describe('options - format & language', function () {
let clock;
let input;
beforeEach(function () {
clock = sinon.useFakeTimers({now: new Date(2020, 1, 14)});
input = document.createElement('input');
testContainer.appendChild(input);
});
afterEach(function () {
testContainer.removeChild(input);
clock.restore();
});
describe('format', function () {
it('specifies the date format used to parse/format the date string in input', function () {
const dp = new Datepicker(input, {format: 'yyyy-mm-dd'});
dp.setDate(new Date(2020, 1, 14));
expect(dp.dates, 'to equal', [dateValue(2020, 1, 14)]);
expect(input.value, 'to be', '2020-02-14');
input.value = '2020/4/22';
dp.update();
expect(dp.dates, 'to equal', [dateValue(2020, 3, 22)]);
expect(input.value, 'to be', '2020-04-22');
// when a date in a wrong format is given...
dp.setDate('2/14/2020');
expect(dp.dates, 'to equal', [dateValue(2, 13, 2020)]);
expect(input.value, 'to be', '0008-08-12');
input.value = '22/4/2020';
dp.update();
expect(dp.dates, 'to equal', [dateValue(22, 3, 2020)]);
expect(input.value, 'to be', '0027-10-11');
dp.destroy();
input.value = '';
});
it('custom parser/fomatter can be used by providing them as toValue/toDisplay of an object', function () {
const dp = new Datepicker(input, {
format: {
toDisplay(date) {
return new Date(date.getTime() - date.getTimezoneOffset() * 60000).toISOString()
.slice(0, 10)
.replace(/-/g, '');
},
toValue(date) {
const parts = [
parseInt(date.slice(0, 4), 10),
parseInt(date.slice(4, 6), 10) - 1,
parseInt(date.slice(6, 8), 10),
];
return dateValue(...parts);
},
},
});
dp.setDate(new Date(2020, 1, 14));
expect(dp.dates, 'to equal', [dateValue(2020, 1, 14)]);
expect(input.value, 'to be', '20200214');
input.value = '20200422';
dp.update();
expect(dp.dates, 'to equal', [dateValue(2020, 3, 22)]);
expect(input.value, 'to be', '20200422');
dp.destroy();
input.value = '';
});
it('can be updated with setOptions()', function () {
const dp = new Datepicker(input);
dp.setOptions({format: 'd M, \'yy'});
dp.setDate('14/2/2020');
expect(dp.dates, 'to equal', [dateValue(2020, 1, 14)]);
expect(input.value, 'to be', '14 Feb, \'20');
dp.setOptions({format: 'mm/dd/yyyy'});
expect(input.value, 'to be', '02/14/2020');
input.value = '4/22/2020';
dp.update();
expect(dp.dates, 'to equal', [dateValue(2020, 3, 22)]);
expect(input.value, 'to be', '04/22/2020');
dp.destroy();
input.value = '';
});
});
describe('language', function () {
const getDayNames = picker => Array.from(picker.querySelectorAll('.dow')).map(el => el.textContent);
it('specifies the language used for the month/day names, today/clear buttons and the default format/weekStart', function () {
const locale = Datepicker.locales['zh-CN'];
const {dp, picker} = createDP(input, {language: 'zh-CN', todayBtn: true, clearBtn: true});
const viewSwitch = getViewSwitch(picker);
dp.setDate(new Date(2020, 1, 14));
dp.show();
expect(viewSwitch.textContent, 'to be', '2020年02月');
expect(input.value, 'to be', '2020-02-14');
expect(picker.querySelector('.today-btn').textContent, 'to be', locale.today);
expect(picker.querySelector('.clear-btn').textContent, 'to be', locale.clear);
const dayNames = locale.daysMin.slice(1);
dayNames.push(locale.daysMin[0]);
expect(getDayNames(picker), 'to equal', dayNames);
let cells = getCells(picker);
expect(cells[0].textContent, 'to be', '27');
expect(cells[5].textContent, 'to be', '1');
expect(cells[33].textContent, 'to be', '29');
expect(cells[41].textContent, 'to be', '8');
expect(filterCells(cells, '.selected'), 'to equal', [cells[18]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[18]]);
expect(cells[18].textContent, 'to be', '14');
viewSwitch.click();
expect(viewSwitch.textContent, 'to be', '2020');
cells = getCells(picker);
expect(Array.from(cells).map(el => el.textContent), 'to equal', locale.monthsShort);
cells[1].click();
input.value = '2020-4-22';
dp.update();
expect(viewSwitch.textContent, 'to be', '2020年04月');
expect(input.value, 'to be', '2020-04-22');
cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', [cells[23]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[23]]);
expect(cells[23].textContent, 'to be', '22');
dp.destroy();
input.value = '';
});
it('default format/weekStart in the locale are overriden by user-specified ones', function () {
const locale = Datepicker.locales['zh-CN'];
const {dp, picker} = createDP(input, {language: 'zh-CN', format: 'yyyy年mm月dd日', weekStart: 0});
const viewSwitch = getViewSwitch(picker);
dp.setDate(new Date(2020, 1, 14));
dp.show();
expect(viewSwitch.textContent, 'to be', '2020年02月');
expect(input.value, 'to be', '2020年02月14日');
expect(getDayNames(picker), 'to equal', locale.daysMin);
let cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', [cells[19]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
expect(cells[19].textContent, 'to be', '14');
dp.destroy();
input.value = '';
});
it('language code + tag not installed falls back to the language code without tag', function () {
const locale = Datepicker.locales.fr;
const {dp, picker} = createDP(input, {language: 'fr-CA', todayBtn: true, clearBtn: true});
const viewSwitch = getViewSwitch(picker);
dp.setDate(new Date(2020, 1, 14));
dp.show();
expect(viewSwitch.textContent, 'to be', 'février 2020');
expect(input.value, 'to be', '14/02/2020');
expect(picker.querySelector('.today-btn').textContent, 'to be', locale.today);
expect(picker.querySelector('.clear-btn').textContent, 'to be', locale.clear);
const dayNames = locale.daysMin.slice(1);
dayNames.push(locale.daysMin[0]);
expect(getDayNames(picker), 'to equal', dayNames);
dp.destroy();
input.value = '';
});
it('language code not installed falls back to "en"', function () {
const locale = Datepicker.locales.en;
const {dp, picker} = createDP(input, {language: 'it', todayBtn: true, clearBtn: true});
const viewSwitch = getViewSwitch(picker);
dp.setDate(new Date(2020, 1, 14));
dp.show();
expect(viewSwitch.textContent, 'to be', 'February 2020');
expect(input.value, 'to be', '02/14/2020');
expect(picker.querySelector('.today-btn').textContent, 'to be', locale.today);
expect(picker.querySelector('.clear-btn').textContent, 'to be', locale.clear);
expect(getDayNames(picker), 'to equal', locale.daysMin);
dp.destroy();
input.value = '';
});
it('can be updated with setOptions()', function () {
const {dp, picker} = createDP(input, {todayBtn: true, clearBtn: true});
const viewSwitch = getViewSwitch(picker);
let locale = Datepicker.locales['zh-CN'];
dp.setDate(new Date(2020, 1, 14));
dp.setOptions({language: 'zh-CN'});
dp.show();
expect(viewSwitch.textContent, 'to be', '2020年02月');
expect(input.value, 'to be', '2020-02-14');
expect(picker.querySelector('.today-btn').textContent, 'to be', locale.today);
expect(picker.querySelector('.clear-btn').textContent, 'to be', locale.clear);
let dayNames = locale.daysMin.slice(1);
dayNames.push(locale.daysMin[0]);
expect(getDayNames(picker), 'to equal', dayNames);
let cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', [cells[18]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[18]]);
expect(cells[18].textContent, 'to be', '14');
locale = Datepicker.locales.fr;
dp.setOptions({language: 'fr'});
expect(viewSwitch.textContent, 'to be', 'février 2020');
expect(input.value, 'to be', '14/02/2020');
expect(picker.querySelector('.today-btn').textContent, 'to be', locale.today);
expect(picker.querySelector('.clear-btn').textContent, 'to be', locale.clear);
dayNames = locale.daysMin.slice(1);
dayNames.push(locale.daysMin[0]);
expect(getDayNames(picker), 'to equal', dayNames);
cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', [cells[18]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[18]]);
expect(cells[18].textContent, 'to be', '14');
locale = Datepicker.locales.en;
dp.setOptions({language: 'en'});
expect(viewSwitch.textContent, 'to be', 'February 2020');
expect(input.value, 'to be', '02/14/2020');
expect(picker.querySelector('.today-btn').textContent, 'to be', locale.today);
expect(picker.querySelector('.clear-btn').textContent, 'to be', locale.clear);
expect(getDayNames(picker), 'to equal', locale.daysMin);
cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', [cells[19]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
expect(cells[19].textContent, 'to be', '14');
dp.destroy();
input.value = '';
});
it('user-specified format/weekStart other than old language\'s default are kept on being updated dynamically', function () {
const {dp, picker} = createDP(input, {language: 'zh-CN', format: 'yyyy/mm/dd', weekStart: 0});
dp.setDate(new Date(2020, 1, 14));
dp.show();
let locale = Datepicker.locales.fr;
dp.setOptions({language: 'fr'});
expect(input.value, 'to be', '2020/02/14');
expect(getDayNames(picker), 'to equal', locale.daysMin);
let cells = getCells(picker);
expect(filterCells(cells, '.selected'), 'to equal', [cells[19]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
expect(cells[19].textContent, 'to be', '14');
dp.destroy();
input.value = '';
});
});
});

View File

@ -0,0 +1,380 @@
describe('options - multi date', function () {
let clock;
let input;
beforeEach(function () {
clock = sinon.useFakeTimers({now: new Date(2020, 1, 14)});
input = document.createElement('input');
testContainer.appendChild(input);
});
afterEach(function () {
testContainer.removeChild(input);
clock.restore();
});
describe('maxNumberOfDates', function () {
it('specifies the muximum number of dates the datepicker accepts for the selection', function () {
let {dp, picker} = createDP(input, {maxNumberOfDates: 2});
dp.setDate('2/14/2020', '4/22/2020');
expect(dp.dates, 'to equal', [dateValue(2020, 1, 14), dateValue(2020, 3, 22)]);
expect(input.value, 'to be', '02/14/2020,04/22/2020');
// the dates come later win
dp.setDate('1/4/2020', '2/22/2020', '3/21/2020');
expect(dp.dates, 'to equal', [dateValue(2020, 1, 22), dateValue(2020, 2, 21)]);
expect(input.value, 'to be', '02/22/2020,03/21/2020');
// repeated dates are eliminated
dp.setDate('4/22/2020', '7/14/2020', '5/5/2020', '7/14/2020');
expect(dp.dates, 'to equal', [dateValue(2020, 6, 14), dateValue(2020, 4, 5)]);
expect(input.value, 'to be', '07/14/2020,05/05/2020');
dp.destroy();
input.value = '';
({dp, picker} = createDP(input, {maxNumberOfDates: 3}));
dp.show();
let cells = getCells(picker);
cells[19].click();
cells[9].click();
expect(dp.dates, 'to equal', [dateValue(2020, 1, 14), dateValue(2020, 1, 4)]);
expect(input.value, 'to be', '02/14/2020,02/04/2020');
expect(filterCells(cells, '.selected'), 'to equal', [cells[19], cells[9]]);
// view date is changed co the last selected item
expect(filterCells(cells, '.focused'), 'to equal', [cells[9]]);
input.value = '2/3/2020,2/22/2020';
dp.update();
expect(dp.dates, 'to equal', [dateValue(2020, 1, 3), dateValue(2020, 1, 22)]);
expect(input.value, 'to be', '02/03/2020,02/22/2020');
expect(filterCells(cells, '.selected'), 'to equal', [cells[8], cells[27]]);
// view date is changed co the last item of the selection
expect(filterCells(cells, '.focused'), 'to equal', [cells[27]]);
dp.destroy();
input.value = '';
({dp, picker} = createDP(input, {maxNumberOfDates: 3}));
dp.setDate('2/14/2020', '4/22/2020', '3/21/2020');
expect(dp.dates, 'to equal', [
dateValue(2020, 1, 14),
dateValue(2020, 3, 22),
dateValue(2020, 2, 21),
]);
expect(input.value, 'to be', '02/14/2020,04/22/2020,03/21/2020');
dp.destroy();
input.value = '';
({dp, picker} = createDP(input, {maxNumberOfDates: 3}));
dp.show();
getCells(picker)[1].click();
getCells(picker)[40].click();
cells = getCells(picker);
cells[19].click();
expect(dp.dates, 'to equal', [
dateValue(2020, 0, 27),
dateValue(2020, 1, 7),
dateValue(2020, 1, 14),
]);
expect(input.value, 'to be', '01/27/2020,02/07/2020,02/14/2020');
expect(filterCells(cells, '.selected'), 'to equal', [cells[1], cells[12], cells[19]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
input.value = '2/3/2020,2/22/2020';
dp.update();
expect(dp.dates, 'to equal', [dateValue(2020, 1, 3), dateValue(2020, 1, 22)]);
expect(input.value, 'to be', '02/03/2020,02/22/2020');
expect(filterCells(cells, '.selected'), 'to equal', [cells[8], cells[27]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[27]]);
// setting initial dates does not cuase error
// (issue #51)
dp.destroy();
input.value = '02/14/2020,04/22/2020,03/21/2020';
({dp, picker} = createDP(input, {maxNumberOfDates: 2}));
expect(dp.dates, 'to equal', [
dateValue(2020, 3, 22),
dateValue(2020, 2, 21),
]);
expect(input.value, 'to be', '04/22/2020,03/21/2020');
dp.destroy();
input.value = '';
});
it('makes the picker deselect the date when a selected date is clicked if value != 1', function () {
const {dp, picker} = createDP(input, {maxNumberOfDates: 3});
dp.show();
let cells = getCells(picker);
cells[19].click();
cells[12].click();
cells[19].click();
expect(dp.dates, 'to equal', [dateValue(2020, 1, 7)]);
expect(input.value, 'to be', '02/07/2020');
expect(filterCells(cells, '.selected'), 'to equal', [cells[12]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[12]]);
cells[12].click();
expect(dp.dates, 'to equal', []);
expect(input.value, 'to be', '');
expect(filterCells(cells, '.selected'), 'to equal', []);
// view date is changed to the default view date
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
dp.destroy();
input.value = '';
});
it('makes the picker deselect the date when a selected date is clicked if value != 1', function () {
const {dp, picker} = createDP(input, {maxNumberOfDates: 3});
const cells = getCells(picker);
dp.setDate('2/14/2020', '2/7/2020');
dp.show();
dp.setDate('2/14/2020');
expect(dp.dates, 'to equal', [dateValue(2020, 1, 7)]);
expect(input.value, 'to be', '02/07/2020');
expect(filterCells(cells, '.selected'), 'to equal', [cells[12]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[12]]);
dp.setDate('2/11/2020', '2/7/2020', '2/14/2020');
expect(dp.dates, 'to equal', [dateValue(2020, 1, 11), dateValue(2020, 1, 14)]);
expect(input.value, 'to be', '02/11/2020,02/14/2020');
expect(filterCells(cells, '.selected'), 'to equal', [cells[16], cells[19]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
dp.destroy();
input.value = '';
});
it('setDate() replaces the selection instead of deselect/merg-ing if clear: true option is passed', function () {
const {dp, picker} = createDP(input, {maxNumberOfDates: 3});
const cells = getCells(picker);
dp.setDate('2/14/2020', '2/7/2020');
dp.show();
dp.setDate('2/14/2020', {clear: true});
expect(dp.dates, 'to equal', [dateValue(2020, 1, 14)]);
expect(input.value, 'to be', '02/14/2020');
expect(filterCells(cells, '.selected'), 'to equal', [cells[19]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
dp.setDate('2/11/2020', '2/7/2020', '2/14/2020', {clear: true});
expect(dp.dates, 'to equal', [
dateValue(2020, 1, 11),
dateValue(2020, 1, 7),
dateValue(2020, 1, 14),
]);
expect(input.value, 'to be', '02/11/2020,02/07/2020,02/14/2020');
expect(filterCells(cells, '.selected'), 'to equal', [cells[16], cells[12], cells[19]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
dp.destroy();
input.value = '';
});
it('setDate() does nothing if no dates or all-invalid dates are passed', function () {
const dp = new Datepicker(input, {maxNumberOfDates: 3});
dp.setDate('2/14/2020', '2/7/2020');
dp.show();
const origDates = [...dp.dates];
dp.setDate([]);
expect(dp.dates, 'to equal', origDates);
expect(input.value, 'to be', '02/14/2020,02/07/2020');
dp.setDate();
expect(dp.dates, 'to equal', origDates);
expect(input.value, 'to be', '02/14/2020,02/07/2020');
dp.setDate([false, NaN], {clear: true});
expect(dp.dates, 'to equal', origDates);
expect(input.value, 'to be', '02/14/2020,02/07/2020');
dp.setDate('', null);
expect(dp.dates, 'to equal', origDates);
expect(input.value, 'to be', '02/14/2020,02/07/2020');
dp.destroy();
});
it('setDate() clears all selected dates if no dates + clear: true option are passed', function () {
const dp = new Datepicker(input, {maxNumberOfDates: 3});
dp.setDate('2/14/2020', '2/7/2020');
dp.show();
dp.setDate([], {clear: true});
expect(dp.dates, 'to equal', []);
expect(input.value, 'to be', '');
dp.setDate('2/14/2020', '2/7/2020');
dp.setDate({clear: true});
expect(dp.dates, 'to equal', []);
expect(input.value, 'to be', '');
dp.destroy();
});
it('setDate() does nothing if all-invalid dates + clear: true option are passed', function () {
const dp = new Datepicker(input, {maxNumberOfDates: 3});
dp.setDate('2/14/2020', '2/7/2020');
dp.show();
const origDates = [...dp.dates];
dp.setDate([false, NaN], {clear: true});
expect(dp.dates, 'to equal', origDates);
expect(input.value, 'to be', '02/14/2020,02/07/2020');
dp.setDate('', null, {clear: true});
expect(dp.dates, 'to equal', origDates);
expect(input.value, 'to be', '02/14/2020,02/07/2020');
dp.destroy();
});
it('does not apply deselecting behavior to update()', function () {
const {dp, picker} = createDP(input, {maxNumberOfDates: 3});
const cells = getCells(picker);
dp.setDate('2/14/2020', '2/7/2020');
dp.show();
input.value = '2/14/2020';
dp.update();
expect(dp.dates, 'to equal', [dateValue(2020, 1, 14)]);
expect(input.value, 'to be', '02/14/2020');
expect(filterCells(cells, '.selected'), 'to equal', [cells[19]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
input.value = '2/11/2020,2/7/2020,2/14/2020';
dp.update();
expect(dp.dates, 'to equal', [
dateValue(2020, 1, 11),
dateValue(2020, 1, 7),
dateValue(2020, 1, 14),
]);
expect(input.value, 'to be', '02/11/2020,02/07/2020,02/14/2020');
expect(filterCells(cells, '.selected'), 'to equal', [cells[16], cells[12], cells[19]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
dp.destroy();
input.value = '';
});
it('makes getDate() return array of dates if value != 1', function () {
const dp = new Datepicker(input, {maxNumberOfDates: 3});
expect(dp.getDate(), 'to equal', []);
expect(dp.getDate('yyyy-mm-dd'), 'to equal', []);
dp.setDate('2/11/2020', '2/7/2020', '2/14/2020');
expect(dp.getDate(), 'to equal', [new Date(2020, 1, 11), new Date(2020, 1, 7), new Date(2020, 1, 14)]);
expect(dp.getDate('yyyy-mm-dd'), 'to equal', ['2020-02-11', '2020-02-07', '2020-02-14']);
dp.setDate('2/7/2020', {clear: true});
expect(dp.getDate(), 'to equal', [new Date(2020, 1, 7)]);
expect(dp.getDate('d M, yyyy'), 'to equal', ['7 Feb, 2020']);
const changeDateListener = (e) => {
evt = e;
};
let evt;
input.addEventListener('changeDate', changeDateListener);
dp.setDate('7/4/2020', '7/14/2020');
expect(evt.detail.date, 'to equal', dp.getDate());
input.removeEventListener('changeDate', changeDateListener);
dp.destroy();
input.value = '';
});
it('value 0 is considered unlimited', function () {
if (window.navigator.userAgent.indexOf('Edge') > -1) {
this.timeout(5000);
}
const max = new Date(2100, 0, 1).getTime();
const generateDates = (dates, length, index = 0) => {
const date = dateUtils.stripTime(Math.floor(Math.random() * max));
if (dates.includes(date)) {
return generateDates(dates, length, index);
} else {
dates.push(date);
return index <= length
? generateDates(dates, length, index + 1)
: dates;
}
};
const dates = generateDates([], 3000);
const dp = new Datepicker(input, {maxNumberOfDates: 0});
dp.setDate(dates);
expect(dp.dates, 'to equal', dates);
dp.destroy();
input.value = '';
});
it('can be updated with setOptions()', function () {
const dp = new Datepicker(input);
dp.setOptions({maxNumberOfDates: 3});
dp.setDate('2/11/2020', '2/7/2020', '2/14/2020');
expect(dp.dates, 'to equal', [
dateValue(2020, 1, 11),
dateValue(2020, 1, 7),
dateValue(2020, 1, 14),
]);
dp.setOptions({maxNumberOfDates: 1});
dp.setDate('7/4/2020', '4/22/2020');
expect(dp.dates, 'to equal', [dateValue(2020, 3, 22)]);
expect(dp.getDate(), 'to be a date');
dp.destroy();
input.value = '';
});
});
describe('dateDelimiter', function () {
it('specifies the date delemiter for the input string', function () {
const dp = new Datepicker(input, {maxNumberOfDates: 3, dateDelimiter: '|'});
dp.setDate('2/14/2020', '4/22/2020');
expect(input.value, 'to be', '02/14/2020|04/22/2020');
input.value = '2/11/2020|2/7/2020|2/14/2020';
dp.update();
expect(dp.dates, 'to equal', [
dateValue(2020, 1, 11),
dateValue(2020, 1, 7),
dateValue(2020, 1, 14),
]);
dp.destroy();
input.value = '';
});
it('can be updated with setOptions()', function () {
const dp = new Datepicker(input, {maxNumberOfDates: 3});
dp.setOptions({dateDelimiter: '_'});
dp.setDate('2/11/2020', '2/7/2020', '2/14/2020');
dp.setOptions({dateDelimiter: ' - '});
expect(input.value, 'to be', '02/11/2020 - 02/07/2020 - 02/14/2020');
dp.setOptions({dateDelimiter: ','});
expect(input.value, 'to be', '02/11/2020,02/07/2020,02/14/2020');
dp.destroy();
input.value = '';
});
});
});

View File

@ -0,0 +1,727 @@
describe('options', function () {
let clock;
let input;
beforeEach(function () {
clock = sinon.useFakeTimers({now: new Date(2020, 1, 14)});
input = document.createElement('input');
testContainer.appendChild(input);
});
afterEach(function () {
testContainer.removeChild(input);
clock.restore();
});
describe('autohide', function () {
it('makes the picker hide automatically on selection when true', function () {
const {dp, picker} = createDP(input, {autohide: true});
dp.show();
// by satDate()
dp.setDate('2/4/2020');
expect(isVisible(picker), 'to be false');
dp.show();
// by click on day cell
getCells(picker)[25].click();
expect(isVisible(picker), 'to be false');
dp.show();
// by typing enter key in edit mode
dp.enterEditMode();
input.value = '2/14/2020';
simulant.fire(input, 'keydown', {key: 'Enter'});
expect(isVisible(picker), 'to be false');
// focus is kept on input field after auto-hidng by clicking day cell
// (issue #21)
const spyFocus = sinon.spy(input, 'focus');
dp.show();
getCells(picker)[25].click();
expect(spyFocus.called, 'to be true');
spyFocus.restore();
dp.destroy();
input.value = '';
});
it('can be updated with setOptions()', function () {
const {dp, picker} = createDP(input);
dp.setOptions({autohide: true});
dp.show();
dp.setDate('2/4/2020');
expect(isVisible(picker), 'to be false');
dp.setOptions({autohide: false});
dp.show();
dp.setDate('2/14/2020');
expect(isVisible(picker), 'to be true');
dp.destroy();
input.value = '';
});
});
describe('buttonClass', function () {
it('specifies the main class used for the button elements', function () {
const {dp, picker} = createDP(input, {buttonClass: 'btn'});
const [viewSwitch, prevBtn, nextBtn, todayBtn, clearBtn] = getParts(picker, [
'.view-switch',
'.prev-btn',
'.next-btn',
'.today-btn',
'.clear-btn',
]);
expect(viewSwitch.className, 'to be', 'btn view-switch');
expect(prevBtn.className, 'to be', 'btn prev-btn');
expect(nextBtn.className, 'to be', 'btn next-btn');
expect(todayBtn.className, 'to be', 'btn today-btn');
expect(clearBtn.className, 'to be', 'btn clear-btn');
dp.destroy();
});
it('cannot be update with setOptions()', function () {
const {dp, picker} = createDP(input);
dp.setOptions({buttonClass: 'btn'});
const [viewSwitch, prevBtn, nextBtn, todayBtn, clearBtn] = getParts(picker, [
'.view-switch',
'.prev-btn',
'.next-btn',
'.today-btn',
'.clear-btn',
]);
expect(viewSwitch.className, 'to be', 'button view-switch');
expect(prevBtn.className, 'to be', 'button prev-btn');
expect(nextBtn.className, 'to be', 'button next-btn');
expect(todayBtn.className, 'to be', 'button today-btn');
expect(clearBtn.className, 'to be', 'button clear-btn');
dp.destroy();
});
});
describe('calendarWeeks', function () {
const getDisplayedWeeks = (picker) => {
const calendarWeeks = picker.querySelector('.calendar-weeks');
return Array.from(calendarWeeks.querySelectorAll('.week')).map(el => el.textContent);
};
it('enables display ISO weeks in days view when true', function () {
const {dp, picker} = createDP(input, {calendarWeeks: true});
const [viewSwitch, prevBtn] = getParts(picker, ['.view-switch', '.prev-btn']);
dp.show();
let calendarWeeks = picker.querySelector('.calendar-weeks');
expect(isVisible(calendarWeeks), 'to be true');
expect(getDisplayedWeeks(picker), 'to equal', ['5', '6', '7', '8', '9', '10']);
prevBtn.click();
expect(getDisplayedWeeks(picker), 'to equal', ['1', '2', '3', '4', '5', '6']);
prevBtn.click();
expect(getDisplayedWeeks(picker), 'to equal', ['48', '49', '50', '51', '52', '1']);
prevBtn.click();
expect(getDisplayedWeeks(picker), 'to equal', ['44', '45', '46', '47', '48', '49']);
dp.setDate('01/01/2021');
expect(getDisplayedWeeks(picker), 'to equal', ['53', '1', '2', '3', '4', '5']);
prevBtn.click();
expect(getDisplayedWeeks(picker), 'to equal', ['49', '50', '51', '52', '53', '1']);
// months view
viewSwitch.click();
expect(picker.querySelector('.calendar-weeks'), 'to be null');
// years view
viewSwitch.click();
expect(picker.querySelector('.calendar-weeks'), 'to be null');
// decades view
viewSwitch.click();
expect(picker.querySelector('.calendar-weeks'), 'to be null');
dp.destroy();
});
it('can be updated with setOptions()', function () {
const {dp, picker} = createDP(input);
dp.setOptions({calendarWeeks: true});
dp.show();
expect(isVisible(picker.querySelector('.calendar-weeks')), 'to be true');
dp.setOptions({calendarWeeks: false});
expect(picker.querySelector('.calendar-weeks'), 'to be null');
dp.destroy();
});
});
describe('container', function () {
let foo;
beforeEach(function () {
foo = parseHTML('<div id="foo"><div>').firstChild;
testContainer.appendChild(foo);
});
afterEach(function () {
testContainer.removeChild(foo);
});
it('specifies the element to attach the picker', function () {
const dp = new Datepicker(input, {container: '#foo'});
expect(document.querySelector('.datepicker').parentElement, 'to be', foo);
dp.destroy();
});
it('cannot be update with setOptions()', function () {
const dp = new Datepicker(input);
dp.setOptions({container: '#foo'});
expect(document.querySelector('.datepicker').parentElement, 'to be', document.body);
dp.destroy();
});
});
describe('daysOfWeekHighlighted', function () {
const highlightedCellIndices = (picker) => {
const cells = getCells(picker);
return filterCells(cells, '.highlighted').map(el => cells.indexOf(el));
};
const highlighted1stWeekIndices = picker => highlightedCellIndices(picker).filter(val => val < 7);
it('specifies the days of week to highlight by dey numbers', function () {
const {dp, picker} = createDP(input, {daysOfWeekHighlighted: [1, 5]});
dp.show();
expect(highlightedCellIndices(picker), 'to equal', [1, 5, 8, 12, 15, 19, 22, 26, 29, 33, 36, 40]);
const viewSwitch = getViewSwitch(picker);
// months view
viewSwitch.click();
expect(highlightedCellIndices(picker), 'to equal', []);
// years view
viewSwitch.click();
expect(highlightedCellIndices(picker), 'to equal', []);
// decades view
viewSwitch.click();
expect(highlightedCellIndices(picker), 'to equal', []);
dp.destroy();
});
it('can contain values of 0 - 6 and max 6 items', function () {
const {dp, picker} = createDP(input, {daysOfWeekHighlighted: [0, -1, 1, 2, 3, 2, 4, 5, 6, 7]});
dp.show();
expect(highlighted1stWeekIndices(picker), 'to equal', [0, 1, 2, 3, 4, 5]);
dp.destroy();
});
it('can be updated with setOptions()', function () {
const {dp, picker} = createDP(input);
dp.setOptions({daysOfWeekHighlighted: [6, 0, 3]});
dp.show();
expect(highlighted1stWeekIndices(picker), 'to equal', [0, 3, 6]);
dp.setOptions({daysOfWeekHighlighted: []});
expect(highlightedCellIndices(picker), 'to equal', []);
dp.destroy();
});
});
describe('defaultViewDate', function () {
it('specifies the start view date in the case no selection is made', function () {
const date = new Date(1984, 0, 24);
const {dp, picker} = createDP(input, {defaultViewDate: date});
dp.show();
expect(getViewSwitch(picker).textContent, 'to be', 'January 1984');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[23]]);
expect(cells[23].textContent, 'to be', '24');
dp.setDate('7/4/2020');
dp.setDate({clear: true});
expect(getViewSwitch(picker).textContent, 'to be', 'January 1984');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[23]]);
expect(cells[23].textContent, 'to be', '24');
picker.querySelector('.prev-btn').click();
dp.hide();
dp.show();
expect(getViewSwitch(picker).textContent, 'to be', 'January 1984');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[23]]);
expect(cells[23].textContent, 'to be', '24');
dp.destroy();
});
it('can be updated with setOptions()', function () {
const {dp, picker} = createDP(input);
dp.show();
dp.setOptions({defaultViewDate: new Date(1984, 0, 24)});
dp.hide();
dp.show();
expect(getViewSwitch(picker).textContent, 'to be', 'January 1984');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[23]]);
expect(cells[23].textContent, 'to be', '24');
dp.setOptions({defaultViewDate: new Date(2007, 5, 29)});
dp.setDate('7/4/2020');
dp.setDate({clear: true});
expect(getViewSwitch(picker).textContent, 'to be', 'June 2007');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[33]]);
expect(cells[33].textContent, 'to be', '29');
dp.destroy();
});
});
describe('disableTouchKeyboard', function () {
const ontouchstartSupported = 'ontouchstart' in document;
before(function () {
if (!ontouchstartSupported) {
document.ontouchstart = null;
}
});
after(function () {
if (!ontouchstartSupported) {
delete document.ontouchstart;
}
});
it('unfocuses the input after showing the picker', function () {
const dp = new Datepicker(input, {disableTouchKeyboard: true});
input.focus();
expect(document.activeElement, 'not to be', input);
dp.destroy();
});
it('prevents the input from getting focus after an eleent in the picker is clicked', function () {
const {dp, picker} = createDP(input, {disableTouchKeyboard: true});
const [viewSwitch, prevBtn] = getParts(picker, ['.view-switch', '.prev-btn']);
dp.show();
prevBtn.focus();
simulant.fire(prevBtn, 'click');
expect(document.activeElement, 'not to be', input);
simulant.fire(getCells(picker)[15], 'click');
expect(document.activeElement, 'not to be', input);
viewSwitch.focus();
simulant.fire(viewSwitch, 'click');
expect(document.activeElement, 'not to be', input);
simulant.fire(getCells(picker)[6], 'click');
expect(document.activeElement, 'not to be', input);
dp.destroy();
});
it('is ignored if the browser does not support document.ontouchstart', function () {
if (ontouchstartSupported) {
return;
}
delete document.ontouchstart;
const {dp, picker} = createDP(input, {disableTouchKeyboard: true});
const [viewSwitch, prevBtn] = getParts(picker, ['.view-switch', '.prev-btn']);
input.focus();
expect(document.activeElement, 'to be', input);
prevBtn.focus();
simulant.fire(prevBtn, 'click');
expect(document.activeElement, 'to be', input);
prevBtn.focus();
simulant.fire(getCells(picker)[15], 'click');
expect(document.activeElement, 'to be', input);
viewSwitch.focus();
simulant.fire(viewSwitch, 'click');
expect(document.activeElement, 'to be', input);
viewSwitch.focus();
simulant.fire(getCells(picker)[6], 'click');
expect(document.activeElement, 'to be', input);
dp.destroy();
document.ontouchstart = null;
});
it('can be updated with setOptions()', function () {
const dp = new Datepicker(input);
dp.setOptions({disableTouchKeyboard: true});
input.focus();
expect(document.activeElement, 'not to be', input);
dp.hide();
dp.setOptions({disableTouchKeyboard: false});
input.focus();
expect(document.activeElement, 'to be', input);
dp.destroy();
});
});
describe('nextArrow', function () {
it('specifies the label of the next button in HTML (or plain text)', function () {
const html = '<i class="icn icn-arrow-right"></i>';
const {dp, picker} = createDP(input, {nextArrow: html});
const nextBtn = picker.querySelector('.next-btn');
dp.show();
expect(nextBtn.innerHTML, 'to be', html);
dp.destroy();
});
it('can be updated with setOptions()', function () {
const {dp, picker} = createDP(input);
const nextBtn = picker.querySelector('.next-btn');
dp.setOptions({nextArrow: 'N'});
dp.show();
expect(nextBtn.textContent, 'to be', 'N');
dp.setOptions({nextArrow: '>'});
expect(nextBtn.textContent, 'to be', '>');
dp.destroy();
});
});
describe('prevArrow', function () {
it('specifies the label of the next button in HTML (or plain text)', function () {
const html = '<i class="icn icn-arrow-left"></i>';
const {dp, picker} = createDP(input, {prevArrow: html});
const prevBtn = picker.querySelector('.prev-btn');
dp.show();
expect(prevBtn.innerHTML, 'to be', html);
dp.destroy();
});
it('can be updated with setOptions()', function () {
const {dp, picker} = createDP(input);
const prevBtn = picker.querySelector('.prev-btn');
dp.setOptions({prevArrow: 'P'});
dp.show();
expect(prevBtn.textContent, 'to be', 'P');
dp.setOptions({prevArrow: '<'});
expect(prevBtn.textContent, 'to be', '<');
dp.destroy();
});
});
describe('showDaysOfWeek', function () {
it('hides day names of week when false', function () {
const {dp, picker} = createDP(input, {showDaysOfWeek: false});
dp.show();
expect(isVisible(picker.querySelector('.days-of-week')), 'to be false');
dp.destroy();
});
it('can be updated with setOptions()', function () {
const {dp, picker} = createDP(input);
dp.setOptions({showDaysOfWeek: false});
dp.show();
expect(isVisible(picker.querySelector('.days-of-week')), 'to be false');
dp.setOptions({showDaysOfWeek: true});
expect(isVisible(picker.querySelector('.days-of-week')), 'to be true');
dp.destroy();
});
});
describe('showOnClick', function () {
it('disables the picker to auto-open on clicking input when false', function () {
const {dp, picker} = createDP(input, {showOnClick: false});
input.focus();
dp.hide();
simulant.fire(input, 'mousedown');
input.click();
expect(isVisible(picker), 'to be false');
dp.destroy();
});
it('can be updated with setOptions()', function () {
const {dp, picker} = createDP(input);
dp.setOptions({showOnClick: false});
input.focus();
dp.hide();
simulant.fire(input, 'mousedown');
input.click();
expect(isVisible(picker), 'to be false');
dp.setOptions({showOnClick: true});
simulant.fire(input, 'mousedown');
input.click();
expect(isVisible(picker), 'to be true');
dp.destroy();
});
});
describe('showOnFocus', function () {
it('disables the picker to auto-open on focus when false', function () {
const {dp, picker} = createDP(input, {showOnFocus: false});
input.focus();
expect(isVisible(picker), 'to be false');
dp.destroy();
});
it('can be updated with setOptions()', function () {
const {dp, picker} = createDP(input);
dp.setOptions({showOnFocus: false});
input.focus();
expect(isVisible(picker), 'to be false');
input.blur();
dp.setOptions({showOnFocus: true});
input.focus();
expect(isVisible(picker), 'to be true');
dp.destroy();
});
});
describe('title', function () {
it('specifies the title of the picker and shows it when not empty', function () {
const {dp, picker} = createDP(input, {title: 'Foo Bar'});
const title = picker.querySelector('.datepicker-title');
dp.show();
expect(title.textContent, 'to be', 'Foo Bar');
expect(isVisible(title), 'to be true');
dp.destroy();
});
it('can be updated with setOptions()', function () {
const {dp, picker} = createDP(input);
const title = picker.querySelector('.datepicker-title');
dp.setOptions({title: 'My Datepicker'});
dp.show();
expect(title.textContent, 'to be', 'My Datepicker');
expect(isVisible(title), 'to be true');
dp.setOptions({title: ''});
expect(title.textContent, 'to be', '');
expect(isVisible(title), 'to be false');
dp.destroy();
});
});
describe('todayHighlight', function () {
it('highlights the current date in days view when true', function () {
const {dp, picker} = createDP(input, {todayHighlight: true});
const viewSwitch = getViewSwitch(picker);
dp.show();
let cells = getCells(picker);
expect(filterCells(cells, '.today'), 'to equal', [cells[19]]);
picker.querySelector('.prev-btn').click();
expect(filterCells(getCells(picker), '.today'), 'to equal', []);
picker.querySelector('.next-btn').click();
viewSwitch.click();
expect(filterCells(getCells(picker), '.today'), 'to equal', []);
viewSwitch.click();
expect(filterCells(getCells(picker), '.today'), 'to equal', []);
viewSwitch.click();
expect(filterCells(getCells(picker), '.today'), 'to equal', []);
dp.destroy();
});
it('can be updated with setOptions()', function () {
const {dp, picker} = createDP(input);
dp.setOptions({todayHighlight: true});
dp.show();
let cells = getCells(picker);
expect(filterCells(cells, '.today'), 'to equal', [cells[19]]);
dp.setOptions({todayHighlight: false});
cells = getCells(picker);
expect(filterCells(cells, '.today'), 'to equal', []);
dp.destroy();
});
});
describe('updateOnBlur', function () {
it('discards unparsed input on losing focus when false', function () {
const outsider = document.createElement('p');
testContainer.appendChild(outsider);
const {dp, picker} = createDP(input, {updateOnBlur: false});
input.focus();
input.value = 'foo';
// on tab key press
simulant.fire(input, 'keydown', {key: 'Tab'});
expect(input.value, 'to be', '');
dp.setDate('04/22/2020');
dp.show();
dp.enterEditMode();
input.value = 'foo';
simulant.fire(input, 'keydown', {key: 'Tab'});
expect(input.value, 'to be', '04/22/2020');
// on click outside
dp.show();
input.value = 'foo';
simulant.fire(picker.querySelector('.dow'), 'mousedown');
expect(input.value, 'to be', 'foo');
simulant.fire(input, 'mousedown');
expect(input.value, 'to be', 'foo');
simulant.fire(outsider, 'mousedown');
expect(input.value, 'to be', '04/22/2020');
dp.setDate({clear: true});
input.value = 'foo';
simulant.fire(outsider, 'mousedown');
expect(input.value, 'to be', '');
dp.destroy();
testContainer.removeChild(outsider);
});
it('can be updated with setOptions()', function () {
const dp = new Datepicker(input);
dp.setOptions({updateOnBlur: false});
input.focus();
input.value = '04/22/2020';
simulant.fire(input, 'keydown', {key: 'Tab'});
expect(input.value, 'to be', '');
dp.setOptions({updateOnBlur: true});
input.focus();
input.value = '04/22/2020';
simulant.fire(input, 'keydown', {key: 'Tab'});
expect(input.value, 'to be', '04/22/2020');
dp.destroy();
});
});
describe('weekStart', function () {
const getDayNames = (picker) => {
const daysOfWeek = picker.querySelector('.days-of-week');
return Array.from(daysOfWeek.children).map(el => el.textContent);
};
const getDatesInColumn = (picker, colIndex) => {
const cells = getCells(picker);
return cells.reduce((dates, el, ix) => {
if (ix % 7 === colIndex) {
dates.push(el.textContent);
}
return dates;
}, []);
};
it('specifies the day of week to display in the first column', function () {
const {dp, picker} = createDP(input, {weekStart: 1});
dp.show();
expect(getDayNames(picker), 'to equal', ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su']);
expect(getDatesInColumn(picker, 0), 'to equal', ['27', '3', '10', '17', '24', '2']);
expect(getDatesInColumn(picker, 6), 'to equal', ['2', '9', '16', '23', '1', '8']);
dp.destroy();
});
it('can be updated with setOptions()', function () {
const {dp, picker} = createDP(input);
dp.setOptions({weekStart: 4});
dp.show();
expect(getDayNames(picker), 'to equal', ['Th', 'Fr', 'Sa', 'Su', 'Mo', 'Tu', 'We']);
expect(getDatesInColumn(picker, 0), 'to equal', ['30', '6', '13', '20', '27', '5']);
expect(getDatesInColumn(picker, 6), 'to equal', ['5', '12', '19', '26', '4', '11']);
dp.setOptions({weekStart: 0});
expect(getDayNames(picker), 'to equal', ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']);
expect(getDatesInColumn(picker, 0), 'to equal', ['26', '2', '9', '16', '23', '1']);
expect(getDatesInColumn(picker, 6), 'to equal', ['1', '8', '15', '22', '29', '7']);
dp.destroy();
});
});
});

View File

@ -0,0 +1,410 @@
describe('options - orientation', function () {
const getIntSize = px => Math.round(parseFloat(px));
const getTopPos = (el, wrap) => el.offsetTop + (wrap ? wrap.offsetTop : 0) + window.scrollY;
const getLeftPos = (el, wrap) => el.offsetLeft + (wrap ? wrap.offsetLeft : 0) + window.scrollX;
const getBottomPos = (el, wrap) => getTopPos(el, wrap) + el.offsetHeight;
const getRightPos = (el, wrap) => getLeftPos(el, wrap) + el.offsetWidth;
let wrapper;
let input;
beforeEach(function () {
wrapper = document.createElement('div');
Object.assign(wrapper.style, {
boxSizing: 'border-box',
position: 'fixed',
top: '50px',
left: '50px',
width: '300px',
paddingTop: '300px',
});
input = document.createElement('input');
wrapper.appendChild(input);
testContainer.appendChild(wrapper);
});
afterEach(function () {
domUtils.emptyChildNodes(testContainer);
});
it('"auto" makes the picker show on top left of the input by default', function () {
const {dp, picker} = createDP(input);
dp.show();
expect(getIntSize(picker.style.top), 'to be close to', getTopPos(input, wrapper) - picker.offsetHeight, 1);
expect(getIntSize(picker.style.left), 'to be close to', getLeftPos(input, wrapper), 1);
expect(picker.classList.contains('datepicker-orient-top'), 'to be true');
expect(picker.classList.contains('datepicker-orient-left'), 'to be true');
dp.destroy();
});
it('"auto" makes the picker show on top right of the input if computed style of the input has direction: rrl', function () {
const {dp, picker} = createDP(input);
wrapper.setAttribute('dir', 'rtl');
dp.show();
expect(getIntSize(picker.style.top), 'to be close to', getTopPos(input, wrapper) - picker.offsetHeight, 1);
expect(getIntSize(picker.style.left), 'to be close to', getRightPos(input, wrapper) - picker.offsetWidth, 1);
expect(picker.classList.contains('datepicker-orient-top'), 'to be true');
expect(picker.classList.contains('datepicker-orient-right'), 'to be true');
dp.destroy();
});
it('"auto" makes the picker show on bottom of the input if visible space above the input < picker height', function () {
const {dp, picker} = createDP(input);
wrapper.style.paddingTop = '0';
dp.show();
expect(getIntSize(picker.style.top), 'to be close to', getBottomPos(input, wrapper), 1);
expect(getIntSize(picker.style.left), 'to be close to', getLeftPos(input, wrapper), 1);
expect(picker.classList.contains('datepicker-orient-bottom'), 'to be true');
expect(picker.classList.contains('datepicker-orient-left'), 'to be true');
dp.hide();
wrapper.setAttribute('dir', 'rtl');
dp.show();
expect(getIntSize(picker.style.top), 'to be close to', getBottomPos(input, wrapper), 1);
expect(getIntSize(picker.style.left), 'to be close to', getRightPos(input, wrapper) - picker.offsetWidth, 1);
expect(picker.classList.contains('datepicker-orient-bottom'), 'to be true');
expect(picker.classList.contains('datepicker-orient-right'), 'to be true');
dp.destroy();
});
it('"auto" makes the picker move to 10px from document\'s left if picker\'s left < document\'s', function () {
const {dp, picker} = createDP(input);
wrapper.style.left = '-40px';
dp.show();
expect(getIntSize(picker.style.left), 'to be', 10);
expect(picker.classList.contains('datepicker-orient-left'), 'to be true');
dp.destroy();
});
it('"auto" makes the picker show on right if picker\'s right edge > document\'s', function () {
const {dp, picker} = createDP(input);
Object.assign(wrapper.style, {left: 'auto', right: 0, width: '150px'});
dp.show();
expect(getIntSize(picker.style.left), 'to be close to', getRightPos(input, wrapper) - picker.offsetWidth, 1);
expect(picker.classList.contains('datepicker-orient-right'), 'to be true');
dp.destroy();
});
it('"top" makes the picker show on top of the input regardless of the size of the space above', function () {
const {dp, picker} = createDP(input, {orientation: 'top'});
dp.show();
expect(picker.classList.contains('datepicker-orient-top'), 'to be true');
expect(picker.classList.contains('datepicker-orient-left'), 'to be true');
dp.hide();
wrapper.style.paddingTop = '0';
dp.show();
expect(picker.classList.contains('datepicker-orient-top'), 'to be true');
expect(picker.classList.contains('datepicker-orient-left'), 'to be true');
dp.hide();
wrapper.setAttribute('dir', 'rtl');
dp.show();
expect(picker.classList.contains('datepicker-orient-top'), 'to be true');
expect(picker.classList.contains('datepicker-orient-right'), 'to be true');
dp.destroy();
});
it('"bottom" makes the picker show on bottom of the input regardless of the size of the space below', function () {
wrapper.style.paddingTop = '0';
const {dp, picker} = createDP(input, {orientation: 'bottom'});
dp.show();
expect(picker.classList.contains('datepicker-orient-bottom'), 'to be true');
expect(picker.classList.contains('datepicker-orient-left'), 'to be true');
dp.hide();
Object.assign(wrapper.style, {top: 'auto', bottom: '0'});
dp.show();
expect(picker.classList.contains('datepicker-orient-bottom'), 'to be true');
expect(picker.classList.contains('datepicker-orient-left'), 'to be true');
dp.hide();
wrapper.setAttribute('dir', 'rtl');
dp.show();
expect(picker.classList.contains('datepicker-orient-bottom'), 'to be true');
expect(picker.classList.contains('datepicker-orient-right'), 'to be true');
dp.destroy();
});
it('"left" makes the picker show on left of the input regardless of the direction of the input', function () {
const {dp, picker} = createDP(input, {orientation: 'left'});
dp.show();
expect(picker.classList.contains('datepicker-orient-top'), 'to be true');
expect(picker.classList.contains('datepicker-orient-left'), 'to be true');
dp.hide();
wrapper.setAttribute('dir', 'rtl');
dp.show();
expect(picker.classList.contains('datepicker-orient-top'), 'to be true');
expect(picker.classList.contains('datepicker-orient-left'), 'to be true');
dp.destroy();
});
it('"right" makes the picker show on right of the input regardless of the direction of the input', function () {
const {dp, picker} = createDP(input, {orientation: 'right'});
dp.show();
expect(picker.classList.contains('datepicker-orient-top'), 'to be true');
expect(picker.classList.contains('datepicker-orient-right'), 'to be true');
dp.hide();
wrapper.setAttribute('dir', 'rtl');
dp.show();
expect(picker.classList.contains('datepicker-orient-top'), 'to be true');
expect(picker.classList.contains('datepicker-orient-right'), 'to be true');
dp.destroy();
});
it('"top left" makes the picker always show on top left of the input', function () {
wrapper.style.paddingTop = '0';
const {dp, picker} = createDP(input, {orientation: 'top left'});
dp.show();
expect(picker.classList.contains('datepicker-orient-top'), 'to be true');
expect(picker.classList.contains('datepicker-orient-left'), 'to be true');
dp.hide();
Object.assign(wrapper.style, {top: 'auto', bottom: '0'});
dp.show();
expect(picker.classList.contains('datepicker-orient-top'), 'to be true');
expect(picker.classList.contains('datepicker-orient-left'), 'to be true');
dp.hide();
wrapper.setAttribute('dir', 'rtl');
dp.show();
expect(picker.classList.contains('datepicker-orient-top'), 'to be true');
expect(picker.classList.contains('datepicker-orient-left'), 'to be true');
dp.hide();
Object.assign(wrapper.style, {top: '0', bottom: ''});
dp.show();
expect(picker.classList.contains('datepicker-orient-top'), 'to be true');
expect(picker.classList.contains('datepicker-orient-left'), 'to be true');
dp.destroy();
});
it('"top right" makes the picker always show on top right of the input', function () {
wrapper.style.paddingTop = '0';
const {dp, picker} = createDP(input, {orientation: 'top right'});
dp.show();
expect(picker.classList.contains('datepicker-orient-top'), 'to be true');
expect(picker.classList.contains('datepicker-orient-right'), 'to be true');
dp.hide();
Object.assign(wrapper.style, {top: 'auto', bottom: '0'});
dp.show();
expect(picker.classList.contains('datepicker-orient-top'), 'to be true');
expect(picker.classList.contains('datepicker-orient-right'), 'to be true');
dp.hide();
wrapper.setAttribute('dir', 'rtl');
dp.show();
expect(picker.classList.contains('datepicker-orient-top'), 'to be true');
expect(picker.classList.contains('datepicker-orient-right'), 'to be true');
dp.hide();
Object.assign(wrapper.style, {top: '0', bottom: ''});
dp.show();
expect(picker.classList.contains('datepicker-orient-top'), 'to be true');
expect(picker.classList.contains('datepicker-orient-right'), 'to be true');
dp.destroy();
});
it('"bottom left" makes the picker always show on bottom left of the input', function () {
wrapper.style.paddingTop = '0';
const {dp, picker} = createDP(input, {orientation: 'bottom left'});
dp.show();
expect(picker.classList.contains('datepicker-orient-bottom'), 'to be true');
expect(picker.classList.contains('datepicker-orient-left'), 'to be true');
dp.hide();
Object.assign(wrapper.style, {top: 'auto', bottom: '0'});
dp.show();
expect(picker.classList.contains('datepicker-orient-bottom'), 'to be true');
expect(picker.classList.contains('datepicker-orient-left'), 'to be true');
dp.hide();
wrapper.setAttribute('dir', 'rtl');
dp.show();
expect(picker.classList.contains('datepicker-orient-bottom'), 'to be true');
expect(picker.classList.contains('datepicker-orient-left'), 'to be true');
dp.hide();
Object.assign(wrapper.style, {top: '0', bottom: ''});
dp.show();
expect(picker.classList.contains('datepicker-orient-bottom'), 'to be true');
expect(picker.classList.contains('datepicker-orient-left'), 'to be true');
dp.destroy();
});
it('"bottom right" makes the picker always show on bottom right of the input', function () {
wrapper.style.paddingTop = '0';
const {dp, picker} = createDP(input, {orientation: 'bottom right'});
dp.show();
expect(picker.classList.contains('datepicker-orient-bottom'), 'to be true');
expect(picker.classList.contains('datepicker-orient-right'), 'to be true');
dp.hide();
Object.assign(wrapper.style, {top: 'auto', bottom: '0'});
dp.show();
expect(picker.classList.contains('datepicker-orient-bottom'), 'to be true');
expect(picker.classList.contains('datepicker-orient-right'), 'to be true');
dp.hide();
wrapper.setAttribute('dir', 'rtl');
dp.show();
expect(picker.classList.contains('datepicker-orient-bottom'), 'to be true');
expect(picker.classList.contains('datepicker-orient-right'), 'to be true');
dp.hide();
Object.assign(wrapper.style, {top: '0', bottom: ''});
dp.show();
expect(picker.classList.contains('datepicker-orient-bottom'), 'to be true');
expect(picker.classList.contains('datepicker-orient-right'), 'to be true');
dp.destroy();
});
it('can be updated with setOptions()', function () {
const {dp, picker} = createDP(input);
dp.setOptions({orientation: 'right bottom'});
dp.show();
expect(picker.classList.contains('datepicker-orient-bottom'), 'to be true');
expect(picker.classList.contains('datepicker-orient-right'), 'to be true');
dp.hide();
dp.setOptions({orientation: 'bottom auto'});
dp.show();
expect(picker.classList.contains('datepicker-orient-bottom'), 'to be true');
expect(picker.classList.contains('datepicker-orient-left'), 'to be true');
dp.hide();
dp.setOptions({orientation: 'auto right'});
dp.show();
expect(picker.classList.contains('datepicker-orient-top'), 'to be true');
expect(picker.classList.contains('datepicker-orient-right'), 'to be true');
dp.hide();
dp.setOptions({orientation: 'auto'});
dp.show();
expect(picker.classList.contains('datepicker-orient-top'), 'to be true');
expect(picker.classList.contains('datepicker-orient-left'), 'to be true');
dp.destroy();
});
describe('with custom container', function () {
let foo;
beforeEach(function () {
foo = parseHTML('<div id="foo"></div>').firstChild;
Object.assign(foo.style, {
boxSizing: 'border-box',
position: 'fixed',
top: '20px',
left: '20px',
height: '360px',
overflow: 'auto',
});
Object.assign(wrapper.style, {position: '', top: '', left: ''});
testContainer.replaceChild(foo, wrapper);
foo.appendChild(wrapper);
});
it('makes the picker\'s position relative to the container', function () {
const {dp, picker} = createDP(input, {container: '#foo'});
dp.show();
expect(getIntSize(picker.style.top), 'to be', input.offsetTop - picker.offsetHeight);
expect(getIntSize(picker.style.left), 'to be', input.offsetLeft);
expect(picker.classList.contains('datepicker-orient-top'), 'to be true');
expect(picker.classList.contains('datepicker-orient-left'), 'to be true');
dp.hide();
wrapper.style.paddingBottom = '200px';
foo.scrollTop = 100;
dp.show();
expect(getIntSize(picker.style.top), 'to be', input.offsetTop + input.offsetHeight);
expect(getIntSize(picker.style.left), 'to be', input.offsetLeft);
expect(picker.classList.contains('datepicker-orient-bottom'), 'to be true');
expect(picker.classList.contains('datepicker-orient-left'), 'to be true');
foo.scrollTop = 0;
wrapper.style.paddingBottom = '';
dp.destroy();
});
it('"auto" makes the picker move to 10px from container\'s left if picker\'s left < container\'s', function () {
const {dp, picker} = createDP(input, {container: '#foo'});
wrapper.style.marginLeft = '-40px';
dp.show();
expect(getIntSize(picker.style.left), 'to be', 10);
expect(picker.classList.contains('datepicker-orient-left'), 'to be true');
dp.destroy();
});
it('"auto" makes the picker show on right if picker\'s right edge < container\'s', function () {
const {dp, picker} = createDP(input, {container: '#foo'});
wrapper.style.width = '150px';
dp.show();
expect(getIntSize(picker.style.left), 'to be', input.offsetLeft + input.offsetWidth - picker.offsetWidth);
expect(picker.classList.contains('datepicker-orient-right'), 'to be true');
dp.destroy();
});
});
});

View File

@ -0,0 +1,357 @@
describe('options - pick level & view', function () {
let clock;
let input;
beforeEach(function () {
clock = sinon.useFakeTimers({now: new Date(2020, 1, 14)});
input = document.createElement('input');
testContainer.appendChild(input);
});
afterEach(function () {
testContainer.removeChild(input);
clock.restore();
});
describe('pickLevel', function () {
it('limits the minimum of available views', function () {
const {dp, picker} = createDP(input, {pickLevel: 2});
const viewSwitch = getViewSwitch(picker);
const cells1 = getCells(picker)[1];
dp.show();
expect(viewSwitch.textContent, 'to be', '2020-2029');
expect(cells1.textContent, 'to be', '2020');
cells1.click();
expect(viewSwitch.textContent, 'to be', '2020-2029');
expect(getCells(picker)[1].textContent, 'to be', '2020');
dp.destroy();
});
it('changes the selection level to month when 1', function () {
input.value = '2/14/2020';
const {dp, picker} = createDP(input, {pickLevel: 1});
const [viewSwitch, nextBtn] = getParts(picker, ['.view-switch', '.next-btn']);
let cells = getCells(picker);
dp.show();
expect(dp.dates, 'to equal', [dateValue(2020, 1, 1)]);
expect(input.value, 'to be', '02/01/2020');
expect(viewSwitch.textContent, 'to be', '2020');
expect(filterCells(cells, '.selected'), 'to equal', [cells[1]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
// mouse operation
cells[0].click();
cells = getCells(picker);
expect(dp.dates, 'to equal', [dateValue(2020, 0, 1)]);
expect(input.value, 'to be', '01/01/2020');
expect(viewSwitch.textContent, 'to be', '2020');
expect(filterCells(cells, '.selected'), 'to equal', [cells[0]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[0]]);
nextBtn.click();
getCells(picker)[7].click();
cells = getCells(picker);
expect(dp.dates, 'to equal', [dateValue(2021, 7, 1)]);
expect(input.value, 'to be', '08/01/2021');
expect(viewSwitch.textContent, 'to be', '2021');
expect(filterCells(cells, '.selected'), 'to equal', [cells[7]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[7]]);
// keyboard operation
simulant.fire(input, 'keydown', {key: 'ArrowLeft', ctrlKey: true});
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
simulant.fire(input, 'keydown', {key: 'Enter'});
cells = getCells(picker);
expect(dp.dates, 'to equal', [dateValue(2020, 6, 1)]);
expect(input.value, 'to be', '07/01/2020');
expect(viewSwitch.textContent, 'to be', '2020');
expect(filterCells(cells, '.selected'), 'to equal', [cells[6]]);
dp.enterEditMode();
input.value = '4/20/2021';
simulant.fire(input, 'keydown', {key: 'Enter'});
cells = getCells(picker);
expect(dp.dates, 'to equal', [dateValue(2021, 3, 1)]);
expect(input.value, 'to be', '04/01/2021');
expect(viewSwitch.textContent, 'to be', '2021');
expect(filterCells(cells, '.selected'), 'to equal', [cells[3]]);
// api call
viewSwitch.click();
dp.setDate('2/14/2022');
cells = getCells(picker);
expect(dp.dates, 'to equal', [dateValue(2022, 1, 1)]);
expect(input.value, 'to be', '02/01/2022');
expect(viewSwitch.textContent, 'to be', '2022');
expect(filterCells(cells, '.selected'), 'to equal', [cells[1]]);
viewSwitch.click();
dp.hide();
input.value = '3/14/2020';
dp.update();
dp.show();
cells = getCells(picker);
expect(dp.dates, 'to equal', [dateValue(2020, 2, 1)]);
expect(input.value, 'to be', '03/01/2020');
expect(viewSwitch.textContent, 'to be', '2020');
expect(filterCells(cells, '.selected'), 'to equal', [cells[2]]);
dp.destroy();
});
it('changes the selection level to year when 2', function () {
input.value = '2/14/2020';
const {dp, picker} = createDP(input, {pickLevel: 2});
const [viewSwitch, nextBtn] = getParts(picker, ['.view-switch', '.next-btn']);
let cells = getCells(picker);
dp.show();
expect(dp.dates, 'to equal', [dateValue(2020, 0, 1)]);
expect(input.value, 'to be', '01/01/2020');
expect(viewSwitch.textContent, 'to be', '2020-2029');
expect(filterCells(cells, '.selected'), 'to equal', [cells[1]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
// mouse operation
cells[2].click();
cells = getCells(picker);
expect(dp.dates, 'to equal', [dateValue(2021, 0, 1)]);
expect(input.value, 'to be', '01/01/2021');
expect(viewSwitch.textContent, 'to be', '2020-2029');
expect(filterCells(cells, '.selected'), 'to equal', [cells[2]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[2]]);
nextBtn.click();
getCells(picker)[7].click();
cells = getCells(picker);
expect(dp.dates, 'to equal', [dateValue(2036, 0, 1)]);
expect(input.value, 'to be', '01/01/2036');
expect(viewSwitch.textContent, 'to be', '2030-2039');
expect(filterCells(cells, '.selected'), 'to equal', [cells[7]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[7]]);
// keyboard operation
simulant.fire(input, 'keydown', {key: 'ArrowLeft', ctrlKey: true});
simulant.fire(input, 'keydown', {key: 'ArrowLeft'});
simulant.fire(input, 'keydown', {key: 'Enter'});
cells = getCells(picker);
expect(dp.dates, 'to equal', [dateValue(2025, 0, 1)]);
expect(input.value, 'to be', '01/01/2025');
expect(viewSwitch.textContent, 'to be', '2020-2029');
expect(filterCells(cells, '.selected'), 'to equal', [cells[6]]);
dp.enterEditMode();
input.value = '4/20/2021';
simulant.fire(input, 'keydown', {key: 'Enter'});
cells = getCells(picker);
expect(dp.dates, 'to equal', [dateValue(2021, 0, 1)]);
expect(input.value, 'to be', '01/01/2021');
expect(viewSwitch.textContent, 'to be', '2020-2029');
expect(filterCells(cells, '.selected'), 'to equal', [cells[2]]);
// api call
viewSwitch.click();
dp.setDate('2/14/2032');
cells = getCells(picker);
expect(dp.dates, 'to equal', [dateValue(2032, 0, 1)]);
expect(input.value, 'to be', '01/01/2032');
expect(viewSwitch.textContent, 'to be', '2030-2039');
expect(filterCells(cells, '.selected'), 'to equal', [cells[3]]);
viewSwitch.click();
dp.hide();
input.value = '3/14/2020';
dp.update();
dp.show();
cells = getCells(picker);
expect(dp.dates, 'to equal', [dateValue(2020, 0, 1)]);
expect(input.value, 'to be', '01/01/2020');
expect(viewSwitch.textContent, 'to be', '2020-2029');
expect(filterCells(cells, '.selected'), 'to equal', [cells[1]]);
dp.destroy();
});
it('can be updated with setOptions()', function () {
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
dp.setOptions({pickLevel: 1});
dp.show();
let cells = getCells(picker);
expect(viewSwitch.textContent, 'to be', '2020');
expect(cells[1].textContent, 'to be', 'Feb');
cells[1].click();
cells = getCells(picker);
expect(dp.dates, 'to equal', [dateValue(2020, 1, 1)]);
expect(input.value, 'to be', '02/01/2020');
expect(viewSwitch.textContent, 'to be', '2020');
expect(filterCells(cells, '.selected'), 'to equal', [cells[0]]);
dp.setOptions({pickLevel: 0});
cells = getCells(picker);
expect(viewSwitch.textContent, 'to be', 'February 2020');
expect(filterCells(cells, '.selected'), 'to equal', [cells[6]]);
expect(filterCells(cells, '.focused'), 'to equal', [cells[6]]);
viewSwitch.click();
getCells(picker)[3].click();
cells = getCells(picker);
expect(viewSwitch.textContent, 'to be', 'April 2020');
expect(filterCells(cells, '.selected'), 'to equal', []);
expect(filterCells(cells, '.focused'), 'to equal', [cells[3]]);
dp.destroy();
});
});
describe('maxView', function () {
it('limits the maximum of available views', function () {
const {dp, picker} = createDP(input, {maxView: 1});
const viewSwitch = getViewSwitch(picker);
dp.show();
viewSwitch.click();
viewSwitch.click();
expect(viewSwitch.textContent, 'to be', '2020');
expect(getCells(picker)[0].textContent, 'to be', 'Jan');
dp.destroy();
});
it('cannot be smaller than pickLevel', function () {
const {dp, picker} = createDP(input, {maxView: 1, pickLevel: 2});
const viewSwitch = getViewSwitch(picker);
dp.show();
expect(viewSwitch.textContent, 'to be', '2020-2029');
expect(getCells(picker)[1].textContent, 'to be', '2020');
viewSwitch.click();
expect(viewSwitch.textContent, 'to be', '2020-2029');
expect(getCells(picker)[1].textContent, 'to be', '2020');
dp.destroy();
});
it('can be updated with setOptions()', function () {
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
dp.setOptions({maxView: 2});
dp.show();
viewSwitch.click();
viewSwitch.click();
viewSwitch.click();
expect(viewSwitch.textContent, 'to be', '2020-2029');
expect(getCells(picker)[1].textContent, 'to be', '2020');
dp.setOptions({maxView: 0});
expect(viewSwitch.textContent, 'to be', 'February 2020');
viewSwitch.click();
expect(viewSwitch.textContent, 'to be', 'February 2020');
dp.destroy();
});
});
describe('startView', function () {
it('specifies the view desplayed on open', function () {
const {dp, picker} = createDP(input, {startView: 3});
const viewSwitch = getViewSwitch(picker);
dp.show();
expect(viewSwitch.textContent, 'to be', '2000-2090');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[3]]);
expect(cells[3].textContent, 'to be', '2020');
dp.destroy();
});
it('cannot be smaller than pickLevel', function () {
const {dp, picker} = createDP(input, {startView: 1, pickLevel: 2});
const viewSwitch = getViewSwitch(picker);
dp.show();
expect(viewSwitch.textContent, 'to be', '2020-2029');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
expect(cells[1].textContent, 'to be', '2020');
dp.destroy();
});
it('cannot be larger than maxView', function () {
const {dp, picker} = createDP(input, {startView: 3, maxView: 2});
const viewSwitch = getViewSwitch(picker);
dp.show();
expect(viewSwitch.textContent, 'to be', '2020-2029');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
expect(cells[1].textContent, 'to be', '2020');
dp.destroy();
});
it('can be updated with setOptions()', function () {
const {dp, picker} = createDP(input);
const viewSwitch = getViewSwitch(picker);
dp.setOptions({startView: 2});
dp.show();
expect(viewSwitch.textContent, 'to be', '2020-2029');
let cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[1]]);
expect(cells[1].textContent, 'to be', '2020');
dp.hide();
dp.setOptions({startView: 0});
dp.show();
expect(viewSwitch.textContent, 'to be', 'February 2020');
cells = getCells(picker);
expect(filterCells(cells, '.focused'), 'to equal', [cells[19]]);
expect(cells[19].textContent, 'to be', '14');
dp.destroy();
});
});
});

94
node_modules/flowbite-datepicker/test/test.html generated vendored Normal file
View File

@ -0,0 +1,94 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Mocha Tests</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="../node_modules/mocha/mocha.css" />
<style type="text/css">
html * {
box-sizing: border-box;
}
</style>
<link rel="stylesheet" href="../dist/css/datepicker.css" />
</head>
<body>
<div id="mocha"></div>
<div id="test-container"></div>
<script src="../node_modules/mocha/mocha.js"></script>
<script src="../node_modules/unexpected/unexpected.js"></script>
<script src="../node_modules/sinon/pkg/sinon.js"></script>
<script src="../node_modules/simulant/dist/simulant.umd.js"></script>
<script class="mocha-init">
mocha.setup('bdd');
mocha.checkLeaks();
window.testContainer = document.getElementById('test-container');
</script>
<script src="./_utils/date.js"></script>
<script src="./_utils/dom.js"></script>
<script class="setup">
/* eslint-disable no-undef, no-unused-vars */
var expect = weknowhow.expect;
var dateValue = dateUtils.dateValue;
var parseHTML = domUtils.parseHTML;
var isVisible = domUtils.isVisible;
var lastItemOf = arr => arr[arr.length - 1];
var createDP = (el, options) => {
const dp = new Datepicker(el, options);
return {dp, picker: document.querySelector('.datepicker')};
};
var createDRP = (el, options) => {
const drp = new DateRangePicker(el, options);
const [picker0, picker1] = document.querySelectorAll('.datepicker');
return {drp, picker0, picker1};
};
var getParts = (picker, selectors) => selectors.map(sel => picker.querySelector(sel));
var getViewSwitch = picker => picker.querySelector('.view-switch');
var getCells = picker => Array.from(picker.querySelectorAll('.datepicker-cell'));
var filterCells = (cells, criteria) => {
const fn = typeof criteria === 'string' ? el => el.matches(criteria) : criteria;
return cells.filter(fn);
};
var getCellIndices = (cells, criteria) => cells.reduce((indices, cell, idx) => {
if (cell.matches(criteria)) {
indices.push(idx);
}
return indices;
}, []);
</script>
<script src="../dist/js/datepicker-full.js"></script>
<script src="../dist/js/locales/fr.js"></script>
<script src="../dist/js/locales/zh-CN.js"></script>
<script src="./Datepicker/Datepicker-object.js"></script>
<script src="./Datepicker/api-methods.js"></script>
<script src="./mouse-operation.js"></script>
<script src="./keyboard-operation/keyboard-operation.js"></script>
<script src="./keyboard-operation/arrow-left.js"></script>
<script src="./keyboard-operation/arrow-right.js"></script>
<script src="./keyboard-operation/arrow-up.js"></script>
<script src="./keyboard-operation/arrow-down.js"></script>
<script src="./keyboard-operation/edit-mode.js"></script>
<script src="./events.js"></script>
<script src="./options/options.js"></script>
<script src="./options/date-restrictions.js"></script>
<script src="./options/buttons.js"></script>
<script src="./options/format.js"></script>
<script src="./options/multidate.js"></script>
<script src="./options/pick-levle+view.js"></script>
<script src="./options/orientation.js"></script>
<script src="./options/before-show.js"></script>
<script src="./inline-mode.js"></script>
<script src="./DateRangePicker/DateRangePicker.js"></script>
<script src="./DateRangePicker/api-methods.js"></script>
<script src="./DateRangePicker/date-selection.js"></script>
<script src="./DateRangePicker/options.js"></script>
<script class="mocha-exec">
mocha.run();
</script>
</body>
</html>

View File

@ -0,0 +1,192 @@
import './_setup.js';
import DateRangePicker from '../../js/DateRangePicker.js';
import {parseHTML} from '../../js/lib/dom.js';
// to spy constructor with sinon, import entire module
// @see: https://github.com/sinonjs/sinon/issues/1358#issuecomment-391643741
import * as DP from '../../js/Datepicker.js';
const Datepicker = DP.default;
describe('DateRangePicker', function () {
let elem;
let input0;
let input1;
beforeEach(function () {
elem = parseHTML('<div><input><input></div>').firstChild;
[input0, input1] = elem.children;
testContainer.appendChild(elem);
});
afterEach(function () {
document.querySelectorAll('.datepicker').forEach((el) => {
el.parentElement.removeChild(el);
});
delete input0.datepicker;
delete input1.datepicker;
delete elem.rangepicker;
testContainer.removeChild(elem);
});
describe('constructor', function () {
it('attachs the created instance to the bound element', function () {
const drp = new DateRangePicker(elem);
expect(elem.rangepicker, 'to be', drp);
});
it('configures the instance with the default values', function () {
let drp = new DateRangePicker(elem);
expect(drp.allowOneSidedRange, 'to be false');
});
it('creates datepicker for the inputs passing rangepicker and given options expect', function () {
const spyDPConstructor = sinon.spy(DP, 'default');
let drp = new DateRangePicker(elem);
expect(spyDPConstructor.args, 'to equal', [
[input0, {}, drp],
[input1, {}, drp],
]);
expect(input0.datepicker, 'to be a', Datepicker);
expect(input1.datepicker, 'to be a', Datepicker);
expect([input0.datepicker, input1.datepicker], 'to equal', drp.datepickers);
spyDPConstructor.resetHistory();
delete input0.datepicker;
delete input1.datepicker;
delete elem.rangepicker;
const fakeOptions = {foo: 123, bar: 456};
drp = new DateRangePicker(elem, fakeOptions);
expect(spyDPConstructor.args, 'to equal', [
[input0, fakeOptions, drp],
[input1, fakeOptions, drp],
]);
spyDPConstructor.restore();
});
it('makes datepickers property read-only/immutable', function () {
const drp = new DateRangePicker(elem);
expect(() => { drp.datepickers = []; }, 'to throw a', TypeError);
expect(() => { drp.datepickers[0] = null; }, 'to throw a', TypeError);
expect(() => { drp.datepickers[2] = {}; }, 'to throw a', TypeError);
});
it('excludes inputs, allowOneSidedRange and maxNumberOfDates from options to pass Datepicker container', function () {
const spyDPConstructor = sinon.spy(DP, 'default');
new DateRangePicker(elem, {
inputs: [input0, input1],
allowOneSidedRange: false,
maxNumberOfDates: 2,
foo: 123,
});
expect(spyDPConstructor.args[0][1], 'to equal', {foo: 123});
spyDPConstructor.restore();
});
it('works with arbitrary input elements if they are provided in the inputs option', function () {
const outsideEl = document.createElement('div');
const drp = new DateRangePicker(outsideEl, {inputs: [input0, input1]});
expect(outsideEl.rangepicker, 'to be', drp);
expect(input0.datepicker.rangepicker, 'to be', drp);
expect(input1.datepicker.rangepicker, 'to be', drp);
expect([input0.datepicker, input1.datepicker], 'to equal', drp.datepickers);
});
it('append datepicker elements to the container)', function () {
new DateRangePicker(elem);
const dpElems = Array.from(document.body.children).filter(el => el.matches('.datepicker'));
expect(dpElems, 'to have length', 2);
});
it('does not add the active class to the picker elements', function () {
new DateRangePicker(elem);
const dpElems = Array.from(document.querySelectorAll('.datepicker'));
expect(dpElems.filter(el => el.classList.contains('active')), 'to be empty');
});
it('does nothing but creating an instance if number of inputs < 2', function () {
elem.removeChild(input1);
let drp = new DateRangePicker(elem);
expect(elem, 'not to have property', 'rangepicker');
expect(drp, 'not to have properties', ['inputs', 'datepickers']);
expect(input0, 'not to have property', 'datepicker');
expect(document.querySelectorAll('.datepicker').length, 'to be', 0);
const outsideEl = document.createElement('div');
drp = new DateRangePicker(outsideEl, {inputs: [input0]});
expect(outsideEl, 'not to have property', 'rangepicker');
expect(input0, 'not to have property', 'datepicker');
expect(document.querySelectorAll('.datepicker').length, 'to be', 0);
});
});
describe('destroy()', function () {
let drp;
let spyDestroy0;
let spyDestroy1;
beforeEach(function () {
drp = new DateRangePicker(elem);
spyDestroy0 = sinon.spy(input0.datepicker, 'destroy');
spyDestroy1 = sinon.spy(input1.datepicker, 'destroy');
});
afterEach(function () {
spyDestroy0.restore();
spyDestroy1.restore();
});
it('calls destroy() of each datepickers', function () {
drp.destroy();
expect(spyDestroy0.called, 'to be true');
expect(spyDestroy1.called, 'to be true');
});
it('removes the instance from the bound element', function () {
drp.destroy();
expect(Object.prototype.hasOwnProperty.call(elem, 'rangepicker'), 'to be false');
});
});
describe('dates property', function () {
it('contains the array of the inputs\' selected dates', function () {
const drp = new DateRangePicker(elem);
expect(drp.dates, 'to equal', [undefined, undefined]);
const date0 = new Date(2020, 3, 20).setHours(0, 0, 0, 0);
const date1 = new Date(2020, 3, 22).setHours(0, 0, 0, 0);
drp.datepickers[0].dates = [date0];
drp.datepickers[1].dates = [date1];
expect(drp.dates, 'to equal', [date0, date1]);
});
});
describe('setOptions()', function () {
it('updates allowOneSidedRange but ignores inputs if they are in the given options', function () {
const input2 = document.createElement('input');
const drp = new DateRangePicker(elem);
drp.setOptions({allowOneSidedRange: true, inputs: [input2, input0]});
expect(drp.allowOneSidedRange, 'to be true');
expect(drp.inputs, 'to equal', [input0, input1]);
});
it('calls each datepicker\'s setOptions() with given options except inputs, allowOneSidedRange and maxNumberOfDates', function () {
const drp = new DateRangePicker(elem);
const stubDP0SetOptions = sinon.stub(drp.datepickers[0], 'setOptions').callsFake(() => {});
const stubDP1SetOptions = sinon.stub(drp.datepickers[1], 'setOptions').callsFake(() => {});
drp.setOptions({inputs: [], allowOneSidedRange: true, maxNumberOfDates: 2, foo: 123, bar: 456});
expect(stubDP0SetOptions.args, 'to equal', [[{foo: 123, bar: 456}]]);
expect(stubDP1SetOptions.args, 'to equal', [[{foo: 123, bar: 456}]]);
});
});
});

View File

@ -0,0 +1,307 @@
import './_setup.js';
import Datepicker from '../../js/Datepicker.js';
import defaultOptions from '../../js/options/defaultOptions.js';
import {locales} from '../../js/i18n/base-locales.js';
import {dateValue, today} from '../../js/lib/date.js';
const esLocale = {
months: ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"],
monthsShort: ["Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic"],
};
describe('Datepicker', function () {
it('has locales attribute with "en" locale', function () {
expect(Datepicker.locales, 'to be an object');
expect(Datepicker.locales.en, 'to equal', locales.en);
});
describe('constructor', function () {
let input;
beforeEach(function () {
input = document.createElement('input');
testContainer.appendChild(input);
});
after(function () {
document.querySelectorAll('.datepicker').forEach((el) => {
el.parentElement.removeChild(el);
});
delete input.datepicker;
testContainer.removeChild(input);
});
it('attachs the created instance to the bound element', function () {
const dp = new Datepicker(input);
expect(input.datepicker, 'to be', dp);
});
it('adds datepicker-input class to the bound element', function () {
new Datepicker(input);
expect(input.classList.contains('datepicker-input'), 'to be true');
});
it('configures the instance with the default options', function () {
const dp = new Datepicker(input);
// config items should be options + container, locale, multidate and weekEnd
const numOfOptions = Object.keys(defaultOptions).length;
expect(Object.keys(dp.config), 'to have length', numOfOptions + 5);
expect(dp.config.autohide, 'to be false');
expect(dp.config.beforeShowDay, 'to be null');
expect(dp.config.beforeShowDecade, 'to be null');
expect(dp.config.beforeShowMonth, 'to be null');
expect(dp.config.beforeShowYear, 'to be null');
expect(dp.config.buttonClass, 'to be', 'button');
expect(dp.config.calendarWeeks, 'to be false');
expect(dp.config.clearBtn, 'to be false');
expect(dp.config.container, 'to be', document.body);
expect(dp.config.dateDelimiter, 'to be', ',');
expect(dp.config.datesDisabled, 'to equal', []);
expect(dp.config.daysOfWeekDisabled, 'to equal', []);
expect(dp.config.daysOfWeekHighlighted, 'to equal', []);
expect(dp.config.defaultViewDate, 'to be', today());
expect(dp.config.disableTouchKeyboard, 'to be false');
expect(dp.config.format, 'to be', 'mm/dd/yyyy');
expect(dp.config.language, 'to be', 'en');
expect(dp.config.locale, 'to equal', Object.assign({
format: defaultOptions.format,
weekStart: defaultOptions.weekStart,
}, locales.en));
expect(dp.config.maxDate, 'to be undefined');
expect(dp.config.maxNumberOfDates, 'to be', 1);
expect(dp.config.maxView, 'to be', 3);
expect(dp.config.minDate, 'to be', dateValue(0, 0, 1));
expect(dp.config.multidate, 'to be false');
//
expect(dp.config.nextArrow, 'to be a', NodeList);
expect(dp.config.nextArrow.length, 'to be', 1);
expect(dp.config.nextArrow[0].wholeText, 'to be', '»');
//
expect(dp.config.orientation, 'to equal', {x: 'auto', y: 'auto'});
expect(dp.config.pickLevel, 'to be', 0);
//
expect(dp.config.prevArrow, 'to be a', NodeList);
expect(dp.config.prevArrow.length, 'to be', 1);
expect(dp.config.prevArrow[0].wholeText, 'to be', '«');
//
expect(dp.config.showDaysOfWeek, 'to be true');
expect(dp.config.showOnFocus, 'to be true');
expect(dp.config.startView, 'to be', 0);
expect(dp.config.title, 'to be', '');
expect(dp.config.todayBtn, 'to be false');
expect(dp.config.todayHighlight, 'to be false');
expect(dp.config.updateOnBlur, 'to be true');
expect(dp.config.weekStart, 'to be', 0);
expect(dp.config.weekEnd, 'to be', 6);
});
it('append datepicker element to the container)', function () {
new Datepicker(input);
const dpElem = Array.from(document.body.children).find(el => el.matches('.datepicker'));
expect(dpElem, 'not to be undefined');
});
it('does not add the active class to the picker element', function () {
new Datepicker(input);
const dpElem = document.querySelector('.datepicker');
expect(dpElem.classList.contains('active'), 'to be false');
});
it('sets rangepicker properties if DateRangePicker to link is passed', function () {
const fakeRangepicker = {
inputs: [input],
datepickers: [],
};
const dp = new Datepicker(input, {}, fakeRangepicker);
expect(dp.rangepicker, 'to be', fakeRangepicker);
});
it('adds itself to rangepicker.datepickers if DateRangePicker to link is passed', function () {
let fakeRangepicker = {
inputs: [input],
datepickers: [],
};
let dp = new Datepicker(input, {}, fakeRangepicker);
expect(fakeRangepicker.datepickers[0], 'to be', dp);
fakeRangepicker = {
inputs: [undefined, input],
datepickers: [],
};
dp = new Datepicker(input, {}, fakeRangepicker);
expect(fakeRangepicker.datepickers[1], 'to be', dp);
});
it('throws an error if invalid rangepicker is passed', function () {
const testFn = rangepicker => new Datepicker(input, {}, rangepicker);
const errMsg = 'Invalid rangepicker object.';
let fakeRangepicker = {
inputs: [],
datepickers: [],
};
expect(() => testFn(fakeRangepicker), 'to throw', errMsg);
fakeRangepicker = {
inputs: ['foo', 'bar', input],
datepickers: [],
};
expect(() => testFn(fakeRangepicker), 'to throw', errMsg);
fakeRangepicker = {
inputs: [input],
};
expect(() => testFn(fakeRangepicker), 'to throw', errMsg);
});
});
describe('destroy()', function () {
let input;
let dp;
let spyHide;
let returnVal;
before(function () {
input = document.createElement('input');
testContainer.appendChild(input);
dp = new Datepicker(input);
spyHide = sinon.spy(dp, 'hide');
returnVal = dp.destroy();
});
after(function () {
spyHide.restore();
document.querySelectorAll('.datepicker').forEach((el) => {
el.parentElement.removeChild(el);
});
delete input.datepicker;
testContainer.removeChild(input);
});
it('calls hide()', function () {
expect(spyHide.called, 'to be true');
});
it('removes datepicker element from its container', function () {
expect(document.body.querySelectorAll('.datepicker').length, 'to be', 0);
});
it('removes the instance from the bound element', function () {
expect(Object.prototype.hasOwnProperty.call(input, 'datepicker'), 'to be false');
});
it('removes datepicker-input class from the bound element', function () {
expect(input.classList.contains('datepicker-input'), 'to be false');
});
it('returns the instance', function () {
expect(returnVal, 'to be', dp);
});
});
describe('show()', function () {
let input;
let dp;
let dpElem;
before(function () {
input = document.createElement('input');
testContainer.appendChild(input);
dp = new Datepicker(input);
dpElem = document.querySelector('.datepicker');
dp.show();
});
after(function () {
dp.destroy();
testContainer.removeChild(input);
});
it('adds the "active" class to the datepicker element', function () {
expect(dpElem.classList.contains('active'), 'to be true');
});
it('sets true to the picker.active property', function () {
expect(dp.picker.active, 'to be true');
});
});
describe('hide()', function () {
let input;
let dp;
let dpElem;
before(function () {
input = document.createElement('input');
testContainer.appendChild(input);
dp = new Datepicker(input);
dpElem = document.querySelector('.datepicker');
dp.picker.active = true;
dpElem.classList.add('active', 'block');
dp.hide();
});
after(function () {
dp.destroy();
testContainer.removeChild(input);
});
it('removes the "active" class from the datepicker element', function () {
expect(dpElem.classList.contains('active'), 'to be false');
});
it('deletes the "picker.active" property', function () {
expect(dp.picker, 'to have property', 'active');
});
});
describe('static formatDate()', function () {
it('formats a date or time value', function () {
Datepicker.locales.es = esLocale;
let date = new Date(2020, 0, 4);
expect(Datepicker.formatDate(date, 'y-m-d'), 'to be', '2020-1-4');
expect(Datepicker.formatDate(date.getTime(), 'dd M yy'), 'to be', '04 Jan 20');
expect(Datepicker.formatDate(date, 'dd M yy', 'es'), 'to be', '04 Ene 20');
expect(Datepicker.formatDate(date.getTime(), 'MM d, y', 'es'), 'to be', 'Enero 4, 2020');
delete Datepicker.locales.es;
// fallback to en
expect(Datepicker.formatDate(date, 'dd M yy', 'es'), 'to be', '04 Jan 20');
expect(Datepicker.formatDate(date.getTime(), 'MM d, y', 'es'), 'to be', 'January 4, 2020');
});
});
describe('static parseDate()', function () {
it('parses a date string and returnes the time value of the date', function () {
Datepicker.locales.es = esLocale;
let timeValue = new Date(2020, 0, 4).getTime();
expect(Datepicker.parseDate('2020-1-4', 'y-m-d'), 'to be', timeValue);
expect(Datepicker.parseDate('04 Jan 2020', 'dd M yy'), 'to be', timeValue);
expect(Datepicker.parseDate('04 Ene 2020', 'dd M yy', 'es'), 'to be', timeValue);
expect(Datepicker.parseDate('Enero 4, 2020', 'MM d, y', 'es'), 'to be', timeValue);
expect(Datepicker.parseDate('04/20/2022', 'mm/dd/yyyy'), 'to equal', new Date(2022, 3, 20).getTime());
expect(Datepicker.parseDate('5/3/1994', 'd/m/y'), 'to equal', new Date(1994, 2, 5).getTime());
delete Datepicker.locales.es;
// fallback to en
const fallbackDate = new Date(timeValue).setMonth(new Date().getMonth());
expect(Datepicker.parseDate('04 Ene 2020', 'dd M yy', 'es'), 'to be', fallbackDate);
expect(Datepicker.parseDate('Enero 4, 2020', 'MM d, y', 'es'), 'to be', fallbackDate);
expect(Datepicker.parseDate('04 Jan 2020', 'dd M yy', 'es'), 'to be', timeValue);
expect(Datepicker.parseDate('2020-1-4', 'y-m-d', 'es'), 'to be', timeValue);
});
});
});

28
node_modules/flowbite-datepicker/test/unit/_setup.js generated vendored Normal file
View File

@ -0,0 +1,28 @@
global.expect = require('unexpected');
global.sinon = require('sinon');
const jsdom = require('jsdom');
const {JSDOM} = jsdom;
const {window} = new JSDOM('<body><div id="test-container"></div></body>', {
pretendToBeVisual: true
});
const document = window.document;
global.JSDOM = JSDOM;
global.window = window;
global.testContainer = document.getElementById('test-container');
const exposeToGlobal = [
'document',
'CustomEvent',
'DocumentFragment',
'Event',
'EventTarget',
'NodeList',
'Range',
];
exposeToGlobal.forEach((prop) => {
global[prop] = window[prop];
});
global.simulant = require('simulant');

View File

@ -0,0 +1,310 @@
import '../_setup.js';
import {parseDate, formatDate} from '../../../js/lib/date-format.js';
describe('lib/date', function () {
const locales = {
en: {
days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
today: "Today",
clear: "Clear",
titleFormat: "MM yyyy"
},
de: {
days: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"],
daysShort: ["Son", "Mon", "Die", "Mit", "Don", "Fre", "Sam"],
months: ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"],
monthsShort: ["Jan", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"],
},
es: {
days: ["Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado"],
daysShort: ["Dom", "Lun", "Mar", "Mié", "Jue", "Vie", "Sáb"],
months: ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"],
monthsShort: ["Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic"],
},
fr: {
days: ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"],
daysShort: ["dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam."],
daysMin: ["d", "l", "ma", "me", "j", "v", "s"],
months: ["janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"],
monthsShort: ["janv.", "févr.", "mars", "avril", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc."],
}
};
describe('parseDate()', function () {
const today = new Date().setHours(0, 0, 0, 0);
const thisYear = new Date().getFullYear();
it('return undefined if the given date is falsy value other than 0 or invalid date', function () {
expect(parseDate(), 'to be undefined');
expect(parseDate(''), 'to be undefined');
expect(parseDate(new Date('')), 'to be undefined');
expect(parseDate(0), 'not to be undefined');
});
it('returns time value of the same day\'s 00:00:00 local time if the given date is a Date object or time value', function () {
const origDate = new Date().setHours(0, 0, 0, 0);
expect(parseDate(new Date()), 'to be', origDate);
expect(parseDate(Date.now()), 'to be', origDate);
});
it('invokes custom parse fucntion and returns the result if it\'s given to format.toValue', function () {
const date = new Date();
const format = {toValue: sinon.stub()};
format.toValue.returns(date);
expect(parseDate('2020-01-01', format, locales.en), 'to be', date.setHours(0, 0, 0, 0));
expect(format.toValue.calledWith('2020-01-01', format, locales.en), 'to be true');
});
it('returns the date that the word means if given date is "today"', function () {
expect(parseDate('today'), 'to be', today);
});
it('uses format: "d" or "dd" as day of month to parse date string', function () {
expect(parseDate('2012-03-5', 'yyyy-mm-d'), 'to be', new Date(2012, 2, 5).getTime());
expect(parseDate('2012-03-15', 'yyyy-mm-d'), 'to be', new Date(2012, 2, 15).getTime());
expect(parseDate('2012-03-05', 'yyyy-mm-d'), 'to be', new Date(2012, 2, 5).getTime());
expect(parseDate('2012-03-5', 'yyyy-mm-dd'), 'to be', new Date(2012, 2, 5).getTime());
expect(parseDate('2012-03-15', 'yyyy-mm-dd'), 'to be', new Date(2012, 2, 15).getTime());
expect(parseDate('2012-03-05', 'yyyy-mm-dd'), 'to be', new Date(2012, 2, 5).getTime());
expect(parseDate('5/03/2012', 'dd/mm/yyyy'), 'to be', new Date(2012, 2, 5).getTime());
expect(parseDate('15/03/2012', 'd/mm/yyyy'), 'to be', new Date(2012, 2, 15).getTime());
});
it('accepts 0 and number larger than the end of the month for "d", "dd"', function () {
expect(parseDate('2012-03-0', 'yyyy-mm-d'), 'to be', new Date(2012, 1, 29).getTime());
expect(parseDate('2012-03-33', 'yyyy-mm-d'), 'to be', new Date(2012, 3, 2).getTime());
expect(parseDate('2013-02-60', 'yyyy-mm-d'), 'to be', new Date(2013, 3, 1).getTime());
});
it('uses format: "m", "mm", "M" or "MM" as month to parse date string', function () {
const fakeToday = new Date(thisYear, 2, 31);
const clock = sinon.useFakeTimers({now: fakeToday});
// month number
expect(parseDate('2012-3-5', 'yyyy-m-d'), 'to be', new Date(2012, 2, 5).getTime());
expect(parseDate('2012-12-15', 'yyyy-m-d'), 'to be', new Date(2012, 11, 15).getTime());
expect(parseDate('2012-03-05', 'yyyy-m-d'), 'to be', new Date(2012, 2, 5).getTime());
expect(parseDate('2012-3-5', 'yyyy-mm-dd'), 'to be', new Date(2012, 2, 5).getTime());
expect(parseDate('2012-12-15', 'yyyy-mm-dd'), 'to be', new Date(2012, 11, 15).getTime());
expect(parseDate('2012-03-05', 'yyyy-mm-dd'), 'to be', new Date(2012, 2, 5).getTime());
expect(parseDate('5/3/2012', 'dd/mm/yyyy'), 'to be', new Date(2012, 2, 5).getTime());
expect(parseDate('15/12/2012', 'd/m/yyyy'), 'to be', new Date(2012, 11, 15).getTime());
// ensure setting a month w/ < 31days on the 31 of a month works correctly
expect(parseDate('2012-02-28', 'yyyy-mm-dd'), 'to be', new Date(2012, 1, 28).getTime());
expect(parseDate('2012-09-15', 'yyyy-mm-dd'), 'to be', new Date(2012, 8, 15).getTime());
// month name
expect(parseDate('Mar 5, 2012', 'M d, yyyy', locales.en), 'to be', new Date(2012, 2, 5).getTime());
expect(parseDate('Dec 15, 2012', 'M d, yyyy', locales.en), 'to be', new Date(2012, 11, 15).getTime());
expect(parseDate('Mär 5, 2012', 'M d, yyyy', locales.de), 'to be', new Date(2012, 2, 5).getTime());
expect(parseDate('Dez 15, 2012', 'M d, yyyy', locales.de), 'to be', new Date(2012, 11, 15).getTime());
expect(parseDate('mars 5, 2012', 'M d, yyyy', locales.fr), 'to be', new Date(2012, 2, 5).getTime());
expect(parseDate('déc. 15, 2012', 'M d, yyyy', locales.fr), 'to be', new Date(2012, 11, 15).getTime());
expect(parseDate('March 5, 2012', 'MM d, yyyy', locales.en), 'to be', new Date(2012, 2, 5).getTime());
expect(parseDate('December 15, 2012', 'MM d, yyyy', locales.en), 'to be', new Date(2012, 11, 15).getTime());
expect(parseDate('März 5, 2012', 'MM d, yyyy', locales.de), 'to be', new Date(2012, 2, 5).getTime());
expect(parseDate('Dezember 15, 2012', 'MM d, yyyy', locales.de), 'to be', new Date(2012, 11, 15).getTime());
expect(parseDate('mars 5, 2012', 'MM d, yyyy', locales.fr), 'to be', new Date(2012, 2, 5).getTime());
expect(parseDate('décembre 15, 2012', 'MM d, yyyy', locales.fr), 'to be', new Date(2012, 11, 15).getTime());
// month number for "M" and "MM"
expect(parseDate('3/5/2012', 'M/dd/yyyy', locales.en), 'to be', new Date(2012, 2, 5).getTime());
expect(parseDate('12/15/2012', 'MM/dd/yyyy', locales.en), 'to be', new Date(2012, 11, 15).getTime());
// month name for "m" and "mm"
expect(parseDate('Mar/5/2012', 'm/d/yyyy', locales.en), 'to be', new Date(2012, 2, 5).getTime());
expect(parseDate('December/15/2012', 'mm/dd/yyyy', locales.en), 'to be', new Date(2012, 11, 15).getTime());
clock.restore();
});
it('accepts 0 and number larger than 12 for "m", "mm"', function () {
const fakeToday = new Date(thisYear, 2, 31);
const clock = sinon.useFakeTimers({now: fakeToday});
expect(parseDate('2012-0-05', 'yyyy-m-dd'), 'to be', new Date(2011, 11, 5).getTime());
expect(parseDate('2012-16-30', 'yyyy-m-d'), 'to be', new Date(2013, 3, 30).getTime());
expect(parseDate('2012-32-30', 'yyyy-m-d'), 'to be', new Date(2014, 7, 30).getTime());
clock.restore();
});
it('evaluates month name with case-insensible begin-with match', function () {
const fakeToday = new Date(thisYear, 2, 31);
const clock = sinon.useFakeTimers({now: fakeToday});
expect(parseDate('march 5, 2012', 'M d, yyyy', locales.en), 'to be', new Date(2012, 2, 5).getTime());
expect(parseDate('DEC 15, 2012', 'MM d, yyyy', locales.en), 'to be', new Date(2012, 11, 15).getTime());
expect(parseDate('MA 5, 2012', 'MM d, yyyy', locales.en), 'to be', new Date(2012, 2, 5).getTime());
expect(parseDate('j 5, 2012', 'MM d, yyyy', locales.en), 'to be', new Date(2012, 0, 5).getTime());
expect(parseDate('ju 5, 2012', 'MM d, yyyy', locales.en), 'to be', new Date(2012, 5, 5).getTime());
expect(parseDate('march/5/2012', 'm/d/yyyy', locales.en), 'to be', new Date(2012, 2, 5).getTime());
expect(parseDate('DEC/15/2012', 'mm/dd/yyyy', locales.en), 'to be', new Date(2012, 11, 15).getTime());
expect(parseDate('MA/05/2012', 'mm/dd/yyyy', locales.en), 'to be', new Date(2012, 2, 5).getTime());
expect(parseDate('j/05/2012', 'mm/dd/yyyy', locales.en), 'to be', new Date(2012, 0, 5).getTime());
expect(parseDate('ju/05/2012', 'mm/dd/yyyy', locales.en), 'to be', new Date(2012, 5, 5).getTime());
clock.restore();
});
it('uses format: "y", "yy" or "yyyy" as year to parse date string', function () {
expect(parseDate('2012-3-5', 'y-m-d'), 'to be', new Date(2012, 2, 5).getTime());
expect(parseDate('1984-3-15', 'y-m-d'), 'to be', new Date(1984, 2, 15).getTime());
expect(parseDate('12-03-05', 'y-m-d'), 'to be', new Date(0, 2, 5).setFullYear(12));
expect(parseDate('2012-3-5', 'yy-m-d'), 'to be', new Date(2012, 2, 5).getTime());
expect(parseDate('1984-3-15', 'yy-m-d'), 'to be', new Date(1984, 2, 15).getTime());
expect(parseDate('12-03-05', 'yy-m-d'), 'to be', new Date(0, 2, 5).setFullYear(12));
expect(parseDate('2012-03-5', 'yyyy-mm-dd'), 'to be', new Date(2012, 2, 5).getTime());
expect(parseDate('1984-03-15', 'yyyy-mm-dd'), 'to be', new Date(1984, 2, 15).getTime());
expect(parseDate('12-03-05', 'yyyy-mm-dd'), 'to be', new Date(0, 2, 5).setFullYear(12));
expect(parseDate('5/03/2012', 'dd/mm/yyyy'), 'to be', new Date(2012, 2, 5).getTime());
expect(parseDate('15/03/1984', 'd/m/yy'), 'to be', new Date(1984, 2, 15).getTime());
});
it('ignores "D" and "DD" (day of week)', function () {
let date = parseDate('2012-03-05', 'yyyy-mm-dd-D');
expect(date, 'to be', new Date(2012, 2, 5).getTime());
date = parseDate('Sat, Dec 15, 2012', 'DD, M dd, yyyy', locales.en);
expect(date, 'to be', new Date(2012, 11, 15).getTime());
});
it('uses current date\'s year/month/day to complement undefined, missing or unparsable parts', function () {
const fakeToday = new Date(thisYear, 2, 31);
const clock = sinon.useFakeTimers({now: fakeToday});
expect(parseDate('03-05', 'mm-dd'), 'to be', new Date(thisYear, 2, 5).getTime());
expect(parseDate('2012-06', 'yyyy-mm'), 'to be', new Date(2012, 5, 30).getTime());
expect(parseDate('5, 2012', 'd, yyyy'), 'to be', new Date(2012, 2, 5).getTime());
expect(parseDate('Mai/10', 'M/d', locales.en), 'to be', new Date(thisYear, 2, 10).getTime());
expect(parseDate('Maya/10', 'M/d', locales.en), 'to be', new Date(thisYear, 2, 10).getTime());
expect(parseDate('03-05', 'yyyy-mm-dd'), 'to be', new Date(0, 4, 31).setFullYear(3));
expect(parseDate('Sun, 23', 'DD, mm-dd'), 'to be', new Date(thisYear + 1, 10, 30).getTime());
expect(parseDate('Mar/05/12', 'yyyy/mm/dd', locales.en), 'to be', new Date(thisYear, 4, 12).getTime());
expect(parseDate('05/Mar/12', 'yyyy/mm/dd', locales.en), 'to be', new Date(0, 2, 12).setFullYear(5));
expect(parseDate('2012年十二月十五日', 'yyyy年mm月dd日', locales.en), 'to be', new Date(2012, 2, 31).getTime());
clock.restore();
});
it('throws an Error if format is neither a valid format string nor an object w/ toValue property', function () {
expect(() => parseDate('01-01-01', {}), 'to throw error');
expect(() => parseDate('01-01-01', 1), 'to throw error');
expect(() => parseDate('01-01-01', 'aa-bb-cc'), 'to throw error');
});
});
describe('formatDate()', function () {
it('return empty string if the given date is falsy value other than 0 or invalid date', function () {
expect(formatDate(), 'to be', '');
expect(formatDate(''), 'to be', '');
expect(formatDate(new Date('')), 'to be', '');
expect(formatDate(0, 'yyyy', locales.en), 'not to be', '');
});
it('invokes custom format fucntion and returns the result if it\'s given to format.toDisplay', function () {
const date = new Date(2012, 2, 5);
const format = {toDisplay: sinon.stub()};
format.toDisplay.returns('foo-bar');
expect(formatDate(date, format, locales.en), 'to be', 'foo-bar');
expect(format.toDisplay.calledWith(date, format, locales.en), 'to be true');
});
it('uses format: "d" as day of month, no leading zero to format date', function () {
expect(formatDate(new Date(2012, 2, 5), 'yyyy-mm-d', locales.en), 'to be', '2012-03-5');
expect(formatDate(0, 'd', locales.en), 'to be', String(new Date(0).getDate()));
});
it('uses format: "dd" as day of month, leading zero to format date', function () {
const date = new Date(2012, 2, 5);
expect(formatDate(date, 'yyyy-mm-dd', locales.en), 'to be', '2012-03-05');
expect(formatDate(date.getTime(), 'yyyy-mm-dd', locales.en), 'to be', '2012-03-05');
});
it('uses format: "D" as short day of week in given language to format date', function () {
const date = new Date(2012, 2, 5);
expect(formatDate(date, 'yyyy-mm-dd-D', locales.en), 'to be', '2012-03-05-Mon');
expect(formatDate(date, 'yyyy-mm-dd-D', locales.es), 'to be', '2012-03-05-Lun');
});
it('uses format: "DD" as long day of week in given language to format date', function () {
const date = new Date(2012, 2, 5);
expect(formatDate(date, 'yyyy-mm-dd-DD', locales.en), 'to be', '2012-03-05-Monday');
expect(formatDate(date, 'yyyy-mm-dd-DD', locales.es), 'to be', '2012-03-05-Lunes');
});
it('uses format: "m" as Month, no leading zero. to format date', function () {
expect(formatDate(new Date(2012, 2, 5), 'yyyy-m-dd', locales.en), 'to be', '2012-3-05');
});
it('uses format: "mm" as Month, leading zero. to format date', function () {
expect(formatDate(new Date(2012, 2, 5), 'yyyy-mm-dd', locales.en), 'to be', '2012-03-05');
});
it('uses format: "M" as month shortname in given language to format date', function () {
const date = new Date(2012, 2, 5);
expect(formatDate(date, 'yyyy-M-dd', locales.en), 'to be', '2012-Mar-05');
expect(formatDate(date, 'yyyy-M-dd', locales.de), 'to be', '2012-Mär-05');
});
it('uses format: "MM" as month full name in given language to format date', function () {
const date = new Date(2012, 2, 5);
expect(formatDate(date, 'yyyy-MM-dd', locales.en), 'to be', '2012-March-05');
expect(formatDate(date, 'yyyy-MM-dd', locales.de), 'to be', '2012-März-05');
});
it('uses format: "y" as Year, no leading zero. to format date', function () {
expect(formatDate(new Date(0, 2, 5).setFullYear(2), 'y-m-d', locales.en), 'to be', '2-3-5');
expect(formatDate(new Date(0, 2, 5).setFullYear(12), 'y-m-d', locales.en), 'to be', '12-3-5');
expect(formatDate(new Date(2012, 2, 5), 'y-m-d', locales.en), 'to be', '2012-3-5');
});
it('uses format: "yy" as Year, two-digit. to format date', function () {
expect(formatDate(new Date(0, 2, 5).setFullYear(2), 'yy-mm-dd', locales.en), 'to be', '02-03-05');
expect(formatDate(new Date(0, 2, 5).setFullYear(12), 'yy-mm-dd', locales.en), 'to be', '12-03-05');
expect(formatDate(new Date(2012, 2, 5), 'yy-mm-dd', locales.en), 'to be', '12-03-05');
});
it('uses format: "yyyy" as Year, four-digit. to format date', function () {
expect(formatDate(new Date(0, 2, 5).setFullYear(2), 'yyyy-mm-dd', locales.en), 'to be', '0002-03-05');
expect(formatDate(new Date(0, 2, 5).setFullYear(12), 'yyyy-mm-dd', locales.en), 'to be', '0012-03-05');
expect(formatDate(new Date(2012, 2, 5), 'yyyy-mm-dd', locales.en), 'to be', '2012-03-05');
});
it('accepts separators come before and after the date numbers', function () {
expect(formatDate(new Date(2012, 2, 5), '西暦yyyy年mm月dd日', locales.en), 'to be', '西暦2012年03月05日');
});
it('throws an Error if format is neither a valid format string nor an object w/ toValue property', function () {
const date = new Date(2012, 2, 5);
expect(() => formatDate(date, {}), 'to throw error');
expect(() => formatDate(date, 1), 'to throw error');
expect(() => formatDate(date, 'aa-bb-cc'), 'to throw error');
});
});
});

211
node_modules/flowbite-datepicker/test/unit/lib/date.js generated vendored Normal file
View File

@ -0,0 +1,211 @@
import '../_setup.js';
import {
stripTime,
dateValue,
today,
addDays,
addWeeks,
addMonths,
addYears,
dayOfTheWeekOf,
getWeek,
startOfYearPeriod
} from '../../../js/lib/date.js';
describe('lib/date', function () {
describe('stripTime()', function () {
it('returns the time value of 00:00:00 local time of given time value or date', function () {
let origDate = new Date(2016, 8, 24, 13, 55, 32, 235);
expect(stripTime(origDate.getTime()), 'to be', new Date(2016, 8, 24).getTime());
origDate = new Date(2019, 1, 14, 20, 55);
expect(stripTime(origDate), 'to be', new Date(2019, 1, 14).getTime());
});
});
describe('today()', function () {
it('returns the time value of 00:00:00 local time of current date', function () {
const now = new Date();
const timeValue = today();
expect(timeValue, 'to be', now.setHours(0, 0, 0, 0));
});
});
describe('dateValue()', function () {
it('returns the time value of 00:00:00 local time of the date created by given Date constructor parameters', function () {
// from Date object
let origDate = new Date(2016, 8, 24, 13, 55, 32, 235);
let timeValue = dateValue(origDate);
expect(timeValue, 'to be', new Date(2016, 8, 24).getTime());
// from Date constructor args
timeValue = dateValue(2019, 1, 17, 9, 43, 18, 953);
expect(timeValue, 'to be', new Date(2019, 1, 17).getTime());
// from string
let origDateStr = '2020-04-20T02:27:15Z';
origDate = new Date(origDateStr);
timeValue = dateValue(origDateStr);
expect(timeValue, 'to be', origDate.setHours(0, 0, 0, 0));
// from time value
origDate = new Date(2016, 8, 24, 13, 55, 32, 235);
timeValue = dateValue(origDate.getTime());
expect(timeValue, 'to be', new Date(2016, 8, 24).getTime());
});
it('does not map 2-digit year to 1900\'s', function () {
let date = new Date(dateValue(86, 8, 24));
expect(date.getFullYear(), 'to be', 86);
expect(date.getMonth(), 'to be', 8);
expect(date.getDate(), 'to be', 24);
date = new Date(dateValue(19, 1, 17));
expect(date.getFullYear(), 'to be', 19);
expect(date.getMonth(), 'to be', 1);
expect(date.getDate(), 'to be', 17);
});
});
describe('addDays()', function () {
it('returns the time value of N days after a date or time value', function () {
let date1 = new Date(2019, 11, 31);
let date2 = addDays(date1, 1);
expect(date2, 'to be', new Date(2020, 0, 1).getTime());
expect(addDays(date2, 30), 'to be', new Date(2020, 0, 31).getTime());
date1 = new Date(2020, 0, 1);
expect(addDays(date1, -1), 'to be', new Date(2019, 11, 31).getTime());
expect(addDays(date1, -10), 'to be', new Date(2019, 11, 22).getTime());
});
});
describe('addWeeks()', function () {
it('returns the time value of N weeks after a date or time value', function () {
let date1 = new Date(2019, 11, 28);
let date2 = addWeeks(date1, 1);
expect(date2, 'to be', new Date(2020, 0, 4).getTime());
expect(addWeeks(date2, 4), 'to be', new Date(2020, 1, 1).getTime());
date1 = new Date(2020, 0, 4);
expect(addWeeks(date1, -1), 'to be', new Date(2019, 11, 28).getTime());
expect(addWeeks(date1, -8), 'to be', new Date(2019, 10, 9).getTime());
});
});
describe('addMonths()', function () {
it('returns the time value of N months after a date or time value', function () {
let date1 = new Date(2019, 11, 31);
let date2 = addMonths(date1, 1);
expect(date2, 'to be', new Date(2020, 0, 31).getTime());
expect(addMonths(date2, 29), 'to be', new Date(2022, 5, 30).getTime());
date1 = new Date(2020, 0, 1);
expect(addMonths(date1, -1), 'to be', new Date(2019, 11, 1).getTime());
expect(addMonths(date1, -18), 'to be', new Date(2018, 6, 1).getTime());
});
it('returns the end of the next/prev month if the day of the old date is not in the new month', function () {
let date = new Date(2019, 9, 31);
expect(addMonths(date, 1), 'to be', new Date(2019, 10, 30).getTime());
expect(addMonths(date, 18), 'to be', new Date(2021, 3, 30).getTime());
date = new Date(2019, 11, 31);
expect(addMonths(date, -1), 'to be', new Date(2019, 10, 30).getTime());
expect(addMonths(date, -30), 'to be', new Date(2017, 5, 30).getTime());
date = new Date(2019, 0, 31);
expect(addMonths(date, 1), 'to be', new Date(2019, 1, 28).getTime());
expect(addMonths(date, 13), 'to be', new Date(2020, 1, 29).getTime());
date = new Date(2020, 0, 31);
expect(addMonths(date, 1), 'to be', new Date(2020, 1, 29).getTime());
expect(addMonths(date, 13), 'to be', new Date(2021, 1, 28).getTime());
date = new Date(2019, 2, 30);
expect(addMonths(date, -1), 'to be', new Date(2019, 1, 28).getTime());
expect(addMonths(date, -37), 'to be', new Date(2016, 1, 29).getTime());
date = new Date(2020, 2, 30);
expect(addMonths(date, -1), 'to be', new Date(2020, 1, 29).getTime());
expect(addMonths(date, -37), 'to be', new Date(2017, 1, 28).getTime());
date = new Date(2020, 1, 29);
expect(addMonths(date, 12), 'to be', new Date(2021, 1, 28).getTime());
expect(addMonths(date, -24), 'to be', new Date(2018, 1, 28).getTime());
});
});
describe('addYears()', function () {
it('returns the time value of N years after a date or time value', function () {
let date1 = new Date(2019, 11, 31);
let date2 = addYears(date1, 1);
expect(date2, 'to be', new Date(2020, 11, 31).getTime());
expect(addYears(date2, 3), 'to be', new Date(2023, 11, 31).getTime());
date1 = new Date(2020, 0, 1);
expect(addYears(date1, -1), 'to be', new Date(2019, 0, 1).getTime());
expect(addYears(date1, -3), 'to be', new Date(2017, 0, 1).getTime());
});
it('returns 2/28 of the year if the old date is 2/29 and the new year is not a leap year', function () {
const date = new Date(2020, 1, 29);
expect(addYears(date, 1), 'to be', new Date(2021, 1, 28).getTime());
expect(addYears(date, -1), 'to be', new Date(2019, 1, 28).getTime());
expect(addYears(date, -4), 'to be', new Date(2016, 1, 29).getTime());
});
});
describe('dayOfTheWeekOf()', function () {
it('returns a date object of given day of the week of given date', function () {
expect(dayOfTheWeekOf(new Date(2017, 0, 1), 0), 'to be', new Date(2017, 0, 1).getTime());
expect(dayOfTheWeekOf(new Date(2017, 3, 5), 1), 'to be', new Date(2017, 3, 3).getTime());
expect(dayOfTheWeekOf(new Date(2017, 5, 8), 2), 'to be', new Date(2017, 5, 6).getTime());
expect(dayOfTheWeekOf(new Date(2017, 9, 31), 3), 'to be', new Date(2017, 10, 1).getTime());
expect(dayOfTheWeekOf(new Date(2018, 2, 10), 4), 'to be', new Date(2018, 2, 8).getTime());
expect(dayOfTheWeekOf(new Date(2018, 5, 19), 5), 'to be', new Date(2018, 5, 22).getTime());
expect(dayOfTheWeekOf(new Date(2018, 10, 20), 6), 'to be', new Date(2018, 10, 24).getTime());
});
it('uses sepecified start day of week if it is given', function () {
expect(dayOfTheWeekOf(new Date(2017, 0, 1), 0, 1), 'to be', new Date(2017, 0, 1).getTime());
expect(dayOfTheWeekOf(new Date(2017, 3, 5), 1, 3), 'to be', new Date(2017, 3, 10).getTime());
expect(dayOfTheWeekOf(new Date(2017, 5, 8), 2, 4), 'to be', new Date(2017, 5, 13).getTime());
expect(dayOfTheWeekOf(new Date(2017, 9, 31), 3, 6), 'to be', new Date(2017, 10, 1).getTime());
expect(dayOfTheWeekOf(new Date(2018, 2, 10), 4, 5), 'to be', new Date(2018, 2, 15).getTime());
expect(dayOfTheWeekOf(new Date(2018, 5, 19), 5, 2), 'to be', new Date(2018, 5, 22).getTime());
});
});
describe('getWeek()', function () {
it('returns ISO week number of given date', function () {
expect(getWeek(new Date(2015, 0, 1)), 'to be', 1);
expect(getWeek(new Date(2015, 3, 26)), 'to be', 17);
expect(getWeek(new Date(2015, 8, 12)), 'to be', 37);
expect(getWeek(new Date(2015, 10, 15)), 'to be', 46);
expect(getWeek(new Date(2016, 0, 1)), 'to be', 53);
expect(getWeek(new Date(2016, 0, 7)), 'to be', 1);
expect(getWeek(new Date(2016, 6, 21)), 'to be', 29);
expect(getWeek(new Date(2016, 8, 6)), 'to be', 36);
expect(getWeek(new Date(2016, 11, 1)), 'to be', 48);
expect(getWeek(new Date(2017, 0, 1)), 'to be', 52);
});
});
describe('startOfYearPeriod()', function () {
it('returns the start year of given length of period of years', function () {
let date = new Date(2121, 0, 1);
expect(startOfYearPeriod(date, 10), 'to be', 2120);
expect(startOfYearPeriod(date, 100), 'to be', 2100);
expect(startOfYearPeriod(date, 1000), 'to be', 2000);
date = new Date(1984, 0, 1);
expect(startOfYearPeriod(date, 10), 'to be', 1980);
expect(startOfYearPeriod(date, 100), 'to be', 1900);
expect(startOfYearPeriod(date, 1000), 'to be', 1000);
expect(startOfYearPeriod(new Date(738, 5, 30), 20), 'to be', 720);
expect(startOfYearPeriod(new Date(0, 5, 30).setFullYear(88), 25), 'to be', 75);
});
});
});

142
node_modules/flowbite-datepicker/test/unit/lib/dom.js generated vendored Normal file
View File

@ -0,0 +1,142 @@
import '../_setup.js';
import {
parseHTML,
isVisible,
hideElement,
showElement,
emptyChildNodes,
replaceChildNodes,
} from '../../../js/lib/dom.js';
describe('lib/dom', function () {
let el;
before(function () {
testContainer.innerHTML = '<div class="test"></div>';
el = testContainer.firstChild;
});
after(function () {
testContainer.removeChild(el);
});
describe('parseHTML()', function () {
it('parses an html fragment with Range.prototype.createContextualFragment()', function () {
const spyFragment = sinon.spy(Range.prototype, 'createContextualFragment');
const html = '<div>test</div>';
const result = parseHTML(html);
expect(spyFragment.calledWith(html), 'to be true');
expect(spyFragment.returned(result), 'to be true');
spyFragment.restore();
});
});
describe('isVisible()', function () {
it('returns true if either offsetHeight > 0, offsetWidth > 0 or getClientRects() has an item', function () {
expect(isVisible(el), 'to be false');
let stub = sinon.stub(el, "offsetHeight").get(() => 10);
expect(isVisible(el), 'to be true');
stub.restore();
stub = sinon.stub(el, "offsetWidth").get(() => 10);
expect(isVisible(el), 'to be true');
stub.restore();
stub = sinon.stub(el, 'getClientRects').callsFake(() => [{x: 10}, {x: 20}]);
expect(isVisible(el), 'to be true');
stub.restore();
});
});
describe('hideElement()', function () {
it('sets none to style.display', function () {
hideElement(el);
expect(el.style.display, 'to be', 'none');
el.removeAttribute('style');
});
it('copies style.display to data-style-display attribute if other than none is set', function () {
el.style.display = 'flex';
hideElement(el);
expect(el.style.display, 'to be', 'none');
expect(el.getAttribute('data-style-display'), 'to be', 'flex');
el.removeAttribute('data-style-display');
el.style.display = 'none';
hideElement(el);
expect(el.hasAttribute('data-style-display'), 'to be false');
el.removeAttribute('style');
});
});
describe('showElement()', function () {
it('clears style.display if none is set', function () {
el.style.display = 'none';
showElement(el);
expect(el.style.display, 'to be', '');
el.style.display = 'inline';
showElement(el);
expect(el.style.display, 'to be', 'inline');
el.removeAttribute('style');
});
it('restores the value of data-style-display attribute to style.display if it exists', function () {
el.style.display = 'none';
el.setAttribute('data-style-display', 'flex');
showElement(el);
expect(el.style.display, 'to be', 'flex');
expect(el.hasAttribute('data-style-display'), 'to be false');
el.removeAttribute('style');
});
});
describe('emptyChildNodes()', function () {
it('removes all child nodes', function () {
el.innerHTML = '<div>test</div><!-- comment--><div></div>';
emptyChildNodes(el);
expect(el.innerHTML, 'to be empty');
});
});
describe('replaceChildNodes()', function () {
it('replace all child nodes with given nodes', function () {
const htmlBefore = '<div>test</div><!-- comment--><div></div>';
const htmlAfter = '<div id="foo">foo</div><div id="bar">bar</div>';
// with html
el.innerHTML = htmlBefore;
replaceChildNodes(el, htmlAfter);
expect(el.innerHTML, 'to be', htmlAfter);
// with DocumentFragment
const fragment = document.createRange().createContextualFragment(htmlAfter);
el.innerHTML = htmlBefore;
replaceChildNodes(el, fragment);
expect(el.innerHTML, 'to be', htmlAfter);
// with NodeList
const nodeList = el.querySelectorAll('div');
el.innerHTML = htmlBefore;
replaceChildNodes(el, nodeList);
expect(el.innerHTML, 'to be', htmlAfter);
// with array
el.innerHTML = htmlBefore;
replaceChildNodes(el, Array.from(nodeList));
expect(el.innerHTML, 'to be', htmlAfter);
el.innerHTML = '';
});
});
});

207
node_modules/flowbite-datepicker/test/unit/lib/event.js generated vendored Normal file
View File

@ -0,0 +1,207 @@
import '../_setup.js';
describe('lib/evnet', function () {
let listenerRegistry;
let spyAEL;
let spyREL;
//
let registerListeners;
let unregisterListeners;
let findElementInEventPath;
before(function () {
spyAEL = sinon.spy(EventTarget.prototype, 'addEventListener');
spyREL = sinon.spy(EventTarget.prototype, 'removeEventListener');
const origWeakMap = global.WeakMap;
global.WeakMap = function (...args) {
return listenerRegistry = new origWeakMap(...args);
};
return import('../../../js/lib/event.js')
.then((module) => {
global.WeakMap = origWeakMap;
registerListeners = module.registerListeners;
unregisterListeners = module.unregisterListeners;
findElementInEventPath = module.findElementInEventPath;
});
});
after(function () {
spyAEL.restore();
spyREL.restore();
});
afterEach(function () {
spyAEL.resetHistory();
spyREL.resetHistory();
});
describe('registerListeners()', function () {
let target;
before(function () {
target = document.createElement('input');
testContainer.appendChild(target);
});
after(function () {
testContainer.removeChild(target);
});
it('registers event listeres with key object calling addEventListener()', function () {
const keyObj = {};
const onClick = sinon.spy();
const onKeydown = sinon.spy();
const onMounseEnter = () => {};
const listeners = [
[document, 'click', onClick],
[target, 'keydown', onKeydown, {capture: false}],
[target, 'mouseenter', onMounseEnter, true],
];
registerListeners(keyObj, listeners);
expect(listenerRegistry.get(keyObj), 'to equal', listeners);
expect(spyAEL.args, 'to equal', listeners.map(listener => listener.slice(1)));
testContainer.click();
expect(onClick.called, 'to be true');
simulant.fire(target, 'keydown', {key: 'enter'});
expect(onKeydown.called, 'to be true');
listeners.forEach((listener) => {
EventTarget.prototype.removeEventListener.call(...listener);
});
listenerRegistry.delete(keyObj);
});
it('appends listeners if registration for key object already exists', function () {
const keyObj = {};
const onClick = () => {};
const onKeydown = () => {};
const onMounseEnter = () => {};
const listeners = [
[document, 'click', onClick],
];
const listenersToAdd = [
[target, 'keydown', onKeydown, {capture: false}],
[target, 'mouseenter', onMounseEnter, true],
];
listenerRegistry.set(keyObj, listeners);
registerListeners(keyObj, listenersToAdd);
expect(listeners.length, 'to be', 3);
expect(listenerRegistry.get(keyObj), 'to equal', listeners);
expect(spyAEL.args, 'to equal', listenersToAdd.map(listener => listener.slice(1)));
listenersToAdd.forEach((listener) => {
EventTarget.prototype.removeEventListener.call(...listener);
});
listenerRegistry.delete(keyObj);
});
});
describe('unregisterListeners()', function () {
let target;
before(function () {
target = document.createElement('input');
testContainer.appendChild(target);
});
after(function () {
testContainer.removeChild(target);
});
it('unregisters all event listeres for key object calling removeEventListener()', function () {
const keyObj = {};
const onClick = sinon.spy();
const onKeydown = sinon.spy();
const onMounseEnter = () => {};
const listeners = [
[document, 'click', onClick],
[target, 'keydown', onKeydown, {capture: false}],
[target, 'mouseenter', onMounseEnter, true],
];
listeners.forEach((listener) => {
EventTarget.prototype.addEventListener.call(...listener);
});
listenerRegistry.set(keyObj, listeners);
unregisterListeners(keyObj);
expect(listenerRegistry.get(keyObj), 'to be undefined');
expect(spyREL.args, 'to equal', listeners.map(listener => listener.slice(1)));
testContainer.click();
expect(onClick.called, 'to be false');
simulant.fire(target, 'keydown', {key: 'enter'});
expect(onKeydown.called, 'to be false');
});
});
describe('findElementInEventPath()', function () {
let field;
let control;
let input;
before(function () {
input = document.createElement('input');
control = document.createElement('div');
control.className = 'control';
control.appendChild(input);
field = document.createElement('div');
field.className = 'field';
field.appendChild(control);
testContainer.appendChild(field);
});
after(function () {
testContainer.removeChild(field);
});
it('returns the first element in event\'s path that matches given selector', function () {
const test = (ev) => {
expect(findElementInEventPath(ev, '.control'), 'to be', control);
expect(findElementInEventPath(ev, '.field'), 'to be', field);
expect(findElementInEventPath(ev, 'div'), 'to be', control);
};
document.addEventListener('click', test);
simulant.fire(input, 'click');
document.removeEventListener('click', test);
});
it('returns undefined if no matched element is in event\'s path', function () {
const test = (ev) => {
expect(findElementInEventPath(ev, '.foo'), 'to be undefined',);
};
document.addEventListener('click', test);
simulant.fire(input, 'click');
document.removeEventListener('click', test);
});
it('stops searching when it reaches event\'s currentTarget', function () {
const test = (ev) => {
expect(findElementInEventPath(ev, '.control'), 'to be', control);
expect(findElementInEventPath(ev, '.field'), 'to be undefined',);
};
control.addEventListener('click', test);
simulant.fire(input, 'click');
control.removeEventListener('click', test);
});
it('function can be used to evaluate the condition instead of css selector', function () {
const test = (ev) => {
expect(findElementInEventPath(ev, target => [field, control].includes(target)), 'to be', control);
expect(findElementInEventPath(ev, target => target === field), 'to be', field);
expect(findElementInEventPath(ev, target => target.tagName === 'DIV'), 'to be', control);
};
document.addEventListener('click', test);
simulant.fire(input, 'click');
document.removeEventListener('click', test);
});
});
});

135
node_modules/flowbite-datepicker/test/unit/lib/utils.js generated vendored Normal file
View File

@ -0,0 +1,135 @@
import '../_setup.js';
import {
lastItemOf,
pushUnique,
stringToArray,
isInRange,
limitToRange,
createTagRepeat,
optimizeTemplateHTML
} from '../../../js/lib/utils.js';
describe('lib/utils', function () {
describe('lastItemOf()', function () {
it('returns the last item of array', function () {
expect(lastItemOf([1, 2, 3]), 'to be', 3);
expect(lastItemOf(['foo']), 'to be', 'foo');
expect(lastItemOf([]), 'to be undefined');
});
});
describe('pushUnique()', function () {
it('add items to an array if the item is not in the array', function () {
let arr = ['foo', 'bar'];
pushUnique(arr, 'foo');
expect(arr, 'to equal', arr);
pushUnique(arr, 'baz');
expect(arr, 'to equal', ['foo', 'bar', 'baz']);
arr = ['foo', 'bar'];
pushUnique(arr, 'bar', 'baz', 'bam', 'baz');
expect(arr, 'to equal', ['foo', 'bar', 'baz', 'bam']);
});
it('returns the given array', function () {
let arr = ['foo', 'bar'];
expect(pushUnique(arr, 'baz'), 'to be', arr);
});
});
describe('stringToArray()', function () {
it('converts a string to array by spliting it with given separator', function () {
expect(stringToArray('foo,bar,baz', ','), 'to equal', ['foo', 'bar', 'baz']);
expect(stringToArray('abc-def', '-'), 'to equal', ['abc', 'def']);
});
it('return an empty array if string is empty', function () {
expect(stringToArray('', ','), 'to equal', []);
});
});
describe('isInRange()', function () {
it('returns whether a value is between given min & max values', function () {
expect(isInRange(0, 1, 3), 'to be false');
expect(isInRange(1, 1, 3), 'to be true');
expect(isInRange(2, 1, 3), 'to be true');
expect(isInRange(3, 1, 3), 'to be true');
expect(isInRange(4, 1, 3), 'to be false');
//
expect(isInRange('abb', 'abc', 'ccc'), 'to be false');
expect(isInRange('bbc', 'abc', 'ccc'), 'to be true');
expect(isInRange('ccb', 'abc', 'ccc'), 'to be true');
expect(isInRange('ccd', 'abc', 'ccc'), 'to be false');
});
it('omits minimum check if min = undefined', function () {
expect(isInRange(0, undefined, 3), 'to be true');
expect(isInRange(4, undefined, 3), 'to be false');
expect(isInRange(-Infinity, undefined, 3), 'to be true');
});
it('omits maximum check if max = undefined', function () {
expect(isInRange(0, 1, undefined), 'to be false');
expect(isInRange(4, 1, undefined), 'to be true');
expect(isInRange(Infinity, 1, undefined), 'to be true');
});
});
describe('limitToRange()', function () {
it('returns min value if it\'s specified and the value < min', function () {
expect(limitToRange(0, 1, undefined), 'to be', 1);
expect(limitToRange(0, 1, 3), 'to be', 1);
expect(limitToRange('abb', 'abc', 'ccc'), 'to be', 'abc');
});
it('returns max value if it\'s specified and the value > max', function () {
expect(limitToRange(4, undefined, 3), 'to be', 3);
expect(limitToRange(4, 1, 3), 'to be', 3);
expect(limitToRange('ccd', 'abc', 'ccc'), 'to be', 'ccc');
});
it('returns the given value if it is within the specified min/max', function () {
expect(limitToRange(1, undefined, undefined), 'to be', 1);
expect(limitToRange(1, undefined, 3), 'to be', 1);
expect(limitToRange(3, 1, undefined), 'to be', 3);
expect(limitToRange(1, 1, 3), 'to be', 1);
expect(limitToRange(3, 1, 3), 'to be', 3);
expect(limitToRange('abc', 'aaa', 'ccc'), 'to be', 'abc');
expect(limitToRange('aaa', 'aaa', 'ccc'), 'to be', 'aaa');
expect(limitToRange('ccc', 'aaa', 'ccc'), 'to be', 'ccc');
});
});
describe('createTagRepeat()', function () {
it('returns HTML of a tag repeated specified times', function () {
expect(createTagRepeat('div', 3), 'to be', '<div></div><div></div><div></div>');
expect(createTagRepeat('span', 2), 'to be', '<span></span><span></span>');
// returns at least 1 tag
expect(createTagRepeat('p', 0), 'to be', '<p></p>');
});
it('adds addributes if name:value pairs are given', function () {
expect(createTagRepeat('p', 2, {class: 'foo bar'}), 'to be', '<p class="foo bar"></p><p class="foo bar"></p>');
expect(createTagRepeat('p', 2, {'data-x': '0', 'data-y': '1'}), 'to be', '<p data-x="0" data-y="1"></p><p data-x="0" data-y="1"></p>');
});
it('accepts function that takes current index as the argument for attribute value', function () {
expect(createTagRepeat('li', 3, {'data-cnt': ix => ix + 1}), 'to be', '<li data-cnt="1"></li><li data-cnt="2"></li><li data-cnt="3"></li>');
});
});
describe('optimizeTemplateHTML()', function () {
it('removes spacing before and after tags', function () {
let text = `<div id="test">
<div>
test 123
</div>
</div>`;
expect(optimizeTemplateHTML(text), 'to be', '<div id="test"><div>test 123</div></div>');
expect(optimizeTemplateHTML('foo'), 'to be', 'foo');
});
});
});