add naturalWholeUnit() and basic tests to lib/time.ts

naturalWholeUnit() is not currently used
This commit is contained in:
Damien Elmes 2021-04-12 14:40:05 +10:00
parent 829b99e5b2
commit 9440898e60
3 changed files with 84 additions and 9 deletions

View file

@ -2,6 +2,7 @@ load("@npm//@bazel/typescript:index.bzl", "ts_library")
load("//ts:prettier.bzl", "prettier_test")
load("//ts:eslint.bzl", "eslint_test")
load("//ts:protobuf.bzl", "protobufjs_library")
load("@npm//jest-cli:index.bzl", "jest_test")
# Protobuf
#############
@ -44,7 +45,10 @@ genrule(
ts_library(
name = "lib",
srcs = glob(["**/*.ts"]) + [":i18n.ts"],
srcs = glob(
["**/*.ts"],
exclude = ["*.test.ts"],
) + [":i18n.ts"],
data = [
"backend_proto",
],
@ -72,3 +76,31 @@ eslint_test(
name = "eslint",
srcs = glob(["*.ts"]),
)
ts_library(
name = "test_lib",
srcs = glob(["*.test.ts"]),
tsconfig = "//ts:tsconfig.json",
deps = [
":lib",
"@npm//@types/jest",
],
)
jest_test(
name = "test",
args = [
"--no-cache",
"--no-watchman",
"--ci",
"--colors",
"--config",
"$(location //ts:jest.config.js)",
],
data = [
":test_lib",
"//ts:jest.config.js",
"//ts:package.json",
"@npm//protobufjs",
],
)

25
ts/lib/time.test.ts Normal file
View file

@ -0,0 +1,25 @@
import { naturalUnit, naturalWholeUnit, TimespanUnit } from "./time";
test("natural unit", () => {
expect(naturalUnit(5)).toBe(TimespanUnit.Seconds);
expect(naturalUnit(59)).toBe(TimespanUnit.Seconds);
expect(naturalUnit(60)).toBe(TimespanUnit.Minutes);
expect(naturalUnit(60 * 60 - 1)).toBe(TimespanUnit.Minutes);
expect(naturalUnit(60 * 60)).toBe(TimespanUnit.Hours);
expect(naturalUnit(60 * 60 * 24)).toBe(TimespanUnit.Days);
expect(naturalUnit(60 * 60 * 24 * 30)).toBe(TimespanUnit.Months);
});
test("natural whole unit", () => {
expect(naturalWholeUnit(5)).toBe(TimespanUnit.Seconds);
expect(naturalWholeUnit(59)).toBe(TimespanUnit.Seconds);
expect(naturalWholeUnit(60)).toBe(TimespanUnit.Minutes);
expect(naturalWholeUnit(61)).toBe(TimespanUnit.Seconds);
expect(naturalWholeUnit(90)).toBe(TimespanUnit.Seconds);
expect(naturalWholeUnit(60 * 60 - 1)).toBe(TimespanUnit.Seconds);
expect(naturalWholeUnit(60 * 60 + 1)).toBe(TimespanUnit.Seconds);
expect(naturalWholeUnit(60 * 60)).toBe(TimespanUnit.Hours);
expect(naturalWholeUnit(24 * 60 * 60 - 1)).toBe(TimespanUnit.Seconds);
expect(naturalWholeUnit(24 * 60 * 60 + 1)).toBe(TimespanUnit.Seconds);
expect(naturalWholeUnit(24 * 60 * 60)).toBe(TimespanUnit.Days);
});

View file

@ -10,7 +10,7 @@ export const DAY = 24.0 * HOUR;
export const MONTH = 30.0 * DAY;
export const YEAR = 12.0 * MONTH;
enum TimespanUnit {
export enum TimespanUnit {
Seconds,
Minutes,
Hours,
@ -53,23 +53,41 @@ export function naturalUnit(secs: number): TimespanUnit {
}
}
export function unitAmount(unit: TimespanUnit, secs: number): number {
/// Number of seconds in a given unit.
export function unitSeconds(unit: TimespanUnit): number {
switch (unit) {
case TimespanUnit.Seconds:
return secs;
return SECOND;
case TimespanUnit.Minutes:
return secs / MINUTE;
return MINUTE;
case TimespanUnit.Hours:
return secs / HOUR;
return HOUR;
case TimespanUnit.Days:
return secs / DAY;
return DAY;
case TimespanUnit.Months:
return secs / MONTH;
return MONTH;
case TimespanUnit.Years:
return secs / YEAR;
return YEAR;
}
}
export function unitAmount(unit: TimespanUnit, secs: number): number {
return secs / unitSeconds(unit);
}
/// Largest unit provided seconds can be divided by without a remainder.
export function naturalWholeUnit(secs: number): TimespanUnit {
let unit = naturalUnit(secs);
while (unit != TimespanUnit.Seconds) {
const amount = Math.round(unitAmount(unit, secs));
if (Math.abs(secs - amount * unitSeconds(unit)) < Number.EPSILON) {
return unit;
}
unit -= 1;
}
return unit;
}
export function studiedToday(cards: number, secs: number): string {
const unit = naturalUnit(secs);
const amount = unitAmount(unit, secs);