Skip to content

Commit

Permalink
feat(time-slots): add basic generation strategy
Browse files Browse the repository at this point in the history
  • Loading branch information
lparolari committed Oct 13, 2020
1 parent 9688dd2 commit 392a8c7
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 1 deletion.
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,9 @@
"files": [
"dist/**/*"
],
"dependencies": {}
"dependencies": {
"@types/ramda": "^0.27.25",
"moment": "^2.29.1",
"ramda": "^0.27.1"
}
}
49 changes: 49 additions & 0 deletions src/__tests__/slots.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import moment, { Moment } from "moment";

import { addInterval, Interval, slots } from "../slots";

describe("slots", () => {
const interval: Interval = { amount: 30, unit: "minutes" };
const d1 = moment();
const d2 = addInterval(interval)(d1); // d1 + 30m
const d3 = addInterval(interval)(d2); // d2 + 30m = d1 + 60m
const start = d1;

const geq = (d: Moment) => (c: Moment): boolean => c >= d;

it("generate a single time slot", () => {
const gen = slots(interval)([])(start);

expect(gen.next().value).toEqual([start.format("HH:mm")]);
});

it("generate subsequent time slots", () => {
const gen = slots(interval)([])(start);

expect(gen.next().value).toEqual([start.format("HH:mm")]);
expect(gen.next().value).toEqual([addInterval(interval)(start).format("HH:mm")]);
});

it("do not generate time slots if constraints always fail", () => {
const gen = slots(interval)([() => false])(start);

expect(gen.next().value).toEqual([]);
});

it("do not generate time slots if a constraint is failing", () => {
const gen = slots(interval)([geq(d2)])(start);

expect(gen.next().value).toEqual([]);
expect(gen.next().value).toEqual([d2.format("HH:mm")]);
expect(gen.next().value).not.toEqual([]);
});

it("do not generate time slots if costraints are failing", () => {
const gen = slots(interval)([geq(d2), geq(d3)])(start);

expect(gen.next().value).toEqual([]);
expect(gen.next().value).toEqual([]);
expect(gen.next().value).toEqual([d3.format("HH:mm")]);
expect(gen.next().value).not.toEqual([]);
});
});
7 changes: 7 additions & 0 deletions src/constraint.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Moment } from "moment";
import * as R from "ramda";

export type Constraint = (current: Moment) => boolean;

export const validate = (constraints: Constraint[]) => (current: Moment) =>
R.all(R.identity, R.map(R.applyTo(current), constraints));
32 changes: 32 additions & 0 deletions src/slots.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import moment, { Moment } from "moment";
import { Constraint, validate } from "./constraint";

export type Interval = {
amount: moment.DurationInputArg1;
unit: moment.DurationInputArg2;
};

export type Slot = string;

export const addInterval = (interval: Interval) => (m: Moment): Moment => m.clone().add(interval.amount, interval.unit);

export const slots = (interval: Interval) => (constraints: Constraint[]) => (start: Moment) => {
return (function* () {
let newStart = start;

while (true) {
yield one(constraints)(newStart);
newStart = addInterval(interval)(newStart);
}
})();
};

export const one = (constraints: Constraint[]) => (start: Moment): string[] => {
const current = moment(start, "HH:mm");

if (validate(constraints)(current)) {
return [current.format("HH:mm")];
}

return [];
};
22 changes: 22 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -994,6 +994,13 @@
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.0.0.tgz#dc85454b953178cc6043df5208b9e949b54a3bc4"
integrity sha512-/rM+sWiuOZ5dvuVzV37sUuklsbg+JPOP8d+nNFlo2ZtfpzPiPvh1/gc8liWOLBqe+sR+ZM7guPaIcTt6UZTo7Q==

"@types/ramda@^0.27.25":
version "0.27.25"
resolved "https://registry.yarnpkg.com/@types/ramda/-/ramda-0.27.25.tgz#8b9b1910f93d3c3344ccfad1641f9332904f9eb5"
integrity sha512-D6gYQumFrGwDa0K2XqUIbktTAnQ/KBnbtL+IpXbpaiJJ1qnmfDZXe0diJC7LRQf7NvjjgxceQmv7YnL/1xjw6A==
dependencies:
ts-toolbelt "^6.3.3"

"@types/retry@^0.12.0":
version "0.12.0"
resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d"
Expand Down Expand Up @@ -5421,6 +5428,11 @@ modify-values@^1.0.0:
resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022"
integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==

moment@^2.29.1:
version "2.29.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==

move-concurrently@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"
Expand Down Expand Up @@ -6552,6 +6564,11 @@ qw@~1.0.1:
resolved "https://registry.yarnpkg.com/qw/-/qw-1.0.1.tgz#efbfdc740f9ad054304426acb183412cc8b996d4"
integrity sha1-77/cdA+a0FQwRCassYNBLMi5ltQ=

ramda@^0.27.1:
version "0.27.1"
resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.27.1.tgz#66fc2df3ef873874ffc2da6aa8984658abacf5c9"
integrity sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==

rc@^1.0.1, rc@^1.1.6, rc@^1.2.8:
version "1.2.8"
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
Expand Down Expand Up @@ -7828,6 +7845,11 @@ ts-jest@26.4.1:
semver "7.x"
yargs-parser "20.x"

ts-toolbelt@^6.3.3:
version "6.15.5"
resolved "https://registry.yarnpkg.com/ts-toolbelt/-/ts-toolbelt-6.15.5.tgz#cb3b43ed725cb63644782c64fbcad7d8f28c0a83"
integrity sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A==

tslib@^1.8.1:
version "1.11.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.0.tgz#f1f3528301621a53220d58373ae510ff747a66bc"
Expand Down

0 comments on commit 392a8c7

Please sign in to comment.