Skip to content

Commit

Permalink
Merge pull request #413 from alleslabs/feat/date-test
Browse files Browse the repository at this point in the history
test: add test cases for date utils
  • Loading branch information
evilpeach committed Jun 30, 2023
2 parents 155b70a + 19d559d commit 7b87b68
Show file tree
Hide file tree
Showing 5 changed files with 231 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Improvements

- [#413](https://github.com/alleslabs/celatone-frontend/pull/413) Add jest test cases for date utils
- [#404](https://github.com/alleslabs/celatone-frontend/pull/404) Use internal navigate instead of app link for block navigation
- [#396](https://github.com/alleslabs/celatone-frontend/pull/396) Refactor useConfig, disable wasm related tabs on the public project page
- [#392](https://github.com/alleslabs/celatone-frontend/pull/392) Refactor proposal table and fix empty state of the proposal list table
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
"husky": "^8.0.1",
"jest": "^29.5.0",
"lint-staged": "^13.0.3",
"mockdate": "^3.0.5",
"next-sitemap": "^3.1.25",
"prettier": "^2.7.1",
"standard-version": "^9.5.0",
Expand Down
219 changes: 219 additions & 0 deletions src/lib/utils/date.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
/* eslint-disable sonarjs/no-duplicate-string */
import MockDate from "mockdate";

import {
getDefaultDate,
getCurrentDate,
parseDate,
parseDateOpt,
parseDateDefault,
formatUTC,
dateFromNow,
formatSeconds,
} from "./date";

const MOCK_CURRENT_ISO = "2026-06-06T06:00:00.000Z";
const DEFAULT_ISO = "1970-01-01T00:00:00.000Z";

beforeEach(() => {
MockDate.set(new Date(MOCK_CURRENT_ISO));
});

afterEach(() => {
MockDate.reset();
});

describe("getDefaultDate", () => {
test("should correctly return default date", () => {
expect(getDefaultDate().toISOString()).toEqual(DEFAULT_ISO);
});
});

describe("getCurrentDate", () => {
test("should correctly return current date", () => {
expect(getCurrentDate().toISOString()).toEqual(MOCK_CURRENT_ISO);
});
});

describe("parseDate", () => {
test("should correctly parse date from string", () => {
let d = "2018";
expect(parseDate(d).toISOString()).toEqual("2018-01-01T00:00:00.000Z");
d = "2018-04";
expect(parseDate(d).toISOString()).toEqual("2018-04-01T00:00:00.000Z");
d = "2018-04-24";
expect(parseDate(d).toISOString()).toEqual("2018-04-24T00:00:00.000Z");
d = "2018-04-24 11:12";
expect(parseDate(d).toISOString()).toEqual("2018-04-24T11:12:00.000Z");
d = "2018-05-02 11:12:13";
expect(parseDate(d).toISOString()).toEqual("2018-05-02T11:12:13.000Z");
d = "2018-05-02 11:12:13.998";
expect(parseDate(d).toISOString()).toEqual("2018-05-02T11:12:13.998Z");
d = "2018036187";
expect(parseDate(d).toISOString()).toEqual("2018-05-03T15:00:00.000Z");
});
});

describe("parseDateOpt", () => {
test("should correctly parse date from string", () => {
let d = "2018";
expect(parseDateOpt(d)?.toISOString()).toEqual("2018-01-01T00:00:00.000Z");
d = "2018-04";
expect(parseDateOpt(d)?.toISOString()).toEqual("2018-04-01T00:00:00.000Z");
d = "2018-04-24";
expect(parseDateOpt(d)?.toISOString()).toEqual("2018-04-24T00:00:00.000Z");
d = "2018-04-24 11:12";
expect(parseDateOpt(d)?.toISOString()).toEqual("2018-04-24T11:12:00.000Z");
d = "2018-05-02 11:12:13";
expect(parseDateOpt(d)?.toISOString()).toEqual("2018-05-02T11:12:13.000Z");
d = "2018-05-02 11:12:13.998";
expect(parseDateOpt(d)?.toISOString()).toEqual("2018-05-02T11:12:13.998Z");
d = "2018036187";
expect(parseDateOpt(d)?.toISOString()).toEqual("2018-05-03T15:00:00.000Z");
});
test("should correctly return undefined for undefined/falsy parameter", () => {
// undefined and falsy cases
expect(parseDateOpt(undefined)).toBeUndefined();
expect(parseDateOpt("")).toBeUndefined();
});
});

describe("parseDateDefault", () => {
test("should correctly parse date from string", () => {
let d = "2018";
expect(parseDateDefault(d).toISOString()).toEqual(
"2018-01-01T00:00:00.000Z"
);
d = "2018-04";
expect(parseDateDefault(d).toISOString()).toEqual(
"2018-04-01T00:00:00.000Z"
);
d = "2018-04-24";
expect(parseDateDefault(d).toISOString()).toEqual(
"2018-04-24T00:00:00.000Z"
);
d = "2018-04-24 11:12";
expect(parseDateDefault(d).toISOString()).toEqual(
"2018-04-24T11:12:00.000Z"
);
d = "2018-05-02 11:12:13";
expect(parseDateDefault(d).toISOString()).toEqual(
"2018-05-02T11:12:13.000Z"
);
d = "2018-05-02 11:12:13.998";
expect(parseDateDefault(d).toISOString()).toEqual(
"2018-05-02T11:12:13.998Z"
);
d = "2018036187";
expect(parseDateDefault(d).toISOString()).toEqual(
"2018-05-03T15:00:00.000Z"
);
});
test("should correctly return default value for undefined/falsy parameter", () => {
// undefined and falsy cases
expect(parseDateDefault(undefined).toISOString()).toEqual(DEFAULT_ISO);
expect(parseDateDefault("").toISOString()).toEqual(DEFAULT_ISO);
});
});

describe("formatUTC", () => {
test("should correctly format date to UTC string", () => {
let d = parseDate("2018");
expect(formatUTC(d)).toEqual("Jan 01, 2018, 12:00:00 AM (UTC)");
d = parseDate("2018-04");
expect(formatUTC(d)).toEqual("Apr 01, 2018, 12:00:00 AM (UTC)");
d = parseDate("2018-04-24");
expect(formatUTC(d)).toEqual("Apr 24, 2018, 12:00:00 AM (UTC)");
d = parseDate("2018-04-24 11:12");
expect(formatUTC(d)).toEqual("Apr 24, 2018, 11:12:00 AM (UTC)");
d = parseDate("2018-05-02 11:12:13");
expect(formatUTC(d)).toEqual("May 02, 2018, 11:12:13 AM (UTC)");
d = parseDate("2018-05-02 11:12:13.998");
expect(formatUTC(d)).toEqual("May 02, 2018, 11:12:13 AM (UTC)");
d = parseDate("2018036187");
expect(formatUTC(d)).toEqual("May 03, 2018, 3:00:00 PM (UTC)");
});
});

describe("dateFromNow", () => {
test("(Past) should correctly get date from now", () => {
// Past
let d = parseDate("2026-06-06T05:59:30.000Z");
expect(dateFromNow(d)).toEqual("a few seconds ago");
d = parseDate("2026-06-06T05:59:00.000Z");
expect(dateFromNow(d)).toEqual("a minute ago");
d = parseDate("2026-06-06T05:30:00.000Z");
expect(dateFromNow(d)).toEqual("30 minutes ago");
d = parseDate("2026-06-06T05:00:00.000Z");
expect(dateFromNow(d)).toEqual("an hour ago");
d = parseDate("2026-06-06T00:00:00.000Z");
expect(dateFromNow(d)).toEqual("6 hours ago");
d = parseDate("2026-06-05T06:00:00.000Z");
expect(dateFromNow(d)).toEqual("a day ago");
d = parseDate("2026-05-31T06:00:00.000Z");
expect(dateFromNow(d)).toEqual("6 days ago");
d = parseDate("2026-05-06T06:00:00.000Z");
expect(dateFromNow(d)).toEqual("a month ago");
d = parseDate("2025-12-06T06:00:00.000Z");
expect(dateFromNow(d)).toEqual("6 months ago");
d = parseDate("2025-06-06T06:00:00.000Z");
expect(dateFromNow(d)).toEqual("a year ago");
d = parseDate("2012-06-06T06:00:00.000Z");
expect(dateFromNow(d)).toEqual("14 years ago");
});

test("(Future) should correctly get date from now", () => {
// Future
let d = parseDate("2026-06-06T06:00:30.000Z");
expect(dateFromNow(d)).toEqual("in a few seconds");
d = parseDate("2026-06-06T06:00:50.000Z");
expect(dateFromNow(d)).toEqual("in a minute");
d = parseDate("2026-06-06T06:30:00.000Z");
expect(dateFromNow(d)).toEqual("in 30 minutes");
d = parseDate("2026-06-06T07:00:00.000Z");
expect(dateFromNow(d)).toEqual("in an hour");
d = parseDate("2026-06-06T12:00:00.000Z");
expect(dateFromNow(d)).toEqual("in 6 hours");
d = parseDate("2026-06-07T06:00:00.000Z");
expect(dateFromNow(d)).toEqual("in a day");
d = parseDate("2026-06-12T06:00:00.000Z");
expect(dateFromNow(d)).toEqual("in 6 days");
d = parseDate("2026-07-06T06:00:00.000Z");
expect(dateFromNow(d)).toEqual("in a month");
d = parseDate("2026-12-06T06:00:00.000Z");
expect(dateFromNow(d)).toEqual("in 6 months");
d = parseDate("2027-06-06T06:00:00.000Z");
expect(dateFromNow(d)).toEqual("in a year");
d = parseDate("2040-06-06T06:00:00.000Z");
expect(dateFromNow(d)).toEqual("in 14 years");
});
});

describe("formatSeconds", () => {
test("should correctly format seconds", () => {
let s = "1000000s";
expect(formatSeconds(s)).toEqual("11 days");
s = "86400s";
expect(formatSeconds(s)).toEqual("1 day");
s = "7200s";
expect(formatSeconds(s)).toEqual("2 hours");
s = "3600s";
expect(formatSeconds(s)).toEqual("1 hour");
s = "120s";
expect(formatSeconds(s)).toEqual("2 minutes");
s = "60s";
expect(formatSeconds(s)).toEqual("1 minute");
s = "30s";
expect(formatSeconds(s)).toEqual("30 seconds");
s = "1s";
expect(formatSeconds(s)).toEqual("1 second");
s = "0s";
expect(formatSeconds(s)).toEqual("0 second");
});
test("should correctly return fallback for undefined/NaN/lesser than 0 parameter", () => {
expect(formatSeconds(undefined)).toEqual("N/A");
expect(formatSeconds("")).toEqual("N/A");
expect(formatSeconds("ABCDEs")).toEqual("N/A");
expect(formatSeconds("-1s")).toEqual("N/A");
});
});
7 changes: 5 additions & 2 deletions src/lib/utils/date.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ export const formatUTC = (date: Date) =>
export const dateFromNow = (date: Date) => dayjs.utc(date).fromNow();

export const formatSeconds = (sec: Option<string>) => {
if (!sec) return "N/A";
if (sec === undefined || Number.isNaN(parseInt(sec, 10))) return "N/A";
const formatSec = big(sec.replace("s", ""));

// TODO: use `pluralize` here
switch (true) {
case formatSec.gte(86400): {
const days = formatSec.div(86400).round(0, 0).toNumber();
Expand All @@ -43,7 +44,9 @@ export const formatSeconds = (sec: Option<string>) => {
const mins = formatSec.div(60).round(0, 0).toNumber();
return `${mins} minute`.concat(mins > 1 ? "s" : "");
}
case formatSec.lt(0):
return "N/A";
default:
return `${formatSec.toFixed()} seconds`;
return `${formatSec.toFixed()} second`.concat(formatSec.gt(1) ? "s" : "");
}
};
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9781,6 +9781,11 @@ mobx@^6.6.2:
resolved "https://registry.npmjs.org/mobx/-/mobx-6.6.2.tgz"
integrity sha512-IOpS0bf3+hXIhDIy+CmlNMBfFpAbHS0aVHcNC+xH/TFYEKIIVDKNYRh9eKlXuVfJ1iRKAp0cRVmO145CyJAMVQ==

mockdate@^3.0.5:
version "3.0.5"
resolved "https://registry.yarnpkg.com/mockdate/-/mockdate-3.0.5.tgz#789be686deb3149e7df2b663d2bc4392bc3284fb"
integrity sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ==

modify-values@^1.0.0:
version "1.0.1"
resolved "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz"
Expand Down

1 comment on commit 7b87b68

@vercel
Copy link

@vercel vercel bot commented on 7b87b68 Jun 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.