Compare commits

...

2 Commits

Author SHA1 Message Date
Jarred Sumner
aec4f27aea Merge branch 'main' into fix-node-url-pt1 2025-03-18 22:26:38 -07:00
Ashcon Partovi
9c873cb14a Fix node:url test 2025-03-18 15:48:11 -07:00
4 changed files with 814 additions and 509 deletions

View File

@@ -68,6 +68,7 @@ static JSC_DECLARE_HOST_FUNCTION(jsDOMURLPrototypeFunction_toJSON);
static JSC_DECLARE_HOST_FUNCTION(jsDOMURLConstructorFunction_createObjectURL);
static JSC_DECLARE_HOST_FUNCTION(jsDOMURLConstructorFunction_revokeObjectURL);
static JSC_DECLARE_HOST_FUNCTION(jsDOMURLPrototypeFunction_toString);
static JSC_DECLARE_HOST_FUNCTION(jsDOMURLPrototypeFunction_inspectCustom);
BUN_DECLARE_HOST_FUNCTION(Bun__createObjectURL);
BUN_DECLARE_HOST_FUNCTION(Bun__revokeObjectURL);
@@ -234,6 +235,13 @@ void JSDOMURLPrototype::finishCreation(VM& vm)
Base::finishCreation(vm);
reifyStaticProperties(vm, JSDOMURL::info(), JSDOMURLPrototypeTableValues, *this);
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
auto& builtinNames = WebCore::builtinNames(vm);
const auto& inspectCustomPublicName = builtinNames.inspectCustomPublicName();
auto* fn = JSC::JSFunction::create(vm, globalObject(), 0, "[nodejs.util.inspect.custom]"_s, jsDOMURLPrototypeFunction_inspectCustom, JSC::ImplementationVisibility::Public, JSC::NoIntrinsic);
this->putDirect(vm, inspectCustomPublicName, fn, JSC::PropertyAttribute::DontEnum | 0);
}
const ClassInfo JSDOMURL::s_info = { "URL"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSDOMURL) };
@@ -772,6 +780,21 @@ JSC_DEFINE_HOST_FUNCTION(jsDOMURLPrototypeFunction_toString, (JSGlobalObject * l
return IDLOperation<JSDOMURL>::call<jsDOMURLPrototypeFunction_toStringBody>(*lexicalGlobalObject, *callFrame, "toString");
}
static inline JSC::EncodedJSValue jsDOMURLPrototypeFunction_inspectCustomBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSDOMURL>::ClassParameter castedThis)
{
auto& vm = JSC::getVM(lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
UNUSED_PARAM(throwScope);
UNUSED_PARAM(callFrame);
auto& impl = castedThis->wrapped();
RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUSVString>(*lexicalGlobalObject, throwScope, impl.href())));
}
JSC_DEFINE_HOST_FUNCTION(jsDOMURLPrototypeFunction_inspectCustom, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
{
return IDLOperation<JSDOMURL>::call<jsDOMURLPrototypeFunction_inspectCustomBody>(*lexicalGlobalObject, *callFrame, "[nodejs.util.inspect.custom]");
}
JSC::GCClient::IsoSubspace* JSDOMURL::subspaceForImpl(JSC::VM& vm)
{
return WebCore::subspaceForImpl<JSDOMURL, UseCustomHeapCellType::No>(

View File

@@ -194,6 +194,13 @@ void JSURLSearchParamsPrototype::finishCreation(VM& vm)
reifyStaticProperties(vm, JSURLSearchParams::info(), JSURLSearchParamsPrototypeTableValues, *this);
putDirect(vm, vm.propertyNames->iteratorSymbol, getDirect(vm, vm.propertyNames->builtinNames().entriesPublicName()), static_cast<unsigned>(JSC::PropertyAttribute::DontEnum));
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
auto& builtinNames = WebCore::builtinNames(vm);
const auto& inspectCustomPublicName = builtinNames.inspectCustomPublicName();
auto* fn = JSC::JSFunction::create(vm, globalObject(), 0, "[nodejs.util.inspect.custom]"_s, jsURLSearchParamsPrototypeFunction_toString, JSC::ImplementationVisibility::Public, JSC::NoIntrinsic);
this->putDirect(vm, inspectCustomPublicName, fn, JSC::PropertyAttribute::DontEnum | 0);
}
const ClassInfo JSURLSearchParams::s_info = { "URLSearchParams"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSURLSearchParams) };

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,143 @@
'use strict';
require('../common');
const assert = require('assert');
const { URL, URLSearchParams, format } = require('url');
[
{ name: 'toString' },
{ name: 'toJSON' },
{ name: Symbol.for('nodejs.util.inspect.custom') },
].forEach(({ name }) => {
testMethod(URL.prototype, name);
});
[
'http://www.google.com',
'https://www.domain.com:443',
'file:///Users/yagiz/Developer/node',
].forEach((url) => {
const u = new URL(url);
assert.strictEqual(JSON.stringify(u), `"${u.href}"`);
assert.strictEqual(u.toString(), u.href);
assert.strictEqual(format(u), u.href);
});
[
{ name: 'href' },
{ name: 'protocol' },
{ name: 'username' },
{ name: 'password' },
{ name: 'host' },
{ name: 'hostname' },
{ name: 'port' },
{ name: 'pathname' },
{ name: 'search' },
{ name: 'hash' },
{ name: 'origin', readonly: true },
{ name: 'searchParams', readonly: true },
].forEach(({ name, readonly = false }) => {
testAccessor(URL.prototype, name, readonly);
});
[
{ name: 'createObjectURL' },
{ name: 'revokeObjectURL' },
].forEach(({ name }) => {
testStaticAccessor(URL, name);
});
[
{ name: 'append' },
{ name: 'delete' },
{ name: 'get' },
{ name: 'getAll' },
{ name: 'has' },
{ name: 'set' },
{ name: 'sort' },
{ name: 'entries' },
{ name: 'forEach' },
{ name: 'keys' },
{ name: 'values' },
{ name: 'toString' },
{ name: Symbol.iterator, methodName: 'entries' },
{ name: Symbol.for('nodejs.util.inspect.custom') },
].forEach(({ name, methodName }) => {
testMethod(URLSearchParams.prototype, name, methodName);
});
{
const params = new URLSearchParams();
params.append('a', 'b');
params.append('a', 'c');
params.append('b', 'c');
assert.strictEqual(params.size, 3);
}
{
const u = new URL('https://abc.com/?q=old');
const s = u.searchParams;
u.href = 'http://abc.com/?q=new';
assert.strictEqual(s.get('q'), 'new');
}
function stringifyName(name) {
if (typeof name === 'symbol') {
const { description } = name;
if (description === undefined) {
return '';
}
return `[${description}]`;
}
return name;
}
function testMethod(target, name, methodName = stringifyName(name)) {
const desc = Object.getOwnPropertyDescriptor(target, name);
console.log(name, methodName);
assert.notStrictEqual(desc, undefined);
assert.strictEqual(desc.enumerable, typeof name === 'string');
const { value } = desc;
assert.strictEqual(typeof value, 'function');
assert.strictEqual(value.name, methodName);
assert.strictEqual(
Object.hasOwn(value, 'prototype'),
false,
);
}
function testAccessor(target, name, readonly = false) {
const desc = Object.getOwnPropertyDescriptor(target, name);
assert.notStrictEqual(desc, undefined);
assert.strictEqual(desc.enumerable, typeof name === 'string');
const methodName = stringifyName(name);
const { get, set } = desc;
assert.strictEqual(typeof get, 'function');
assert.strictEqual(get.name, `get ${methodName}`);
assert.strictEqual(
Object.hasOwn(get, 'prototype'),
false,
);
if (readonly) {
assert.strictEqual(set, undefined);
} else {
assert.strictEqual(typeof set, 'function');
assert.strictEqual(set.name, `set ${methodName}`);
assert.strictEqual(
Object.hasOwn(set, 'prototype'),
false,
);
}
}
function testStaticAccessor(target, name) {
const desc = Object.getOwnPropertyDescriptor(target, name);
assert.notStrictEqual(desc, undefined);
assert.strictEqual(desc.configurable, true);
assert.strictEqual(desc.enumerable, true);
assert.strictEqual(desc.writable, true);
}