From 3ad3c889ab4a6394d7fb7e8e3b5fd928839f0c33 Mon Sep 17 00:00:00 2001 From: Ardis Lu Date: Sun, 12 Jan 2025 20:09:40 -0800 Subject: [PATCH] Simplify and add test cases for parsePathLike fileURLToPath already throws on unsupported URLs, no need to re-throw. --- src/core.js | 10 ++-------- test/core.test.js | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/core.js b/src/core.js index aa38823..6cd25b5 100644 --- a/src/core.js +++ b/src/core.js @@ -30,8 +30,7 @@ export function arrayToCSVString(arr) { * * @param {PathLike} path A `string`, `Buffer`, or `URL` representing a path to a local file. * @returns {string} The normalized file path in string form. - * @throws {TypeError} If `path` is not a `string`, `Buffer`, or `URL`. - * @throws {URIError} If `path` is a URL but it cannot be parsed. + * @throws {TypeError} If `path` is not a `string`, `Buffer`, or `URL`, or it is a `URL` that is not using the `file` schema. */ export function parsePathLike(path) { let parsedPath; @@ -42,12 +41,7 @@ export function parsePathLike(path) { parsedPath = normalize(new TextDecoder().decode(path)); } else if (path instanceof URL) { - if (URL.canParse(path)) { - parsedPath = fileURLToPath(path); - } - else { - throw new URIError('URL could not be parsed.'); - } + parsedPath = fileURLToPath(path); } else { throw new TypeError(`Expected a string, Buffer, or URL, but received ${typeof path}.`); diff --git a/test/core.test.js b/test/core.test.js index 436e5e1..98256e5 100644 --- a/test/core.test.js +++ b/test/core.test.js @@ -1,9 +1,11 @@ import { suite, test } from 'node:test'; -import { deepStrictEqual } from 'node:assert/strict'; +import { deepStrictEqual, throws } from 'node:assert/strict'; import { unlink } from 'node:fs/promises'; +import { normalize, resolve } from 'node:path'; +import { pathToFileURL } from 'node:url'; import { csvStreamEqualWritable, csvStreamNotEqualWritable, createCSVMockStream, createTempFile } from './utils.js'; -import { arrayToCSVString, createCSVReadableStream, createCSVTransformStream, createCSVWritableStream } from '../src/core.js'; +import { arrayToCSVString, parsePathLike, createCSVReadableStream, createCSVTransformStream, createCSVWritableStream } from '../src/core.js'; suite('arrayToCSVString', { concurrency: true }, () => { const vectors = [ @@ -23,6 +25,33 @@ suite('arrayToCSVString', { concurrency: true }, () => { } }); +suite('parsePathLike', { concurrency: true }, () => { + const vectors = [ + { name: 'parses string relative path', input: './folder/example.txt', output: './folder/example.txt' }, + { name: 'parses string absolute path', input: '/absolute/path/to/file.txt', output: '/absolute/path/to/file.txt' }, + { name: 'parses Buffer relative path', input: new TextEncoder().encode('./folder/example.txt'), output: './folder/example.txt' }, + { name: 'parses Buffer absolute path', input: new TextEncoder().encode('/absolute/path/to/file.txt'), output: '/absolute/path/to/file.txt' }, + { name: 'parses URL relative path', input: pathToFileURL('./folder/example.txt'), output: resolve('./folder/example.txt') }, // Must use resolve because URLs automatically resolve to absolute path + { name: 'parses URL absolute path', input: pathToFileURL('/absolute/path/to/file.txt'), output: resolve('/absolute/path/to/file.txt') }, + { name: 'parses URL with percent-encoding', input: pathToFileURL('./folder/example%20chars.txt'), output: resolve('./folder/example%20chars.txt') }, + { name: 'parses empty string', input: '', output: '' }, + { name: 'throws TypeError for unsupported type (number)', input: 12345, error: TypeError }, + { name: 'throws TypeError for unsupported type (object)', input: { path: './example.txt' }, error: TypeError }, + { name: 'throws TypeError for unsupported type (null)', input: null, error: TypeError }, + { name: 'throws TypeError for unsupported URL schema', input: new URL('http://example.com/example.txt'), error: TypeError }, + ]; + for (const { name, input, output, error } of vectors) { + test(name, { concurrency: true }, () => { + if (error !== undefined) { + throws(() => parsePathLike(input), error); + } + else { + deepStrictEqual(parsePathLike(input), normalize(output)); + } + }); + } +}); + suite('createCSVReadableStream', { concurrency: true }, () => { const vectors = [ { -- 2.47.3