mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 02:47:35 +00:00
LibJS+js: Parse new constructor options from Intl.NumberFormat V3
This contains minimal changes to parse newly added and modified options from the Intl.NumberFormat V3 proposal, while maintaining main spec behavior in Intl.NumberFormat.prototype.format. The parsed options are reflected only in Intl.NumberFormat.prototype.resolvedOptions and the js REPL.
This commit is contained in:
parent
cd8bcd06c6
commit
33698b9615
11 changed files with 589 additions and 75 deletions
|
@ -208,6 +208,70 @@ describe("errors", () => {
|
|||
new Intl.NumberFormat("en", { signDisplay: "hello!" });
|
||||
}).toThrowWithMessage(RangeError, "hello! is not a valid value for option signDisplay");
|
||||
});
|
||||
|
||||
test("roundingPriority option is invalid", () => {
|
||||
expect(() => {
|
||||
new Intl.NumberFormat("en", { roundingPriority: "hello!" });
|
||||
}).toThrowWithMessage(
|
||||
RangeError,
|
||||
"hello! is not a valid value for option roundingPriority"
|
||||
);
|
||||
});
|
||||
|
||||
test("roundingMode option is invalid", () => {
|
||||
expect(() => {
|
||||
new Intl.NumberFormat("en", { roundingMode: "hello!" });
|
||||
}).toThrowWithMessage(RangeError, "hello! is not a valid value for option roundingMode");
|
||||
});
|
||||
|
||||
test("roundingIncrement option is invalid", () => {
|
||||
expect(() => {
|
||||
new Intl.NumberFormat("en", { roundingIncrement: "hello!" });
|
||||
}).toThrowWithMessage(RangeError, "Value NaN is NaN or is not between 1 and 5000");
|
||||
|
||||
expect(() => {
|
||||
new Intl.NumberFormat("en", { roundingIncrement: 0 });
|
||||
}).toThrowWithMessage(RangeError, "Value 0 is NaN or is not between 1 and 5000");
|
||||
|
||||
expect(() => {
|
||||
new Intl.NumberFormat("en", { roundingIncrement: 5001 });
|
||||
}).toThrowWithMessage(RangeError, "Value 5001 is NaN or is not between 1 and 5000");
|
||||
|
||||
expect(() => {
|
||||
new Intl.NumberFormat("en", {
|
||||
roundingIncrement: 3,
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
});
|
||||
}).toThrowWithMessage(RangeError, "3 is not a valid rounding increment");
|
||||
|
||||
expect(() => {
|
||||
new Intl.NumberFormat("en", { roundingIncrement: 5, minimumSignificantDigits: 1 });
|
||||
}).toThrowWithMessage(
|
||||
TypeError,
|
||||
"5 is not a valid rounding increment for rounding type significantDigits"
|
||||
);
|
||||
|
||||
expect(() => {
|
||||
new Intl.NumberFormat("en", {
|
||||
roundingIncrement: 5,
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 3,
|
||||
});
|
||||
}).toThrowWithMessage(
|
||||
RangeError,
|
||||
"5 is not a valid rounding increment for inequal min/max fraction digits"
|
||||
);
|
||||
});
|
||||
|
||||
test("trailingZeroDisplay option is invalid", () => {
|
||||
expect(() => {
|
||||
new Intl.NumberFormat("en", { trailingZeroDisplay: "hello!" });
|
||||
}).toThrowWithMessage(
|
||||
RangeError,
|
||||
"hello! is not a valid value for option trailingZeroDisplay"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("normal behavior", () => {
|
||||
|
@ -344,10 +408,66 @@ describe("normal behavior", () => {
|
|||
});
|
||||
|
||||
test("all valid signDisplay options", () => {
|
||||
["auto", "never", "always", "exceptZero"].forEach(signDisplay => {
|
||||
["auto", "never", "always", "exceptZero", "negative"].forEach(signDisplay => {
|
||||
expect(() => {
|
||||
new Intl.NumberFormat("en", { signDisplay: signDisplay });
|
||||
}).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
test("valid useGrouping options", () => {
|
||||
["min2", "auto", "always", false, true, ""].forEach(useGrouping => {
|
||||
expect(() => {
|
||||
new Intl.NumberFormat("en", { useGrouping: useGrouping });
|
||||
}).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
test("all valid roundingPriority options", () => {
|
||||
["auto", "morePrecision", "lessPrecision"].forEach(roundingPriority => {
|
||||
expect(() => {
|
||||
new Intl.NumberFormat("en", { roundingPriority: roundingPriority });
|
||||
}).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
test("all valid roundingMode options", () => {
|
||||
[
|
||||
"ceil",
|
||||
"floor",
|
||||
"expand",
|
||||
"trunc",
|
||||
"halfCeil",
|
||||
"halfFloor",
|
||||
"halfExpand",
|
||||
"halfTrunc",
|
||||
"halfEven",
|
||||
].forEach(roundingMode => {
|
||||
expect(() => {
|
||||
new Intl.NumberFormat("en", { roundingMode: roundingMode });
|
||||
}).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
test("all valid roundingIncrement options", () => {
|
||||
[1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, 5000].forEach(
|
||||
roundingIncrement => {
|
||||
expect(() => {
|
||||
new Intl.NumberFormat("en", {
|
||||
roundingIncrement: roundingIncrement,
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
});
|
||||
}).not.toThrow();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test("all valid trailingZeroDisplay options", () => {
|
||||
["auto", "stripIfInteger"].forEach(trailingZeroDisplay => {
|
||||
expect(() => {
|
||||
new Intl.NumberFormat("en", { trailingZeroDisplay: trailingZeroDisplay });
|
||||
}).not.toThrow();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -176,12 +176,12 @@ describe("correct behavior", () => {
|
|||
});
|
||||
});
|
||||
|
||||
test("compact notation causes all min/max digits to be undefined by default", () => {
|
||||
test("compact notation causes all min/max digits to be set to default values", () => {
|
||||
const en = new Intl.NumberFormat("en", { notation: "compact" });
|
||||
expect(en.resolvedOptions().minimumFractionDigits).toBeUndefined();
|
||||
expect(en.resolvedOptions().maximumFractionDigits).toBeUndefined();
|
||||
expect(en.resolvedOptions().minimumSignificantDigits).toBeUndefined();
|
||||
expect(en.resolvedOptions().maximumSignificantDigits).toBeUndefined();
|
||||
expect(en.resolvedOptions().minimumFractionDigits).toBe(0);
|
||||
expect(en.resolvedOptions().maximumFractionDigits).toBe(0);
|
||||
expect(en.resolvedOptions().minimumSignificantDigits).toBe(1);
|
||||
expect(en.resolvedOptions().maximumSignificantDigits).toBe(2);
|
||||
});
|
||||
|
||||
test("currency display and sign only defined when style is currency", () => {
|
||||
|
@ -276,19 +276,89 @@ describe("correct behavior", () => {
|
|||
|
||||
test("use grouping", () => {
|
||||
const en1 = new Intl.NumberFormat("en");
|
||||
expect(en1.resolvedOptions().useGrouping).toBeTrue();
|
||||
expect(en1.resolvedOptions().useGrouping).toBe("auto");
|
||||
|
||||
const en2 = new Intl.NumberFormat("en", { useGrouping: false });
|
||||
expect(en2.resolvedOptions().useGrouping).toBeFalse();
|
||||
const en2 = new Intl.NumberFormat("en", { notation: "compact" });
|
||||
expect(en2.resolvedOptions().useGrouping).toBe("min2");
|
||||
|
||||
const en3 = new Intl.NumberFormat("en", { useGrouping: false });
|
||||
expect(en3.resolvedOptions().useGrouping).toBeFalse();
|
||||
|
||||
const en4 = new Intl.NumberFormat("en", { useGrouping: true });
|
||||
expect(en4.resolvedOptions().useGrouping).toBe("always");
|
||||
|
||||
["auto", "always", "min2"].forEach(useGrouping => {
|
||||
const en5 = new Intl.NumberFormat("en", { useGrouping: useGrouping });
|
||||
expect(en5.resolvedOptions().useGrouping).toBe(useGrouping);
|
||||
});
|
||||
});
|
||||
|
||||
test("sign display", () => {
|
||||
const en1 = new Intl.NumberFormat("en");
|
||||
expect(en1.resolvedOptions().signDisplay).toBe("auto");
|
||||
|
||||
["auto", "never", "always", "exceptZero"].forEach(signDisplay => {
|
||||
["auto", "never", "always", "exceptZero", "negative"].forEach(signDisplay => {
|
||||
const en2 = new Intl.NumberFormat("en", { signDisplay: signDisplay });
|
||||
expect(en2.resolvedOptions().signDisplay).toBe(signDisplay);
|
||||
});
|
||||
});
|
||||
|
||||
test("rounding priority", () => {
|
||||
const en1 = new Intl.NumberFormat("en");
|
||||
expect(en1.resolvedOptions().roundingPriority).toBe("auto");
|
||||
|
||||
const en2 = new Intl.NumberFormat("en", { notation: "compact" });
|
||||
expect(en2.resolvedOptions().roundingPriority).toBe("morePrecision");
|
||||
|
||||
["auto", "morePrecision", "lessPrecision"].forEach(roundingPriority => {
|
||||
const en3 = new Intl.NumberFormat("en", { roundingPriority: roundingPriority });
|
||||
expect(en3.resolvedOptions().roundingPriority).toBe(roundingPriority);
|
||||
});
|
||||
});
|
||||
|
||||
test("rounding mode", () => {
|
||||
const en1 = new Intl.NumberFormat("en");
|
||||
expect(en1.resolvedOptions().roundingMode).toBe("halfExpand");
|
||||
|
||||
[
|
||||
"ceil",
|
||||
"floor",
|
||||
"expand",
|
||||
"trunc",
|
||||
"halfCeil",
|
||||
"halfFloor",
|
||||
"halfExpand",
|
||||
"halfTrunc",
|
||||
"halfEven",
|
||||
].forEach(roundingMode => {
|
||||
const en2 = new Intl.NumberFormat("en", { roundingMode: roundingMode });
|
||||
expect(en2.resolvedOptions().roundingMode).toBe(roundingMode);
|
||||
});
|
||||
});
|
||||
|
||||
test("rounding increment", () => {
|
||||
const en1 = new Intl.NumberFormat("en");
|
||||
expect(en1.resolvedOptions().roundingIncrement).toBe(1);
|
||||
|
||||
[1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, 5000].forEach(
|
||||
roundingIncrement => {
|
||||
const en2 = new Intl.NumberFormat("en", {
|
||||
roundingIncrement: roundingIncrement,
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
});
|
||||
expect(en2.resolvedOptions().roundingIncrement).toBe(roundingIncrement);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test("trailing zero display", () => {
|
||||
const en1 = new Intl.NumberFormat("en");
|
||||
expect(en1.resolvedOptions().trailingZeroDisplay).toBe("auto");
|
||||
|
||||
["auto", "stripIfInteger"].forEach(trailingZeroDisplay => {
|
||||
const en2 = new Intl.NumberFormat("en", { trailingZeroDisplay: trailingZeroDisplay });
|
||||
expect(en2.resolvedOptions().trailingZeroDisplay).toBe(trailingZeroDisplay);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue