Skip to content

Commit

Permalink
test: add tests for toNextSelectableDate
Browse files Browse the repository at this point in the history
  • Loading branch information
motss committed Sep 18, 2021
1 parent d9eec02 commit 18ea669
Show file tree
Hide file tree
Showing 3 changed files with 237 additions and 35 deletions.
64 changes: 30 additions & 34 deletions src/helpers/to-next-selectable-date.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { toUTCDate } from 'nodemod/dist/calendar/helpers/to-utc-date.js';

import { navigationKeySetDayNext, navigationKeySetDayPrevious } from '../constants.js';
import type { InferredFromSet } from '../typings.js';
import { toDateRange } from './to-date-range.js';
import type { ToNextSelectableDateInit } from './typings.js';

export function toNextSelectableDate({
Expand All @@ -13,61 +12,58 @@ export function toNextSelectableDate({
maxTime,
minTime,
}: ToNextSelectableDateInit): Date {
const focusedDateTime = +date;

let isLessThanMinTime = focusedDateTime < minTime;
let isMoreThanMaxTime = focusedDateTime > maxTime;
// Bail when there is no valid date range (<= 1 day).
if ((maxTime - minTime + 864e5) <= 864e5) return date;

// Bail when there is no valid date range (< 1 day).
if (toDateRange(minTime, maxTime) < 864e5) return date;
const focusedDateTime = +date;

let isBeforeMinTime = focusedDateTime < minTime;
let iaAfterMaxTime = focusedDateTime > maxTime;
let isDisabledDay =
isLessThanMinTime ||
isMoreThanMaxTime ||
isBeforeMinTime ||
iaAfterMaxTime ||
disabledDaysSet.has((date as Date).getUTCDay()) ||
disabledDatesSet.has(focusedDateTime);

if (!isDisabledDay) return date;

let selectableDateTime = 0;
let selectableDate = isLessThanMinTime === isMoreThanMaxTime ?
date : new Date(isLessThanMinTime ? minTime - 864e5 : 864e5 + maxTime);
let newSelectableDate = isBeforeMinTime === iaAfterMaxTime ?
date : new Date(isBeforeMinTime ? minTime - 864e5 : 864e5 + maxTime);
let newSelectableDateTime = +newSelectableDate;

const fy = selectableDate.getUTCFullYear();
const m = selectableDate.getUTCMonth();
let d = selectableDate.getUTCDate();
const fy = newSelectableDate.getUTCFullYear();
const m = newSelectableDate.getUTCMonth();
let d = newSelectableDate.getUTCDate();

while (isDisabledDay) {
if (isLessThanMinTime || (!isMoreThanMaxTime && navigationKeySetDayNext.has(key as InferredFromSet<typeof navigationKeySetDayNext>))) d += 1;
if (isMoreThanMaxTime || (!isLessThanMinTime && navigationKeySetDayPrevious.has(key as InferredFromSet<typeof navigationKeySetDayPrevious>))) d -= 1;
if (isBeforeMinTime || (!iaAfterMaxTime && navigationKeySetDayNext.has(key as InferredFromSet<typeof navigationKeySetDayNext>))) d += 1;
if (iaAfterMaxTime || (!isBeforeMinTime && navigationKeySetDayPrevious.has(key as InferredFromSet<typeof navigationKeySetDayPrevious>))) d -= 1;

selectableDate = toUTCDate(fy, m, d);
selectableDateTime = +selectableDate;
newSelectableDate = toUTCDate(fy, m, d);
newSelectableDateTime = +newSelectableDate;

if (!isLessThanMinTime) {
isLessThanMinTime = selectableDateTime < minTime;
if (!isBeforeMinTime) {
isBeforeMinTime = newSelectableDateTime < minTime;

if (isLessThanMinTime) {
selectableDate = new Date(minTime);
selectableDateTime = +selectableDate;
d = selectableDate.getUTCDate();
if (isBeforeMinTime) {
newSelectableDate = new Date(minTime);
d = newSelectableDate.getUTCDate();
}
}

if (!isMoreThanMaxTime) {
isMoreThanMaxTime = selectableDateTime > maxTime;
if (!iaAfterMaxTime) {
iaAfterMaxTime = newSelectableDateTime > maxTime;

if (isMoreThanMaxTime) {
selectableDate = new Date(maxTime);
selectableDateTime = +selectableDate;
d = selectableDate.getUTCDate();
if (iaAfterMaxTime) {
newSelectableDate = new Date(maxTime)
d = newSelectableDate.getUTCDate();
}
}

isDisabledDay =
disabledDaysSet.has(selectableDate.getUTCDay()) ||
disabledDatesSet.has(selectableDateTime);
disabledDaysSet.has(newSelectableDate.getUTCDay()) ||
disabledDatesSet.has(+newSelectableDate);
}

return selectableDate;
return newSelectableDate;
}
200 changes: 200 additions & 0 deletions src/tests/helpers/to-next-selectable-date.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
import { expect } from '@open-wc/testing';

import { toNextSelectableDate } from '../../helpers/to-next-selectable-date';
import type { ToNextSelectableDateInit } from '../../helpers/typings';
import { messageFormatter } from '../test-utils/message-formatter';

describe(toNextSelectableDate.name, () => {
const defaultInit: ToNextSelectableDateInit = {
date: new Date('2020-02-02'),
disabledDatesSet: new Set(),
disabledDaysSet: new Set(),
key: 'ArrowRight',
maxTime: +new Date('2020-03-03'),
minTime: +new Date('2020-01-01'),
};

type A = [Partial<ToNextSelectableDateInit>, Date];

const cases: A[] = [
[
{},
new Date('2020-02-02'),
],
[
{
minTime: +new Date('2020-02-02'),
maxTime: +new Date('2020-02-02'),
},
new Date('2020-02-02'),
],
];

cases.forEach((a) => {
const [partialInit, expected] = a;

it(
messageFormatter('returns next selectable date for non-disabled date (%j)', a),
() => {
const result = toNextSelectableDate({
...defaultInit,
...partialInit,
});

expect(result).deep.equal(expected);
}
);
});

type A1 = [Partial<ToNextSelectableDateInit>, Date];

const cases1: A1[] = [
// disabled dates to non-disabled dates
[
{
disabledDatesSet: new Set([+new Date('2020-02-02')]),
key: 'ArrowLeft',
},
new Date('2020-02-01'),
],
[
{
disabledDatesSet: new Set([+new Date('2020-02-02')]),
key: 'ArrowRight',
},
new Date('2020-02-03'),
],

// > 1 disabled dates to non-disabled dates
[
{
disabledDatesSet: new Set([
+new Date('2020-02-01'),
+new Date('2020-02-02'),
]),
key: 'ArrowLeft',
},
new Date('2020-01-31'),
],
[
{
disabledDatesSet: new Set([
+new Date('2020-02-02'),
+new Date('2020-02-03'),
]),
key: 'ArrowRight',
},
new Date('2020-02-04'),
],

// > 1 disabled dates to non-disabled dates with min/ max dates
[
{
disabledDatesSet: new Set([
+new Date('2020-02-01'),
+new Date('2020-02-02'),
]),
key: 'ArrowLeft',
minTime: +new Date('2020-01-31'),
},
new Date('2020-01-31'),
],
[
{
disabledDatesSet: new Set([
+new Date('2020-02-02'),
+new Date('2020-02-03'),
]),
key: 'ArrowRight',
maxTime: +new Date('2020-02-04'),
},
new Date('2020-02-04'),
],

// disabled date before min to min
[
{
date: new Date('2019-02-02'),
key: 'ArrowLeft',
},
new Date(defaultInit.minTime),
],
[
{
date: new Date('2019-02-02'),
key: 'ArrowRight',
},
new Date(defaultInit.minTime),
],

// disabled date after max to max
[
{
date: new Date('2020-04-03'),
key: 'ArrowRight',
},
new Date(defaultInit.maxTime),
],
[
{
date: new Date('2020-04-03'),
key: 'ArrowLeft',
},
new Date(defaultInit.maxTime),
],

// disabled min/ max to non-disabled date after/ before min/ max
[
{
date: new Date('2020-02-01'),
disabledDatesSet: new Set([
+new Date('2020-02-01'),
]),
key: 'ArrowLeft',
minTime: +new Date('2020-02-01'),
},
new Date('2020-02-02'),
],
[
{
date: new Date('2020-04-03'),
disabledDatesSet: new Set([
+new Date('2020-04-03'),
]),
key: 'ArrowRight',
maxTime: +new Date('2020-04-03'),
},
new Date('2020-04-02'),
],

// disabled max to non-disabled min
[
{
date: new Date('2020-04-03'),
disabledDatesSet: new Set([
+new Date('2020-04-03'),
]),
key: 'ArrowRight',
minTime: +new Date('2020-04-02'),
maxTime: +new Date('2020-04-03'),
},
new Date('2020-04-02'),
],
];

cases1.forEach((a) => {
const [partialInit, expected] = a;

it(
messageFormatter('returns next selectable date for disabled date (%j)', a),
() => {
const result = toNextSelectableDate({
...defaultInit,
...partialInit,
});

expect(result).deep.equal(expected);
}
);
});
});
8 changes: 7 additions & 1 deletion src/tests/test-utils/message-formatter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
const re = /%s|%j/g;

function replacer(_: string, v: unknown): unknown {
return v instanceof Set || v instanceof Map ?
Array.from(v) :
v;
}

export function messageFormatter<T>(message: string, group: T): string {
let i = 0;

Expand All @@ -11,7 +17,7 @@ export function messageFormatter<T>(message: string, group: T): string {
try {
return value?.toJSON();
} catch {
return s === '%j' ? JSON.stringify(value): String(value);
return s === '%j' ? JSON.stringify(value, replacer): String(value);
}
}
);
Expand Down

0 comments on commit 18ea669

Please sign in to comment.