mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
LibJS: Implement most Intl.Locale.Prototype.<<keyword>> properties
The keyword accessors all have the same function body in the spec, except for the Intl.Locale method they invoke. This generates those properties in the same manner as RegExp.prototype. Intl.Locale.prototype.calendar Intl.Locale.prototype.caseFirst Intl.Locale.prototype.collation Intl.Locale.prototype.hourCycle Intl.Locale.prototype.numberingSystem The exception is Intl.Locale.prototype.numeric, which will be defined separately because it is a boolean value.
This commit is contained in:
parent
21b3c5edba
commit
d7825f3680
Notes:
sideshowbarker
2024-07-18 04:53:04 +09:00
Author: https://github.com/trflynn89 Commit: https://github.com/SerenityOS/serenity/commit/d7825f36800 Pull-request: https://github.com/SerenityOS/serenity/pull/9749 Reviewed-by: https://github.com/linusg ✅
7 changed files with 117 additions and 0 deletions
|
@ -47,6 +47,11 @@ void LocalePrototype::initialize(GlobalObject& global_object)
|
|||
define_direct_property(*vm.well_known_symbol_to_string_tag(), js_string(vm, "Intl.Locale"), Attribute::Configurable);
|
||||
|
||||
define_native_accessor(vm.names.baseName, base_name, {}, Attribute::Configurable);
|
||||
define_native_accessor(vm.names.calendar, calendar, {}, Attribute::Configurable);
|
||||
define_native_accessor(vm.names.caseFirst, case_first, {}, Attribute::Configurable);
|
||||
define_native_accessor(vm.names.collation, collation, {}, Attribute::Configurable);
|
||||
define_native_accessor(vm.names.hourCycle, hour_cycle, {}, Attribute::Configurable);
|
||||
define_native_accessor(vm.names.numberingSystem, numbering_system, {}, Attribute::Configurable);
|
||||
}
|
||||
|
||||
// 14.3.5 Intl.Locale.prototype.toString ( ), https://tc39.es/ecma402/#sec-Intl.Locale.prototype.toString
|
||||
|
@ -79,4 +84,29 @@ JS_DEFINE_NATIVE_GETTER(LocalePrototype::base_name)
|
|||
return js_string(vm, locale->language_id.to_string());
|
||||
}
|
||||
|
||||
#define JS_ENUMERATE_LOCALE_KEYWORD_PROPERTIES \
|
||||
__JS_ENUMERATE(calendar) \
|
||||
__JS_ENUMERATE(case_first) \
|
||||
__JS_ENUMERATE(collation) \
|
||||
__JS_ENUMERATE(hour_cycle) \
|
||||
__JS_ENUMERATE(numbering_system)
|
||||
|
||||
// 14.3.7 get Intl.Locale.prototype.calendar, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.calendar
|
||||
// 14.3.8 get Intl.Locale.prototype.caseFirst, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.caseFirst
|
||||
// 14.3.9 get Intl.Locale.prototype.collation, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.collation
|
||||
// 14.3.10 get Intl.Locale.prototype.hourCycle, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.hourCycle
|
||||
// 14.3.12 get Intl.Locale.prototype.numberingSystem, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.numberingSystem
|
||||
#define __JS_ENUMERATE(keyword) \
|
||||
JS_DEFINE_NATIVE_GETTER(LocalePrototype::keyword) \
|
||||
{ \
|
||||
auto* locale_object = typed_this(global_object); \
|
||||
if (!locale_object) \
|
||||
return {}; \
|
||||
if (!locale_object->has_##keyword()) \
|
||||
return js_undefined(); \
|
||||
return js_string(vm, locale_object->keyword()); \
|
||||
}
|
||||
JS_ENUMERATE_LOCALE_KEYWORD_PROPERTIES
|
||||
#undef __JS_ENUMERATE
|
||||
|
||||
}
|
||||
|
|
|
@ -22,6 +22,11 @@ private:
|
|||
JS_DECLARE_NATIVE_FUNCTION(to_string);
|
||||
|
||||
JS_DECLARE_NATIVE_GETTER(base_name);
|
||||
JS_DECLARE_NATIVE_GETTER(calendar);
|
||||
JS_DECLARE_NATIVE_GETTER(case_first);
|
||||
JS_DECLARE_NATIVE_GETTER(collation);
|
||||
JS_DECLARE_NATIVE_GETTER(hour_cycle);
|
||||
JS_DECLARE_NATIVE_GETTER(numbering_system);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
describe("errors", () => {
|
||||
test("called on non-Locale object", () => {
|
||||
expect(() => {
|
||||
Intl.Locale.prototype.calendar;
|
||||
}).toThrowWithMessage(TypeError, "Not a Intl.Locale object");
|
||||
});
|
||||
});
|
||||
|
||||
describe("normal behavior", () => {
|
||||
test("basic functionality", () => {
|
||||
expect(new Intl.Locale("en").calendar).toBeUndefined();
|
||||
expect(new Intl.Locale("en-u-ca-abc").calendar).toBe("abc");
|
||||
expect(new Intl.Locale("en", { calendar: "abc" }).calendar).toBe("abc");
|
||||
expect(new Intl.Locale("en-u-ca-abc", { calendar: "def" }).calendar).toBe("def");
|
||||
});
|
||||
});
|
|
@ -0,0 +1,16 @@
|
|||
describe("errors", () => {
|
||||
test("called on non-Locale object", () => {
|
||||
expect(() => {
|
||||
Intl.Locale.prototype.caseFirst;
|
||||
}).toThrowWithMessage(TypeError, "Not a Intl.Locale object");
|
||||
});
|
||||
});
|
||||
|
||||
describe("normal behavior", () => {
|
||||
test("basic functionality", () => {
|
||||
expect(new Intl.Locale("en").caseFirst).toBeUndefined();
|
||||
expect(new Intl.Locale("en-u-kf-upper").caseFirst).toBe("upper");
|
||||
expect(new Intl.Locale("en", { caseFirst: "lower" }).caseFirst).toBe("lower");
|
||||
expect(new Intl.Locale("en-u-kf-upper", { caseFirst: "false" }).caseFirst).toBe("false");
|
||||
});
|
||||
});
|
|
@ -0,0 +1,16 @@
|
|||
describe("errors", () => {
|
||||
test("called on non-Locale object", () => {
|
||||
expect(() => {
|
||||
Intl.Locale.prototype.collation;
|
||||
}).toThrowWithMessage(TypeError, "Not a Intl.Locale object");
|
||||
});
|
||||
});
|
||||
|
||||
describe("normal behavior", () => {
|
||||
test("basic functionality", () => {
|
||||
expect(new Intl.Locale("en").collation).toBeUndefined();
|
||||
expect(new Intl.Locale("en-u-co-abc").collation).toBe("abc");
|
||||
expect(new Intl.Locale("en", { collation: "abc" }).collation).toBe("abc");
|
||||
expect(new Intl.Locale("en-u-co-abc", { collation: "def" }).collation).toBe("def");
|
||||
});
|
||||
});
|
|
@ -0,0 +1,16 @@
|
|||
describe("errors", () => {
|
||||
test("called on non-Locale object", () => {
|
||||
expect(() => {
|
||||
Intl.Locale.prototype.hourCycle;
|
||||
}).toThrowWithMessage(TypeError, "Not a Intl.Locale object");
|
||||
});
|
||||
});
|
||||
|
||||
describe("normal behavior", () => {
|
||||
test("basic functionality", () => {
|
||||
expect(new Intl.Locale("en").hourCycle).toBeUndefined();
|
||||
expect(new Intl.Locale("en-u-hc-h11").hourCycle).toBe("h11");
|
||||
expect(new Intl.Locale("en", { hourCycle: "h12" }).hourCycle).toBe("h12");
|
||||
expect(new Intl.Locale("en-u-hc-h23", { hourCycle: "h24" }).hourCycle).toBe("h24");
|
||||
});
|
||||
});
|
|
@ -0,0 +1,18 @@
|
|||
describe("errors", () => {
|
||||
test("called on non-Locale object", () => {
|
||||
expect(() => {
|
||||
Intl.Locale.prototype.numberingSystem;
|
||||
}).toThrowWithMessage(TypeError, "Not a Intl.Locale object");
|
||||
});
|
||||
});
|
||||
|
||||
describe("normal behavior", () => {
|
||||
test("basic functionality", () => {
|
||||
expect(new Intl.Locale("en").numberingSystem).toBeUndefined();
|
||||
expect(new Intl.Locale("en-u-nu-abc").numberingSystem).toBe("abc");
|
||||
expect(new Intl.Locale("en", { numberingSystem: "abc" }).numberingSystem).toBe("abc");
|
||||
expect(new Intl.Locale("en-u-nu-abc", { numberingSystem: "def" }).numberingSystem).toBe(
|
||||
"def"
|
||||
);
|
||||
});
|
||||
});
|
Loading…
Reference in a new issue