• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2const { isWindows } = require('../common');
3const assert = require('assert');
4const url = require('url');
5
6{
7  const fileURL = url.pathToFileURL('test/').href;
8  assert.ok(fileURL.startsWith('file:///'));
9  assert.ok(fileURL.endsWith('/'));
10}
11
12{
13  const fileURL = url.pathToFileURL('test\\').href;
14  assert.ok(fileURL.startsWith('file:///'));
15  if (isWindows)
16    assert.ok(fileURL.endsWith('/'));
17  else
18    assert.ok(fileURL.endsWith('%5C'));
19}
20
21{
22  const fileURL = url.pathToFileURL('test/%').href;
23  assert.ok(fileURL.includes('%25'));
24}
25
26{
27  if (isWindows) {
28    // UNC path: \\server\share\resource
29
30    // Missing server:
31    assert.throws(() => url.pathToFileURL('\\\\\\no-server'), {
32      code: 'ERR_INVALID_ARG_VALUE'
33    });
34
35    // Missing share or resource:
36    assert.throws(() => url.pathToFileURL('\\\\host'), {
37      code: 'ERR_INVALID_ARG_VALUE'
38    });
39  } else {
40    // UNC paths on posix are considered a single path that has backslashes:
41    const fileURL = url.pathToFileURL('\\\\nas\\share\\path.txt').href;
42    assert.match(fileURL, /file:\/\/.+%5C%5Cnas%5Cshare%5Cpath\.txt$/);
43  }
44}
45
46{
47  let testCases;
48  if (isWindows) {
49    testCases = [
50      // Lowercase ascii alpha
51      { path: 'C:\\foo', expected: 'file:///C:/foo' },
52      // Uppercase ascii alpha
53      { path: 'C:\\FOO', expected: 'file:///C:/FOO' },
54      // dir
55      { path: 'C:\\dir\\foo', expected: 'file:///C:/dir/foo' },
56      // trailing separator
57      { path: 'C:\\dir\\', expected: 'file:///C:/dir/' },
58      // dot
59      { path: 'C:\\foo.mjs', expected: 'file:///C:/foo.mjs' },
60      // space
61      { path: 'C:\\foo bar', expected: 'file:///C:/foo%20bar' },
62      // question mark
63      { path: 'C:\\foo?bar', expected: 'file:///C:/foo%3Fbar' },
64      // number sign
65      { path: 'C:\\foo#bar', expected: 'file:///C:/foo%23bar' },
66      // ampersand
67      { path: 'C:\\foo&bar', expected: 'file:///C:/foo&bar' },
68      // equals
69      { path: 'C:\\foo=bar', expected: 'file:///C:/foo=bar' },
70      // colon
71      { path: 'C:\\foo:bar', expected: 'file:///C:/foo:bar' },
72      // semicolon
73      { path: 'C:\\foo;bar', expected: 'file:///C:/foo;bar' },
74      // percent
75      { path: 'C:\\foo%bar', expected: 'file:///C:/foo%25bar' },
76      // backslash
77      { path: 'C:\\foo\\bar', expected: 'file:///C:/foo/bar' },
78      // backspace
79      { path: 'C:\\foo\bbar', expected: 'file:///C:/foo%08bar' },
80      // tab
81      { path: 'C:\\foo\tbar', expected: 'file:///C:/foo%09bar' },
82      // newline
83      { path: 'C:\\foo\nbar', expected: 'file:///C:/foo%0Abar' },
84      // carriage return
85      { path: 'C:\\foo\rbar', expected: 'file:///C:/foo%0Dbar' },
86      // latin1
87      { path: 'C:\\fóóbàr', expected: 'file:///C:/f%C3%B3%C3%B3b%C3%A0r' },
88      // Euro sign (BMP code point)
89      { path: 'C:\\€', expected: 'file:///C:/%E2%82%AC' },
90      // Rocket emoji (non-BMP code point)
91      { path: 'C:\\��', expected: 'file:///C:/%F0%9F%9A%80' },
92      // UNC path (see https://docs.microsoft.com/en-us/archive/blogs/ie/file-uris-in-windows)
93      { path: '\\\\nas\\My Docs\\File.doc', expected: 'file://nas/My%20Docs/File.doc' }
94    ];
95  } else {
96    testCases = [
97      // Lowercase ascii alpha
98      { path: '/foo', expected: 'file:///foo' },
99      // Uppercase ascii alpha
100      { path: '/FOO', expected: 'file:///FOO' },
101      // dir
102      { path: '/dir/foo', expected: 'file:///dir/foo' },
103      // trailing separator
104      { path: '/dir/', expected: 'file:///dir/' },
105      // dot
106      { path: '/foo.mjs', expected: 'file:///foo.mjs' },
107      // space
108      { path: '/foo bar', expected: 'file:///foo%20bar' },
109      // question mark
110      { path: '/foo?bar', expected: 'file:///foo%3Fbar' },
111      // number sign
112      { path: '/foo#bar', expected: 'file:///foo%23bar' },
113      // ampersand
114      { path: '/foo&bar', expected: 'file:///foo&bar' },
115      // equals
116      { path: '/foo=bar', expected: 'file:///foo=bar' },
117      // colon
118      { path: '/foo:bar', expected: 'file:///foo:bar' },
119      // semicolon
120      { path: '/foo;bar', expected: 'file:///foo;bar' },
121      // percent
122      { path: '/foo%bar', expected: 'file:///foo%25bar' },
123      // backslash
124      { path: '/foo\\bar', expected: 'file:///foo%5Cbar' },
125      // backspace
126      { path: '/foo\bbar', expected: 'file:///foo%08bar' },
127      // tab
128      { path: '/foo\tbar', expected: 'file:///foo%09bar' },
129      // newline
130      { path: '/foo\nbar', expected: 'file:///foo%0Abar' },
131      // carriage return
132      { path: '/foo\rbar', expected: 'file:///foo%0Dbar' },
133      // latin1
134      { path: '/fóóbàr', expected: 'file:///f%C3%B3%C3%B3b%C3%A0r' },
135      // Euro sign (BMP code point)
136      { path: '/€', expected: 'file:///%E2%82%AC' },
137      // Rocket emoji (non-BMP code point)
138      { path: '/��', expected: 'file:///%F0%9F%9A%80' },
139    ];
140  }
141
142  for (const { path, expected } of testCases) {
143    const actual = url.pathToFileURL(path).href;
144    assert.strictEqual(actual, expected);
145  }
146}
147