Skip to content

Commit bd4e23c

Browse files
committed
url: align default argument handling for URLPattern with webidl
1 parent e35a00e commit bd4e23c

File tree

2 files changed

+56
-7
lines changed

2 files changed

+56
-7
lines changed

src/node_url_pattern.cc

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,10 @@ void URLPattern::New(const FunctionCallbackInfo<Value>& args) {
202202
// - new URLPattern(input, baseURL)
203203
// - new URLPattern(input, options)
204204
// - new URLPattern(input, baseURL, options)
205-
if (args[0]->IsString()) {
205+
// Per WebIDL, undefined for an optional argument uses the default value.
206+
if (args[0]->IsUndefined()) {
207+
init = ada::url_pattern_init{};
208+
} else if (args[0]->IsString()) {
206209
BufferValue input_buffer(env->isolate(), args[0]);
207210
CHECK_NOT_NULL(*input_buffer);
208211
input = input_buffer.ToString();
@@ -218,7 +221,7 @@ void URLPattern::New(const FunctionCallbackInfo<Value>& args) {
218221
}
219222

220223
// The next argument can be baseURL or options.
221-
if (args.Length() > 1) {
224+
if (args.Length() > 1 && !args[1]->IsUndefined()) {
222225
if (args[1]->IsString()) {
223226
BufferValue base_url_buffer(env->isolate(), args[1]);
224227
CHECK_NOT_NULL(*base_url_buffer);
@@ -239,7 +242,7 @@ void URLPattern::New(const FunctionCallbackInfo<Value>& args) {
239242
}
240243

241244
// Only remaining argument can be options.
242-
if (args.Length() > 2) {
245+
if (args.Length() > 2 && !args[2]->IsUndefined()) {
243246
if (!args[2]->IsObject()) {
244247
THROW_ERR_INVALID_ARG_TYPE(env, "options must be an object");
245248
return;
@@ -564,7 +567,7 @@ void URLPattern::Exec(const FunctionCallbackInfo<Value>& args) {
564567
ada::url_pattern_input input;
565568
std::optional<std::string> baseURL{};
566569
std::string input_base;
567-
if (args.Length() == 0) {
570+
if (args.Length() == 0 || args[0]->IsUndefined()) {
568571
input = ada::url_pattern_init{};
569572
} else if (args[0]->IsString()) {
570573
Utf8Value input_value(env->isolate(), args[0].As<String>());
@@ -580,7 +583,7 @@ void URLPattern::Exec(const FunctionCallbackInfo<Value>& args) {
580583
return;
581584
}
582585

583-
if (args.Length() > 1) {
586+
if (args.Length() > 1 && !args[1]->IsUndefined()) {
584587
if (!args[1]->IsString()) {
585588
THROW_ERR_INVALID_ARG_TYPE(env, "baseURL must be a string");
586589
return;
@@ -607,7 +610,7 @@ void URLPattern::Test(const FunctionCallbackInfo<Value>& args) {
607610
ada::url_pattern_input input;
608611
std::optional<std::string> baseURL{};
609612
std::string input_base;
610-
if (args.Length() == 0) {
613+
if (args.Length() == 0 || args[0]->IsUndefined()) {
611614
input = ada::url_pattern_init{};
612615
} else if (args[0]->IsString()) {
613616
Utf8Value input_value(env->isolate(), args[0].As<String>());
@@ -623,7 +626,7 @@ void URLPattern::Test(const FunctionCallbackInfo<Value>& args) {
623626
return;
624627
}
625628

626-
if (args.Length() > 1) {
629+
if (args.Length() > 1 && !args[1]->IsUndefined()) {
627630
if (!args[1]->IsString()) {
628631
THROW_ERR_INVALID_ARG_TYPE(env, "baseURL must be a string");
629632
return;

test/parallel/test-urlpattern-types.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,49 @@ assert.throws(() => pattern.test(1), {
4444
assert.throws(() => pattern.test('', 1), {
4545
code: 'ERR_INVALID_ARG_TYPE',
4646
});
47+
48+
// Per WebIDL, undefined for optional arguments with defaults should use the
49+
// default value (empty URLPatternInit {}) rather than throwing.
50+
51+
// Constructor: undefined input should be treated as empty init.
52+
{
53+
const p = new URLPattern(undefined);
54+
assert.strictEqual(p.protocol, '*');
55+
assert.strictEqual(p.hostname, '*');
56+
}
57+
58+
// Constructor: undefined input with undefined baseURL.
59+
{
60+
const p = new URLPattern(undefined, undefined);
61+
assert.strictEqual(p.protocol, '*');
62+
assert.strictEqual(p.pathname, '*');
63+
}
64+
65+
// Constructor: valid input with undefined options.
66+
{
67+
const p = new URLPattern({ pathname: '/foo' }, undefined);
68+
assert.strictEqual(p.pathname, '/foo');
69+
}
70+
71+
// Constructor: string input, undefined baseURL, undefined options.
72+
{
73+
const p = new URLPattern('https://example.com/foo', undefined, undefined);
74+
assert.strictEqual(p.hostname, 'example.com');
75+
assert.strictEqual(p.pathname, '/foo');
76+
}
77+
78+
// exec() and test(): undefined input should be treated as empty init.
79+
{
80+
const p = new URLPattern();
81+
assert.strictEqual(p.test(undefined), true);
82+
assert.strictEqual(p.test(undefined, undefined), true);
83+
assert.notStrictEqual(p.exec(undefined), null);
84+
assert.notStrictEqual(p.exec(undefined, undefined), null);
85+
}
86+
87+
// exec() and test(): valid input with undefined baseURL.
88+
{
89+
const p = new URLPattern({ protocol: 'https' });
90+
assert.strictEqual(p.test('https://example.com', undefined), true);
91+
assert.notStrictEqual(p.exec('https://example.com', undefined), null);
92+
}

0 commit comments

Comments
 (0)