diff --git a/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp index 34495b0c5e..2d48c84fa5 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp @@ -633,12 +633,17 @@ ThrowCompletionOr get_string_or_boolean_option(VM& vm, Object c // 6. Let value be ? ToString(value). auto value_string = TRY(value.to_string(vm)); - // 7. If values does not contain an element equal to value, return fallback. - auto it = find(values.begin(), values.end(), value_string); - if (it == values.end()) + // 7. NOTE: For historical reasons, the strings "true" and "false" are treated the same as the boolean value true. + // 8. If value is "true" or "false", return fallback. + if (value_string.is_one_of("true"sv, "false"sv)) return fallback; - // 8. Return value. + // 9. If values does not contain an element equal to value, throw a RangeError exception. + auto it = find(values.begin(), values.end(), value_string); + if (it == values.end()) + return vm.throw_completion(ErrorType::OptionIsNotValidValue, value_string, property.as_string()); + + // 10. Return value. return StringOrBoolean { *it }; } diff --git a/Userland/Libraries/LibJS/Tests/builtins/Intl/NumberFormat/NumberFormat.js b/Userland/Libraries/LibJS/Tests/builtins/Intl/NumberFormat/NumberFormat.js index 46a6509175..c4e0546183 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Intl/NumberFormat/NumberFormat.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Intl/NumberFormat/NumberFormat.js @@ -209,6 +209,12 @@ describe("errors", () => { }).toThrowWithMessage(RangeError, "hello! is not a valid value for option signDisplay"); }); + test("useGrouping option is invalid", () => { + expect(() => { + new Intl.NumberFormat("en", { useGrouping: "hello!" }); + }).toThrowWithMessage(RangeError, "hello! is not a valid value for option useGrouping"); + }); + test("roundingPriority option is invalid", () => { expect(() => { new Intl.NumberFormat("en", { roundingPriority: "hello!" }); @@ -416,7 +422,7 @@ describe("normal behavior", () => { }); test("valid useGrouping options", () => { - ["min2", "auto", "always", false, true, ""].forEach(useGrouping => { + ["min2", "auto", "always", false, true, "false", "true", ""].forEach(useGrouping => { expect(() => { new Intl.NumberFormat("en", { useGrouping: useGrouping }); }).not.toThrow(); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Intl/NumberFormat/NumberFormat.prototype.resolvedOptions.js b/Userland/Libraries/LibJS/Tests/builtins/Intl/NumberFormat/NumberFormat.prototype.resolvedOptions.js index e8ee8db9ac..26104748f6 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Intl/NumberFormat/NumberFormat.prototype.resolvedOptions.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Intl/NumberFormat/NumberFormat.prototype.resolvedOptions.js @@ -287,9 +287,15 @@ describe("correct behavior", () => { const en4 = new Intl.NumberFormat("en", { useGrouping: true }); expect(en4.resolvedOptions().useGrouping).toBe("always"); + const en5 = new Intl.NumberFormat("en", { useGrouping: "false" }); + expect(en5.resolvedOptions().useGrouping).toBe("auto"); + + const en6 = new Intl.NumberFormat("en", { useGrouping: "true" }); + expect(en6.resolvedOptions().useGrouping).toBe("auto"); + ["auto", "always", "min2"].forEach(useGrouping => { - const en5 = new Intl.NumberFormat("en", { useGrouping: useGrouping }); - expect(en5.resolvedOptions().useGrouping).toBe(useGrouping); + const en7 = new Intl.NumberFormat("en", { useGrouping: useGrouping }); + expect(en7.resolvedOptions().useGrouping).toBe(useGrouping); }); });