mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 18:38:55 +00:00
203 lines
6.8 KiB
JavaScript
203 lines
6.8 KiB
JavaScript
import { describe, test } from "bun:test";
|
|
import { isWindows } from "harness";
|
|
import assert from "node:assert";
|
|
import url from "node:url";
|
|
|
|
describe("url.pathToFileURL", () => {
|
|
// TODO: Fix these asserts on Windows.
|
|
test.skipIf(isWindows)("dangling slashes and percent sign", () => {
|
|
{
|
|
const fileURL = url.pathToFileURL("test/").href;
|
|
assert.ok(fileURL.startsWith("file:///"));
|
|
assert.ok(fileURL.endsWith("/"));
|
|
}
|
|
|
|
// TODO: Support these.
|
|
//
|
|
// {
|
|
// const fileURL = url.pathToFileURL("test\\").href;
|
|
// assert.ok(fileURL.startsWith("file:///"));
|
|
// if (isWindows) assert.ok(fileURL.endsWith("/"));
|
|
// else assert.ok(fileURL.endsWith("%5C"));
|
|
// }
|
|
|
|
// {
|
|
// const fileURL = url.pathToFileURL("test/%").href;
|
|
// assert.ok(fileURL.includes("%25"));
|
|
// }
|
|
});
|
|
|
|
// TODO: Support UNC paths across platforms.
|
|
test.todo("UNC paths", () => {
|
|
if (isWindows) {
|
|
// UNC path: \\server\share\resource
|
|
|
|
// Missing server:
|
|
assert.throws(() => url.pathToFileURL("\\\\\\no-server"), {
|
|
code: "ERR_INVALID_ARG_VALUE",
|
|
});
|
|
|
|
// Missing share or resource:
|
|
assert.throws(() => url.pathToFileURL("\\\\host"), {
|
|
code: "ERR_INVALID_ARG_VALUE",
|
|
});
|
|
|
|
// Regression test for direct String.prototype.startsWith call
|
|
assert.throws(() => url.pathToFileURL(["\\\\", { [Symbol.toPrimitive]: () => "blep\\blop" }]), {
|
|
code: "ERR_INVALID_ARG_TYPE",
|
|
});
|
|
assert.throws(() => url.pathToFileURL(["\\\\", "blep\\blop"]), {
|
|
code: "ERR_INVALID_ARG_TYPE",
|
|
});
|
|
assert.throws(
|
|
() =>
|
|
url.pathToFileURL({
|
|
[Symbol.toPrimitive]: () => "\\\\blep\\blop",
|
|
}),
|
|
{
|
|
code: "ERR_INVALID_ARG_TYPE",
|
|
},
|
|
);
|
|
} else {
|
|
// UNC paths on posix are considered a single path that has backslashes:
|
|
const fileURL = url.pathToFileURL("\\\\nas\\share\\path.txt").href;
|
|
assert.match(fileURL, /file:\/\/.+%5C%5Cnas%5Cshare%5Cpath\.txt$/);
|
|
}
|
|
});
|
|
|
|
test("general", () => {
|
|
let testCases;
|
|
if (isWindows) {
|
|
testCases = [
|
|
// Lowercase ascii alpha
|
|
{ path: "C:\\foo", expected: "file:///C:/foo" },
|
|
// Uppercase ascii alpha
|
|
{ path: "C:\\FOO", expected: "file:///C:/FOO" },
|
|
// dir
|
|
{ path: "C:\\dir\\foo", expected: "file:///C:/dir/foo" },
|
|
// trailing separator
|
|
{ path: "C:\\dir\\", expected: "file:///C:/dir/" },
|
|
// dot
|
|
{ path: "C:\\foo.mjs", expected: "file:///C:/foo.mjs" },
|
|
// space
|
|
{ path: "C:\\foo bar", expected: "file:///C:/foo%20bar" },
|
|
// question mark
|
|
{ path: "C:\\foo?bar", expected: "file:///C:/foo%3Fbar" },
|
|
// number sign
|
|
{ path: "C:\\foo#bar", expected: "file:///C:/foo%23bar" },
|
|
// ampersand
|
|
{ path: "C:\\foo&bar", expected: "file:///C:/foo&bar" },
|
|
// equals
|
|
{ path: "C:\\foo=bar", expected: "file:///C:/foo=bar" },
|
|
// colon
|
|
{ path: "C:\\foo:bar", expected: "file:///C:/foo:bar" },
|
|
// semicolon
|
|
{ path: "C:\\foo;bar", expected: "file:///C:/foo;bar" },
|
|
// TODO: Support these.
|
|
//
|
|
// percent
|
|
// { path: "C:\\foo%bar", expected: "file:///C:/foo%25bar" },
|
|
// backslash
|
|
// { path: "C:\\foo\\bar", expected: "file:///C:/foo/bar" },
|
|
// backspace
|
|
// { path: "C:\\foo\bbar", expected: "file:///C:/foo%08bar" },
|
|
// tab
|
|
// { path: "C:\\foo\tbar", expected: "file:///C:/foo%09bar" },
|
|
// newline
|
|
// { path: "C:\\foo\nbar", expected: "file:///C:/foo%0Abar" },
|
|
// carriage return
|
|
// { path: "C:\\foo\rbar", expected: "file:///C:/foo%0Dbar" },
|
|
// latin1
|
|
{ path: "C:\\fóóbàr", expected: "file:///C:/f%C3%B3%C3%B3b%C3%A0r" },
|
|
// Euro sign (BMP code point)
|
|
{ path: "C:\\€", expected: "file:///C:/%E2%82%AC" },
|
|
// Rocket emoji (non-BMP code point)
|
|
{ path: "C:\\🚀", expected: "file:///C:/%F0%9F%9A%80" },
|
|
// UNC path (see https://docs.microsoft.com/en-us/archive/blogs/ie/file-uris-in-windows)
|
|
{ path: "\\\\nas\\My Docs\\File.doc", expected: "file://nas/My%20Docs/File.doc" },
|
|
];
|
|
} else {
|
|
testCases = [
|
|
// Lowercase ascii alpha
|
|
{ path: "/foo", expected: "file:///foo" },
|
|
// Uppercase ascii alpha
|
|
{ path: "/FOO", expected: "file:///FOO" },
|
|
// dir
|
|
{ path: "/dir/foo", expected: "file:///dir/foo" },
|
|
// trailing separator
|
|
{ path: "/dir/", expected: "file:///dir/" },
|
|
// dot
|
|
{ path: "/foo.mjs", expected: "file:///foo.mjs" },
|
|
// space
|
|
{ path: "/foo bar", expected: "file:///foo%20bar" },
|
|
// question mark
|
|
{ path: "/foo?bar", expected: "file:///foo%3Fbar" },
|
|
// number sign
|
|
{ path: "/foo#bar", expected: "file:///foo%23bar" },
|
|
// ampersand
|
|
{ path: "/foo&bar", expected: "file:///foo&bar" },
|
|
// equals
|
|
{ path: "/foo=bar", expected: "file:///foo=bar" },
|
|
// colon
|
|
{ path: "/foo:bar", expected: "file:///foo:bar" },
|
|
// semicolon
|
|
{ path: "/foo;bar", expected: "file:///foo;bar" },
|
|
// TODO: Support these.
|
|
//
|
|
// percent
|
|
// { path: "/foo%bar", expected: "file:///foo%25bar" },
|
|
// backslash
|
|
// { path: "/foo\\bar", expected: "file:///foo%5Cbar" },
|
|
// backspace
|
|
//{ path: "/foo\bbar", expected: "file:///foo%08bar" },
|
|
// tab
|
|
// { path: "/foo\tbar", expected: "file:///foo%09bar" },
|
|
// newline
|
|
// { path: "/foo\nbar", expected: "file:///foo%0Abar" },
|
|
// carriage return
|
|
// { path: "/foo\rbar", expected: "file:///foo%0Dbar" },
|
|
// latin1
|
|
{ path: "/fóóbàr", expected: "file:///f%C3%B3%C3%B3b%C3%A0r" },
|
|
// Euro sign (BMP code point)
|
|
{ path: "/€", expected: "file:///%E2%82%AC" },
|
|
// Rocket emoji (non-BMP code point)
|
|
{ path: "/🚀", expected: "file:///%F0%9F%9A%80" },
|
|
];
|
|
}
|
|
|
|
for (const { path, expected } of testCases) {
|
|
const actual = url.pathToFileURL(path).href;
|
|
assert.strictEqual(actual, expected);
|
|
}
|
|
});
|
|
|
|
// TODO: Support throwing correct exception for non-string params.
|
|
test.todo("non-string parameter", () => {
|
|
for (const badPath of [
|
|
undefined,
|
|
null,
|
|
true,
|
|
42,
|
|
42n,
|
|
Symbol("42"),
|
|
NaN,
|
|
{},
|
|
[],
|
|
() => {},
|
|
Promise.resolve("foo"),
|
|
new Date(),
|
|
new String("notPrimitive"),
|
|
{
|
|
toString() {
|
|
return "amObject";
|
|
},
|
|
},
|
|
{ [Symbol.toPrimitive]: hint => "amObject" },
|
|
]) {
|
|
assert.throws(() => url.pathToFileURL(badPath), {
|
|
code: "ERR_INVALID_ARG_TYPE",
|
|
});
|
|
}
|
|
});
|
|
});
|