summaryrefslogtreecommitdiff
path: root/Userland/Libraries
diff options
context:
space:
mode:
authorstelar7 <dudedbz@gmail.com>2022-06-02 01:37:15 +0200
committerLinus Groh <mail@linusgroh.de>2022-06-02 23:04:27 +0100
commit771e3b9868ed479dc5119b52bb9cf2cfd2959a6a (patch)
treed96a1b989b07bc4f01e197e2aa8c02f1ff67956b /Userland/Libraries
parent0239c79d3df2bbce12bdf42e2c1f3c051c8f09f5 (diff)
downloadserenity-771e3b9868ed479dc5119b52bb9cf2cfd2959a6a.zip
LibJS: Stub out String.prototype.normalize
Diffstat (limited to 'Userland/Libraries')
-rw-r--r--Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h1
-rw-r--r--Userland/Libraries/LibJS/Runtime/ErrorTypes.h3
-rw-r--r--Userland/Libraries/LibJS/Runtime/StringPrototype.cpp26
-rw-r--r--Userland/Libraries/LibJS/Runtime/StringPrototype.h1
-rw-r--r--Userland/Libraries/LibJS/Tests/builtins/String/String.prototype.normalize.js54
5 files changed, 84 insertions, 1 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h
index f9a45402e8..19a26c2631 100644
--- a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h
+++ b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h
@@ -342,6 +342,7 @@ namespace JS {
P(nanoseconds) \
P(negated) \
P(next) \
+ P(normalize) \
P(notation) \
P(now) \
P(numberingSystem) \
diff --git a/Userland/Libraries/LibJS/Runtime/ErrorTypes.h b/Userland/Libraries/LibJS/Runtime/ErrorTypes.h
index 9e0ca0ed0b..03a90af47d 100644
--- a/Userland/Libraries/LibJS/Runtime/ErrorTypes.h
+++ b/Userland/Libraries/LibJS/Runtime/ErrorTypes.h
@@ -293,7 +293,8 @@
M(BadArgCountAtLeastOne, "{}() needs at least one argument") \
M(BadArgCountMany, "{}() needs {} arguments") \
M(NotEnoughMemoryToAllocate, "Not enough memory to allocate {} bytes") \
- M(InvalidEnumerationValue, "Invalid value '{}' for enumeration type '{}'")
+ M(InvalidEnumerationValue, "Invalid value '{}' for enumeration type '{}'") \
+ M(InvalidNormalizationForm, "The normalization form must be one of NFC, NFD, NFKC, NFKD. Got '{}'")
namespace JS {
diff --git a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp b/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp
index 396ca4897d..f8a55b8e3c 100644
--- a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp
+++ b/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp
@@ -143,6 +143,7 @@ void StringPrototype::initialize(GlobalObject& global_object)
define_native_function(vm.names.at, at, 1, attr);
define_native_function(vm.names.match, match, 1, attr);
define_native_function(vm.names.matchAll, match_all, 1, attr);
+ define_native_function(vm.names.normalize, normalize, 0, attr);
define_native_function(vm.names.replace, replace, 2, attr);
define_native_function(vm.names.replaceAll, replace_all, 2, attr);
define_native_function(vm.names.search, search, 1, attr);
@@ -803,6 +804,31 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::match_all)
return TRY(Value(rx).invoke(global_object, *vm.well_known_symbol_match_all(), js_string(vm, move(string))));
}
+// 22.1.3.14 String.prototype.normalize ( [ form ] ), https://tc39.es/ecma262/#sec-string.prototype.normalize
+JS_DEFINE_NATIVE_FUNCTION(StringPrototype::normalize)
+{
+ // 1. Let O be ? RequireObjectCoercible(this value).
+ // 2. Let S be ? ToString(O).
+ auto string = TRY(ak_string_from(vm, global_object));
+
+ // 3. If form is undefined, let f be "NFC".
+ // 4. Else, let f be ? ToString(form).
+ String form = "NFC";
+ auto form_value = vm.argument(0);
+ if (!form_value.is_undefined())
+ form = TRY(form_value.to_string(global_object));
+
+ // 5. If f is not one of "NFC", "NFD", "NFKC", or "NFKD", throw a RangeError exception.
+ if (!form.is_one_of("NFC"sv, "NFD"sv, "NFKC"sv, "NFKD"sv))
+ return vm.throw_completion<RangeError>(global_object, ErrorType::InvalidNormalizationForm, form);
+
+ // FIXME: 6. Let ns be the String value that is the result of normalizing S into the normalization form named by f as specified in https://unicode.org/reports/tr15/.
+ auto ns = string;
+
+ // 7. return ns.
+ return js_string(vm, move(ns));
+}
+
// 22.1.3.18 String.prototype.replace ( searchValue, replaceValue ), https://tc39.es/ecma262/#sec-string.prototype.replace
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::replace)
{
diff --git a/Userland/Libraries/LibJS/Runtime/StringPrototype.h b/Userland/Libraries/LibJS/Runtime/StringPrototype.h
index e33f8bb029..2493e47002 100644
--- a/Userland/Libraries/LibJS/Runtime/StringPrototype.h
+++ b/Userland/Libraries/LibJS/Runtime/StringPrototype.h
@@ -57,6 +57,7 @@ private:
JS_DECLARE_NATIVE_FUNCTION(at);
JS_DECLARE_NATIVE_FUNCTION(match);
JS_DECLARE_NATIVE_FUNCTION(match_all);
+ JS_DECLARE_NATIVE_FUNCTION(normalize);
JS_DECLARE_NATIVE_FUNCTION(replace);
JS_DECLARE_NATIVE_FUNCTION(replace_all);
JS_DECLARE_NATIVE_FUNCTION(search);
diff --git a/Userland/Libraries/LibJS/Tests/builtins/String/String.prototype.normalize.js b/Userland/Libraries/LibJS/Tests/builtins/String/String.prototype.normalize.js
new file mode 100644
index 0000000000..3081cf73af
--- /dev/null
+++ b/Userland/Libraries/LibJS/Tests/builtins/String/String.prototype.normalize.js
@@ -0,0 +1,54 @@
+test("Function length is 0", () => {
+ expect(String.prototype.normalize).toHaveLength(0);
+});
+
+test("Function name is normalize", () => {
+ expect(String.prototype.normalize.name).toBe("normalize");
+});
+
+test("Type is function", () => {
+ expect(typeof String.prototype.normalize).toBe("function");
+});
+
+test("Invalid form throws", () => {
+ expect(() => "foo".normalize("bar")).toThrowWithMessage(
+ RangeError,
+ "The normalization form must be one of NFC, NFD, NFKC, NFKD. Got 'bar'"
+ );
+ expect(() => "foo".normalize("NFC1")).toThrowWithMessage(
+ RangeError,
+ "The normalization form must be one of NFC, NFD, NFKC, NFKD. Got 'NFC1'"
+ );
+ expect(() => "foo".normalize(null)).toThrowWithMessage(
+ RangeError,
+ "The normalization form must be one of NFC, NFD, NFKC, NFKD. Got 'null'"
+ );
+});
+
+test("Invalid object throws", () => {
+ expect(() => String.prototype.normalize.call(undefined)).toThrowWithMessage(
+ TypeError,
+ "undefined cannot be converted to an object"
+ );
+ expect(() => String.prototype.normalize.call(null)).toThrowWithMessage(
+ TypeError,
+ "null cannot be converted to an object"
+ );
+});
+
+// Tests below here are skipped due to the function being a stub at the moment
+test.skip("Normalization works", () => {
+ var s = "\u1E9B\u0323";
+
+ expect(s.normalize("NFC")).toBe("\u1E9B\u0323");
+ expect(s.normalize("NFD")).toBe("\u017F\u0323\u0307");
+ expect(s.normalize("NFKC")).toBe("\u1E69");
+ expect(s.normalize("NFKD")).toBe("\u0073\u0323\u0307");
+});
+
+test.skip("Default parameter is NFC", () => {
+ var s = "\u1E9B\u0323";
+
+ expect(s.normalize("NFC")).toBe(s.normalize());
+ expect(s.normalize("NFC")).toBe(s.normalize(undefined));
+});