From c996a0ceeb5d5882144b786e1f15a274f4ced41e Mon Sep 17 00:00:00 2001 From: Igor Randjelovic Date: Fri, 11 Oct 2024 14:28:28 +0200 Subject: [PATCH] fix(URL): allow undefined 2nd args and fix pathname return value --- NativeScript/runtime/URLImpl.cpp | 49 ++++++++--------- TestRunner/app/tests/URL.js | 90 +++++++++++++++++++++----------- 2 files changed, 83 insertions(+), 56 deletions(-) diff --git a/NativeScript/runtime/URLImpl.cpp b/NativeScript/runtime/URLImpl.cpp index 50ca6157..a8c322d9 100644 --- a/NativeScript/runtime/URLImpl.cpp +++ b/NativeScript/runtime/URLImpl.cpp @@ -141,6 +141,16 @@ void URLImpl::Ctor(const v8::FunctionCallbackInfo &args) { auto result = ada::parse(url_string, &base_url.value()); + if (result) { + url = result.value(); + } else { + isolate->ThrowException( + v8::Exception::TypeError(ToV8String(isolate, ""))); + return; + } + } else { + // treat 2nd arg as undefined otherwise. + auto result = ada::parse(url_string, nullptr); if (result) { url = result.value(); } else { @@ -149,7 +159,6 @@ void URLImpl::Ctor(const v8::FunctionCallbackInfo &args) { return; } } - } else { auto result = ada::parse(url_string, nullptr); if (result) { @@ -242,7 +251,6 @@ void URLImpl::GetHostName(v8::Local property, auto value = ptr->GetURL()->get_hostname(); info.GetReturnValue().Set(ToV8String(isolate, value.data(), (int)value.length())); - } void URLImpl::SetHostName(v8::Local property, @@ -271,7 +279,6 @@ void URLImpl::GetHref(v8::Local property, auto value = ptr->GetURL()->get_href(); info.GetReturnValue().Set(ToV8String(isolate, value.data(), (int)value.length())); - } void URLImpl::SetHref(v8::Local property, @@ -299,7 +306,6 @@ void URLImpl::GetOrigin(v8::Local property, auto value = ptr->GetURL()->get_origin(); info.GetReturnValue().Set(ToV8String(isolate, value.c_str())); - } void URLImpl::GetPassword(v8::Local property, @@ -314,7 +320,6 @@ void URLImpl::GetPassword(v8::Local property, auto value = ptr->GetURL()->get_password(); info.GetReturnValue().Set(ToV8String(isolate, value.data(), (int)value.length())); - } void URLImpl::SetPassword(v8::Local property, @@ -341,8 +346,7 @@ void URLImpl::GetPathName(v8::Local property, auto value = ptr->GetURL()->get_pathname(); - info.GetReturnValue().Set(ToV8String(isolate, value.data())); - + info.GetReturnValue().Set(ToV8String(isolate, value.data(), (int)value.length())); } void URLImpl::SetPathName(v8::Local property, @@ -370,7 +374,6 @@ void URLImpl::GetPort(v8::Local property, auto value = ptr->GetURL()->get_port(); info.GetReturnValue().Set(ToV8String(isolate, value.data(), (int)value.length())); - } void URLImpl::SetPort(v8::Local property, @@ -398,7 +401,6 @@ void URLImpl::GetProtocol(v8::Local property, auto value = ptr->GetURL()->get_protocol(); info.GetReturnValue().Set(ToV8String(isolate, value.data(), (int)value.length())); - } void URLImpl::SetProtocol(v8::Local property, @@ -427,7 +429,6 @@ void URLImpl::GetSearch(v8::Local property, auto value = ptr->GetURL()->get_search(); info.GetReturnValue().Set(ToV8String(isolate, value.data(), (int)value.length())); - } void URLImpl::SetSearch(v8::Local property, @@ -456,7 +457,6 @@ void URLImpl::GetUserName(v8::Local property, auto value = ptr->GetURL()->get_username(); info.GetReturnValue().Set(ToV8String(isolate, value.data(), (int)value.length())); - } void URLImpl::SetUserName(v8::Local property, @@ -473,39 +473,36 @@ void URLImpl::SetUserName(v8::Local property, } -void URLImpl::ToString(const v8::FunctionCallbackInfo &args) { - URLImpl *ptr = GetPointer(args.This()); +void URLImpl::ToString(const v8::FunctionCallbackInfo &info) { + URLImpl *ptr = GetPointer(info.This()); if (ptr == nullptr) { - args.GetReturnValue().SetEmptyString(); + info.GetReturnValue().SetEmptyString(); return; } - auto isolate = args.GetIsolate(); + auto isolate = info.GetIsolate(); auto value = ptr->GetURL()->get_href(); - auto ret = ToV8String(isolate, value.data(), (int)value.length()); - - args.GetReturnValue().Set(ret); + info.GetReturnValue().Set(ToV8String(isolate, value.data(), (int)value.length())); } -void URLImpl::CanParse(const v8::FunctionCallbackInfo &args) { +void URLImpl::CanParse(const v8::FunctionCallbackInfo &info) { bool value; - auto count = args.Length(); + auto count = info.Length(); - - auto isolate = args.GetIsolate(); + auto isolate = info.GetIsolate(); if (count > 1) { - auto url_string = tns::ToString(isolate, args[0].As()); - auto base_string = tns::ToString(isolate, args[1].As()); + auto url_string = tns::ToString(isolate, info[0].As()); + auto base_string = tns::ToString(isolate, info[1].As()); std::string_view base_string_view(base_string.data(), base_string.length()); value = can_parse(url_string, &base_string_view); } else { - value = can_parse(tns::ToString(isolate, args[0].As()).c_str(), nullptr); + value = can_parse(tns::ToString(isolate, info[0].As()).c_str(), nullptr); } - args.GetReturnValue().Set(value); + info.GetReturnValue().Set(value); } diff --git a/TestRunner/app/tests/URL.js b/TestRunner/app/tests/URL.js index 5ebda35c..245d3b0a 100644 --- a/TestRunner/app/tests/URL.js +++ b/TestRunner/app/tests/URL.js @@ -1,31 +1,61 @@ -describe("Test URL ", function () { - - it("Test invalid URL parsing", function(){ - var exceptionCaught = false; - try { - const url = new URL(''); - }catch(e){ - exceptionCaught = true; - } - expect(exceptionCaught).toBe(true); - }); - - it("Test valid URL parsing", function(){ - var exceptionCaught = false; - try { - const url = new URL('https://google.com'); - }catch(e){ - exceptionCaught = true; - } - expect(exceptionCaught).toBe(false); - }); - - - it("Test URL fields", function(){ - var exceptionCaught = false; - const url = new URL('https://google.com'); - expect(url.protocol).toBe('https:'); - expect(url.hostname).toBe('google.com'); - }); - +describe("URL", function () { + it("throws on invalid URL", function () { + var exceptionCaught = false; + try { + const url = new URL(""); + } catch (e) { + exceptionCaught = true; + } + expect(exceptionCaught).toBe(true); + }); + + it("does not throw on valid URL", function () { + var exceptionCaught = false; + try { + const url = new URL("https://google.com"); + } catch (e) { + exceptionCaught = true; + } + expect(exceptionCaught).toBe(false); + }); + + it("parses simple urls", function () { + const url = new URL("https://google.com"); + expect(url.protocol).toBe("https:"); + expect(url.hostname).toBe("google.com"); + expect(url.pathname).toBe("/"); + expect(url.port).toBe(""); + expect(url.search).toBe(""); + expect(url.hash).toBe(""); + expect(url.username).toBe(""); + expect(url.password).toBe(""); + expect(url.origin).toBe("https://google.com"); + expect(url.searchParams.size).toBe(0); + }); + + it("parses with undefined base", function () { + const url = new URL("https://google.com", undefined); + expect(url.protocol).toBe("https:"); + expect(url.hostname).toBe("google.com"); + }); + + it("parses with null base", function () { + const url = new URL("https://google.com", null); + expect(url.protocol).toBe("https:"); + expect(url.hostname).toBe("google.com"); + }); + + it("parses query strings", function () { + const url = new URL("https://google.com?q=hello"); + expect(url.search).toBe("?q=hello"); + expect(url.searchParams.get("q")).toBe("hello"); + expect(url.pathname).toBe("/"); + }); + + it("parses query strings with pathname", function () { + const url = new URL("https://google.com/some/path?q=hello"); + expect(url.search).toBe("?q=hello"); + expect(url.searchParams.get("q")).toBe("hello"); + expect(url.pathname).toBe("/some/path"); + }); });