When maxDecimalPoints truncates a unit count to exactly 1, the rendered
number showed 1 while the word was pluralized from the raw count (for
example humanizeDuration(1500, { maxDecimalPoints: 0 }) returned
"1 seconds"). Pluralize from the normalized count that is actually
displayed so the number and word agree.
350 lines
9.5 KiB
JavaScript
350 lines
9.5 KiB
JavaScript
const humanizeDuration = require("..");
|
|
const humanizer = humanizeDuration.humanizer;
|
|
const { describe, it } = require("node:test");
|
|
const assert = require("node:assert/strict");
|
|
const ms = require("ms");
|
|
|
|
describe("humanizer", function () {
|
|
it("humanizes English when passed no arguments", function () {
|
|
const h = humanizer();
|
|
|
|
assert.strictEqual(h(1000), "1 second");
|
|
});
|
|
|
|
it("humanizes English when passed an empty object", function () {
|
|
const h = humanizer({});
|
|
|
|
assert.strictEqual(h(1000), "1 second");
|
|
});
|
|
|
|
it("can change the delimiter", function () {
|
|
const h = humanizer({ delimiter: "+" });
|
|
|
|
assert.strictEqual(h(0), "0 seconds");
|
|
assert.strictEqual(h(1000), "1 second");
|
|
assert.strictEqual(h(363000), "6 minutes+3 seconds");
|
|
});
|
|
|
|
it("can change the spacer", function () {
|
|
const h = humanizer({ spacer: " whole " });
|
|
|
|
assert.strictEqual(h(0), "0 whole seconds");
|
|
assert.strictEqual(h(1000), "1 whole second");
|
|
assert.strictEqual(h(260040000), "3 whole days, 14 whole minutes");
|
|
});
|
|
|
|
it("can use a conjunction", function () {
|
|
const h = humanizer({ conjunction: " and " });
|
|
|
|
assert.strictEqual(h(0), "0 seconds");
|
|
assert.strictEqual(h(1000), "1 second");
|
|
assert.strictEqual(h(260040000), "3 days and 14 minutes");
|
|
assert.strictEqual(h(10874000), "3 hours, 1 minute, and 14 seconds");
|
|
});
|
|
|
|
it("can use a conjunction without a serial comma", function () {
|
|
const h = humanizer({
|
|
conjunction: " & ",
|
|
serialComma: false,
|
|
});
|
|
|
|
assert.strictEqual(h(1000), "1 second");
|
|
assert.strictEqual(h(260040000), "3 days & 14 minutes");
|
|
assert.strictEqual(h(10874000), "3 hours, 1 minute & 14 seconds");
|
|
});
|
|
|
|
it("can change the units", function () {
|
|
const h = humanizer({ units: ["d"] });
|
|
|
|
assert.strictEqual(h(0), "0 days");
|
|
assert.strictEqual(h(ms("6h")), "0.25 days");
|
|
assert.strictEqual(h(ms("7d")), "7 days");
|
|
});
|
|
|
|
it("can overwrite the unit measures in the initializer", function () {
|
|
const h = humanizer({
|
|
unitMeasures: {
|
|
y: 10512000000,
|
|
mo: 864000000,
|
|
w: 144000000,
|
|
d: 28800000,
|
|
h: 3600000,
|
|
m: 60000,
|
|
s: 1000,
|
|
ms: 1,
|
|
},
|
|
});
|
|
|
|
assert.strictEqual(h(1000), "1 second");
|
|
assert.strictEqual(h(3600000), "1 hour");
|
|
assert.strictEqual(h(28800000), "1 day");
|
|
assert.strictEqual(h(144000000), "1 week");
|
|
});
|
|
|
|
it("can change the decimal", function () {
|
|
const h = humanizer({
|
|
units: ["s"],
|
|
decimal: "what",
|
|
});
|
|
|
|
assert.strictEqual(h(1234), "1what234 seconds");
|
|
assert.strictEqual(
|
|
h(1234, {
|
|
decimal: "!!",
|
|
}),
|
|
"1!!234 seconds"
|
|
);
|
|
});
|
|
|
|
it("can do simple rounding", function () {
|
|
const h = humanizer({ round: true });
|
|
|
|
assert.strictEqual(h(0), "0 seconds");
|
|
assert.strictEqual(h(499), "0 seconds");
|
|
assert.strictEqual(h(500), "1 second");
|
|
assert.strictEqual(h(1000), "1 second");
|
|
assert.strictEqual(h(1499), "1 second");
|
|
assert.strictEqual(h(1500), "2 seconds");
|
|
assert.strictEqual(h(1500), "2 seconds");
|
|
assert.strictEqual(h(121499), "2 minutes, 1 second");
|
|
assert.strictEqual(h(121500), "2 minutes, 2 seconds");
|
|
});
|
|
|
|
it('can do rounding with the "units" option', function () {
|
|
const h = humanizer({ round: true });
|
|
|
|
assert.strictEqual(
|
|
h(86364000, { units: ["y", "mo", "w", "d", "h"] }),
|
|
"1 day"
|
|
);
|
|
assert.strictEqual(
|
|
h(1209564000, { units: ["y", "mo", "w", "d", "h"] }),
|
|
"2 weeks"
|
|
);
|
|
assert.strictEqual(h(3692131200000, { units: ["y", "mo"] }), "117 years");
|
|
assert.strictEqual(
|
|
h(3692131200001, { units: ["y", "mo", "w", "d", "h", "m"] }),
|
|
"116 years, 11 months, 4 weeks, 1 day, 4 hours, 30 minutes"
|
|
);
|
|
});
|
|
|
|
it('can do rounding with the "largest" option', function () {
|
|
const h = humanizer({ round: true });
|
|
|
|
assert.strictEqual(h(3692131200000, { largest: 1 }), "117 years");
|
|
assert.strictEqual(h(3692131200000, { largest: 2 }), "117 years");
|
|
assert.strictEqual(
|
|
h(3692131200001, { largest: 100 }),
|
|
"116 years, 11 months, 4 weeks, 1 day, 4 hours, 30 minutes"
|
|
);
|
|
assert.strictEqual(h(2838550, { largest: 3 }), "47 minutes, 19 seconds");
|
|
});
|
|
|
|
it('can do rounding with the "maxDecimalPoints" option', function () {
|
|
var h = humanizer({ maxDecimalPoints: 2 });
|
|
|
|
assert.strictEqual(h(8123.456789), "8.12 seconds");
|
|
h.maxDecimalPoints = 3;
|
|
assert.strictEqual(h(8123.456789), "8.123 seconds");
|
|
assert.strictEqual(h(8000), "8 seconds");
|
|
|
|
h.maxDecimalPoints = 6;
|
|
assert.strictEqual(h(8123.45), "8.12345 seconds");
|
|
|
|
h.maxDecimalPoints = 6;
|
|
assert.strictEqual(h(8000), "8 seconds");
|
|
|
|
h.maxDecimalPoints = 0;
|
|
assert.strictEqual(h(7123.456), "7 seconds");
|
|
h.maxDecimalPoints = 2;
|
|
assert.strictEqual(h(7999), "7.99 seconds");
|
|
h.maxDecimalPoints = 3;
|
|
assert.strictEqual(h(7999), "7.999 seconds");
|
|
});
|
|
|
|
it('pluralizes based on the count rendered by "maxDecimalPoints"', function () {
|
|
// A count truncated to exactly 1 must take the singular word.
|
|
assert.strictEqual(humanizer({ maxDecimalPoints: 0 })(1500), "1 second");
|
|
assert.strictEqual(humanizer({ maxDecimalPoints: 2 })(1005), "1 second");
|
|
// A truncated count that is not 1 stays plural.
|
|
assert.strictEqual(humanizer({ maxDecimalPoints: 0 })(2500), "2 seconds");
|
|
// German shares the same singular/plural mechanism.
|
|
assert.strictEqual(
|
|
humanizer({ language: "de", maxDecimalPoints: 0 })(1500),
|
|
"1 Sekunde"
|
|
);
|
|
});
|
|
|
|
it("can ask for the largest units", function () {
|
|
const h = humanizer({ largest: 2 });
|
|
|
|
assert.strictEqual(h(0), "0 seconds");
|
|
assert.strictEqual(h(1000), "1 second");
|
|
assert.strictEqual(h(2000), "2 seconds");
|
|
assert.strictEqual(h(540360012), "6 days, 6 hours");
|
|
assert.strictEqual(
|
|
h(540360012, { largest: 3 }),
|
|
"6 days, 6 hours, 6 minutes"
|
|
);
|
|
assert.strictEqual(
|
|
h(540360012, { largest: 100 }),
|
|
"6 days, 6 hours, 6 minutes, 0.012 seconds"
|
|
);
|
|
});
|
|
|
|
it("has properties which can be modified", function () {
|
|
const h = humanizer();
|
|
|
|
assert.strictEqual(h(363000), "6 minutes, 3 seconds");
|
|
|
|
h.delimiter = "+";
|
|
assert.strictEqual(h(363000), "6 minutes+3 seconds");
|
|
|
|
h.language = "es";
|
|
assert.strictEqual(h(363000), "6 minutos+3 segundos");
|
|
|
|
h.units = ["m"];
|
|
assert.strictEqual(h(363000), "6,05 minutos");
|
|
});
|
|
|
|
it("is a named function", function () {
|
|
assert.strictEqual(humanizer().name, "humanizer");
|
|
});
|
|
|
|
it("can add a new language", function () {
|
|
const h = humanizer({ language: "cool language" });
|
|
h.languages["cool language"] = {
|
|
y: () => "y",
|
|
mo: () => "mo",
|
|
w: () => "w",
|
|
d: () => "d",
|
|
h: () => "h",
|
|
m: () => "m",
|
|
s: () => "s",
|
|
ms: () => "ms",
|
|
delimiter: "--",
|
|
};
|
|
|
|
assert.strictEqual(h(1000), "1 s");
|
|
assert.strictEqual(h(61000), "1 m--1 s");
|
|
|
|
assert.strictEqual(h(61000, { delimiter: "&&" }), "1 m&&1 s");
|
|
|
|
assert.strictEqual(
|
|
h(1000, {
|
|
language: "es",
|
|
}),
|
|
"1 segundo"
|
|
);
|
|
|
|
const anotherH = humanizer({
|
|
language: "cool language",
|
|
});
|
|
assert.throws(() => {
|
|
anotherH(1000);
|
|
}, Error);
|
|
});
|
|
|
|
it("can overwrite an existing language", function () {
|
|
const h = humanizer({ language: "en" });
|
|
|
|
assert.strictEqual(h(1000), "1 second");
|
|
|
|
h.languages.en = {
|
|
y: () => "y",
|
|
mo: () => "mo",
|
|
w: () => "w",
|
|
d: () => "d",
|
|
h: () => "h",
|
|
m: () => "m",
|
|
s: () => "s",
|
|
ms: () => "ms",
|
|
};
|
|
|
|
assert.strictEqual(h(1000), "1 s");
|
|
assert.strictEqual(h(15600000), "4 h, 20 m");
|
|
|
|
const anotherH = humanizer({ language: "en" });
|
|
|
|
assert.strictEqual(anotherH(1000), "1 second");
|
|
});
|
|
|
|
it("can overwrite the languages property in the initializer", function () {
|
|
const h = humanizer({
|
|
languages: {
|
|
en: {
|
|
y: () => "y",
|
|
mo: () => "mo",
|
|
w: () => "w",
|
|
d: () => "d",
|
|
h: () => "h",
|
|
m: () => "m",
|
|
s: () => "s",
|
|
ms: () => "ms",
|
|
decimal: "!",
|
|
},
|
|
},
|
|
});
|
|
|
|
assert.strictEqual(h(1000), "1 s");
|
|
assert.strictEqual(h(15600000), "4 h, 20 m");
|
|
assert.strictEqual(h(1000, { language: "es" }), "1 segundo");
|
|
assert.strictEqual(h(71750), "1 m, 11!75 s");
|
|
});
|
|
|
|
it('uses "." as a fallback for a missing decimal', function () {
|
|
const h = humanizer({
|
|
languages: {
|
|
en: {
|
|
y: () => "y",
|
|
mo: () => "mo",
|
|
w: () => "w",
|
|
d: () => "d",
|
|
h: () => "h",
|
|
m: () => "m",
|
|
s: () => "s",
|
|
ms: () => "ms",
|
|
},
|
|
},
|
|
});
|
|
|
|
assert.strictEqual(h(71750), "1 m, 11.75 s");
|
|
assert.strictEqual(h(71750, { decimal: "!" }), "1 m, 11!75 s");
|
|
});
|
|
|
|
it("accepts fallback languages", function () {
|
|
const h = humanizer();
|
|
|
|
assert.strictEqual(
|
|
h(10000, { language: "es", fallbacks: ["en"] }),
|
|
"10 segundos"
|
|
);
|
|
assert.strictEqual(
|
|
h(10000, { language: "BAD", fallbacks: ["BAD", "es"] }),
|
|
"10 segundos"
|
|
);
|
|
assert.strictEqual(
|
|
h(10000, { language: "BAD", fallbacks: ["es", "fr"] }),
|
|
"10 segundos"
|
|
);
|
|
});
|
|
|
|
it("can replace digits", function () {
|
|
const h = humanizer({
|
|
digitReplacements: [
|
|
"Zero",
|
|
"One",
|
|
"Two",
|
|
"Three",
|
|
"UNUSED",
|
|
"UNUSED",
|
|
"UNUSED",
|
|
"UNUSED",
|
|
"UNUSED",
|
|
"UNUSED",
|
|
],
|
|
});
|
|
assert.strictEqual(h(123), "Zero.OneTwoThree seconds");
|
|
});
|
|
});
|