mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 01:07:35 +00:00
LibJS: Implement Temporal.Duration.prototype.round
This commit is contained in:
parent
4a08fd2be2
commit
acf8729a81
4 changed files with 291 additions and 0 deletions
|
@ -0,0 +1,164 @@
|
|||
describe("correct behavior", () => {
|
||||
test("length is 1", () => {
|
||||
expect(Temporal.Duration.prototype.round).toHaveLength(1);
|
||||
});
|
||||
|
||||
test("basic functionality", () => {
|
||||
const duration = new Temporal.Duration(0, 0, 0, 21, 7, 10, 100, 200, 300, 400);
|
||||
const values = [
|
||||
["nanosecond", "P21DT7H11M40.2003004S"],
|
||||
["microsecond", "P21DT7H11M40.2003S"],
|
||||
["millisecond", "P21DT7H11M40.2S"],
|
||||
["second", "P21DT7H11M40S"],
|
||||
["minute", "P21DT7H12M"],
|
||||
["hour", "P21DT7H"],
|
||||
["day", "P21D"],
|
||||
];
|
||||
|
||||
for (const [smallestUnit, durationString] of values) {
|
||||
const singularRoundedDuration = duration.round({ smallestUnit });
|
||||
const pluralRoundedDuration = duration.round({ smallestUnit: `${smallestUnit}s` });
|
||||
|
||||
// Passing in a string is treated as though { smallestUnit: "<string value>" } was passed in.
|
||||
const singularRoundedDurationWithString = duration.round(smallestUnit);
|
||||
const pluralRoundedDurationWithString = duration.round(`${smallestUnit}s`);
|
||||
|
||||
expect(singularRoundedDuration.toString()).toBe(durationString);
|
||||
expect(singularRoundedDurationWithString.toString()).toBe(durationString);
|
||||
expect(pluralRoundedDuration.toString()).toBe(durationString);
|
||||
expect(pluralRoundedDurationWithString.toString()).toBe(durationString);
|
||||
}
|
||||
});
|
||||
|
||||
test("largestUnit option", () => {
|
||||
const duration = new Temporal.Duration(0, 0, 0, 21, 7, 10, 100, 200, 300, 400);
|
||||
|
||||
// Using strings is not sufficient here, for example, the nanosecond case will produce "PT1840300.2003004S" which is 1840300 s, 200 ms, 300 us, 400 ns
|
||||
const values = [
|
||||
["nanosecond", { nanoseconds: 1840300200300400 }],
|
||||
["microsecond", { microseconds: 1840300200300, nanoseconds: 400 }],
|
||||
["millisecond", { milliseconds: 1840300200, microseconds: 300, nanoseconds: 400 }],
|
||||
[
|
||||
"second",
|
||||
{ seconds: 1840300, milliseconds: 200, microseconds: 300, nanoseconds: 400 },
|
||||
],
|
||||
[
|
||||
"minute",
|
||||
{
|
||||
minutes: 30671,
|
||||
seconds: 40,
|
||||
milliseconds: 200,
|
||||
microseconds: 300,
|
||||
nanoseconds: 400,
|
||||
},
|
||||
],
|
||||
[
|
||||
"hour",
|
||||
{
|
||||
hours: 511,
|
||||
minutes: 11,
|
||||
seconds: 40,
|
||||
milliseconds: 200,
|
||||
microseconds: 300,
|
||||
nanoseconds: 400,
|
||||
},
|
||||
],
|
||||
[
|
||||
"day",
|
||||
{
|
||||
days: 21,
|
||||
hours: 7,
|
||||
minutes: 11,
|
||||
seconds: 40,
|
||||
milliseconds: 200,
|
||||
microseconds: 300,
|
||||
nanoseconds: 400,
|
||||
},
|
||||
],
|
||||
];
|
||||
|
||||
for (const [largestUnit, durationLike] of values) {
|
||||
const singularRoundedDuration = duration.round({ largestUnit });
|
||||
const pluralRoundedDuration = duration.round({ largestUnit: `${largestUnit}s` });
|
||||
|
||||
const propertiesToCheck = Object.keys(durationLike);
|
||||
|
||||
for (const property of propertiesToCheck) {
|
||||
expect(singularRoundedDuration[property]).toBe(durationLike[property]);
|
||||
expect(pluralRoundedDuration[property]).toBe(durationLike[property]);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("errors", () => {
|
||||
test("this value must be a Temporal.Duration object", () => {
|
||||
expect(() => {
|
||||
Temporal.Duration.prototype.round.call("foo");
|
||||
}).toThrowWithMessage(TypeError, "Not an object of type Temporal.Duration");
|
||||
});
|
||||
|
||||
test("missing options object", () => {
|
||||
const duration = new Temporal.Duration(1);
|
||||
expect(() => {
|
||||
duration.round();
|
||||
}).toThrowWithMessage(TypeError, "Required options object is missing or undefined");
|
||||
});
|
||||
|
||||
test("invalid rounding mode", () => {
|
||||
const duration = new Temporal.Duration(1);
|
||||
expect(() => {
|
||||
duration.round({ smallestUnit: "second", roundingMode: "serenityOS" });
|
||||
}).toThrowWithMessage(
|
||||
RangeError,
|
||||
"serenityOS is not a valid value for option roundingMode"
|
||||
);
|
||||
});
|
||||
|
||||
test("invalid smallest unit", () => {
|
||||
const duration = new Temporal.Duration(1);
|
||||
expect(() => {
|
||||
duration.round({ smallestUnit: "serenityOS" });
|
||||
}).toThrowWithMessage(
|
||||
RangeError,
|
||||
"serenityOS is not a valid value for option smallestUnit"
|
||||
);
|
||||
});
|
||||
|
||||
test("increment may not be NaN", () => {
|
||||
const duration = new Temporal.Duration(1);
|
||||
expect(() => {
|
||||
duration.round({ smallestUnit: "second", roundingIncrement: NaN });
|
||||
}).toThrowWithMessage(RangeError, "NaN is not a valid value for option roundingIncrement");
|
||||
});
|
||||
|
||||
test("increment may smaller than 1 or larger than maximum", () => {
|
||||
const duration = new Temporal.Duration(1);
|
||||
expect(() => {
|
||||
duration.round({ smallestUnit: "second", roundingIncrement: -1 });
|
||||
}).toThrowWithMessage(RangeError, "-1 is not a valid value for option roundingIncrement");
|
||||
expect(() => {
|
||||
duration.round({ smallestUnit: "second", roundingIncrement: 0 });
|
||||
}).toThrowWithMessage(RangeError, "0 is not a valid value for option roundingIncrement");
|
||||
expect(() => {
|
||||
duration.round({ smallestUnit: "second", roundingIncrement: Infinity });
|
||||
}).toThrowWithMessage(RangeError, "inf is not a valid value for option roundingIncrement");
|
||||
});
|
||||
|
||||
test("must provide one or both of smallestUnit or largestUnit", () => {
|
||||
const duration = new Temporal.Duration(1);
|
||||
expect(() => {
|
||||
duration.round({});
|
||||
}).toThrowWithMessage(RangeError, "One or both of smallestUnit or largestUnit is required");
|
||||
});
|
||||
|
||||
test("relativeTo is required when duration has calendar units", () => {
|
||||
const duration = new Temporal.Duration(1);
|
||||
expect(() => {
|
||||
duration.round({ largestUnit: "second" });
|
||||
}).toThrowWithMessage(
|
||||
RangeError,
|
||||
"A starting point is required for balancing calendar units"
|
||||
);
|
||||
});
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue