Files
bun.sh/test/js/node/url/url-format.test.js
2024-02-16 11:32:08 -08:00

282 lines
8.4 KiB
JavaScript

import { describe, test } from "bun:test";
import assert from "node:assert";
import url from "node:url";
describe("url.format", () => {
test("slightly wonky content", () => {
// Formatting tests to verify that it'll format slightly wonky content to a
// valid URL.
const formatTests = {
"http://example.com?": {
href: "http://example.com/?",
protocol: "http:",
slashes: true,
host: "example.com",
hostname: "example.com",
search: "?",
query: {},
pathname: "/",
},
"http://example.com?foo=bar#frag": {
href: "http://example.com/?foo=bar#frag",
protocol: "http:",
host: "example.com",
hostname: "example.com",
hash: "#frag",
search: "?foo=bar",
query: "foo=bar",
pathname: "/",
},
"http://example.com?foo=@bar#frag": {
href: "http://example.com/?foo=@bar#frag",
protocol: "http:",
host: "example.com",
hostname: "example.com",
hash: "#frag",
search: "?foo=@bar",
query: "foo=@bar",
pathname: "/",
},
"http://example.com?foo=/bar/#frag": {
href: "http://example.com/?foo=/bar/#frag",
protocol: "http:",
host: "example.com",
hostname: "example.com",
hash: "#frag",
search: "?foo=/bar/",
query: "foo=/bar/",
pathname: "/",
},
"http://example.com?foo=?bar/#frag": {
href: "http://example.com/?foo=?bar/#frag",
protocol: "http:",
host: "example.com",
hostname: "example.com",
hash: "#frag",
search: "?foo=?bar/",
query: "foo=?bar/",
pathname: "/",
},
"http://example.com#frag=?bar/#frag": {
href: "http://example.com/#frag=?bar/#frag",
protocol: "http:",
host: "example.com",
hostname: "example.com",
hash: "#frag=?bar/#frag",
pathname: "/",
},
'http://google.com" onload="alert(42)/': {
href: "http://google.com/%22%20onload=%22alert(42)/",
protocol: "http:",
host: "google.com",
pathname: "/%22%20onload=%22alert(42)/",
},
"http://a.com/a/b/c?s#h": {
href: "http://a.com/a/b/c?s#h",
protocol: "http",
host: "a.com",
pathname: "a/b/c",
hash: "h",
search: "s",
},
"xmpp:isaacschlueter@jabber.org": {
href: "xmpp:isaacschlueter@jabber.org",
protocol: "xmpp:",
host: "jabber.org",
auth: "isaacschlueter",
hostname: "jabber.org",
},
"http://atpass:foo%40bar@127.0.0.1/": {
href: "http://atpass:foo%40bar@127.0.0.1/",
auth: "atpass:foo@bar",
hostname: "127.0.0.1",
protocol: "http:",
pathname: "/",
},
"http://atslash%2F%40:%2F%40@foo/": {
href: "http://atslash%2F%40:%2F%40@foo/",
auth: "atslash/@:/@",
hostname: "foo",
protocol: "http:",
pathname: "/",
},
"svn+ssh://foo/bar": {
href: "svn+ssh://foo/bar",
hostname: "foo",
protocol: "svn+ssh:",
pathname: "/bar",
slashes: true,
},
"dash-test://foo/bar": {
href: "dash-test://foo/bar",
hostname: "foo",
protocol: "dash-test:",
pathname: "/bar",
slashes: true,
},
"dash-test:foo/bar": {
href: "dash-test:foo/bar",
hostname: "foo",
protocol: "dash-test:",
pathname: "/bar",
},
"dot.test://foo/bar": {
href: "dot.test://foo/bar",
hostname: "foo",
protocol: "dot.test:",
pathname: "/bar",
slashes: true,
},
"dot.test:foo/bar": {
href: "dot.test:foo/bar",
hostname: "foo",
protocol: "dot.test:",
pathname: "/bar",
},
// IPv6 support
"coap:u:p@[::1]:61616/.well-known/r?n=Temperature": {
href: "coap:u:p@[::1]:61616/.well-known/r?n=Temperature",
protocol: "coap:",
auth: "u:p",
hostname: "::1",
port: "61616",
pathname: "/.well-known/r",
search: "n=Temperature",
},
"coap:[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:61616/s/stopButton": {
href: "coap:[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:61616/s/stopButton",
protocol: "coap",
host: "[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:61616",
pathname: "/s/stopButton",
},
// TODO: Support this.
//
// "http://[::]/": {
// href: "http://[::]/",
// protocol: "http:",
// hostname: "[::]",
// pathname: "/",
// },
// Encode context-specific delimiters in path and query, but do not touch
// other non-delimiter chars like `%`.
// <https://github.com/nodejs/node-v0.x-archive/issues/4082>
// `#`,`?` in path
"/path/to/%%23%3F+=&.txt?foo=theA1#bar": {
href: "/path/to/%%23%3F+=&.txt?foo=theA1#bar",
pathname: "/path/to/%#?+=&.txt",
query: {
foo: "theA1",
},
hash: "#bar",
},
// `#`,`?` in path + `#` in query
"/path/to/%%23%3F+=&.txt?foo=the%231#bar": {
href: "/path/to/%%23%3F+=&.txt?foo=the%231#bar",
pathname: "/path/to/%#?+=&.txt",
query: {
foo: "the#1",
},
hash: "#bar",
},
// `#` in path end + `#` in query
"/path/to/%%23?foo=the%231#bar": {
href: "/path/to/%%23?foo=the%231#bar",
pathname: "/path/to/%#",
query: {
foo: "the#1",
},
hash: "#bar",
},
// `?` and `#` in path and search
"http://ex.com/foo%3F100%m%23r?abc=the%231?&foo=bar#frag": {
href: "http://ex.com/foo%3F100%m%23r?abc=the%231?&foo=bar#frag",
protocol: "http:",
hostname: "ex.com",
hash: "#frag",
search: "?abc=the#1?&foo=bar",
pathname: "/foo?100%m#r",
},
// `?` and `#` in search only
"http://ex.com/fooA100%mBr?abc=the%231?&foo=bar#frag": {
href: "http://ex.com/fooA100%mBr?abc=the%231?&foo=bar#frag",
protocol: "http:",
hostname: "ex.com",
hash: "#frag",
search: "?abc=the#1?&foo=bar",
pathname: "/fooA100%mBr",
},
// TODO: Support these.
//
// // Multiple `#` in search
// "http://example.com/?foo=bar%231%232%233&abc=%234%23%235#frag": {
// href: "http://example.com/?foo=bar%231%232%233&abc=%234%23%235#frag",
// protocol: "http:",
// slashes: true,
// host: "example.com",
// hostname: "example.com",
// hash: "#frag",
// search: "?foo=bar#1#2#3&abc=#4##5",
// query: {},
// pathname: "/",
// },
// More than 255 characters in hostname which exceeds the limit
// [`http://${"a".repeat(255)}.com/node`]: {
// href: "http:///node",
// protocol: "http:",
// slashes: true,
// host: "",
// hostname: "",
// pathname: "/node",
// path: "/node",
// },
// Greater than or equal to 63 characters after `.` in hostname
// [`http://www.${"z".repeat(63)}example.com/node`]: {
// href: `http://www.${"z".repeat(63)}example.com/node`,
// protocol: "http:",
// slashes: true,
// host: `www.${"z".repeat(63)}example.com`,
// hostname: `www.${"z".repeat(63)}example.com`,
// pathname: "/node",
// path: "/node",
// },
// https://github.com/nodejs/node/issues/3361
// "file:///home/user": {
// href: "file:///home/user",
// protocol: "file",
// pathname: "/home/user",
// path: "/home/user",
// },
// surrogate in auth
"http://%F0%9F%98%80@www.example.com/": {
href: "http://%F0%9F%98%80@www.example.com/",
protocol: "http:",
auth: "\uD83D\uDE00",
hostname: "www.example.com",
pathname: "/",
},
};
for (const u in formatTests) {
const expect = formatTests[u].href;
delete formatTests[u].href;
const actual = url.format(u);
const actualObj = url.format(formatTests[u]);
assert.strictEqual(actual, expect, `wonky format(${u}) == ${expect}\nactual:${actual}`);
assert.strictEqual(
actualObj,
expect,
`wonky format(${JSON.stringify(formatTests[u])}) == ${expect}\nactual: ${actualObj}`,
);
}
});
});