From 8d484e80a057aca3358988daa54c9be2618e4569 Mon Sep 17 00:00:00 2001 From: Titus Wormer Date: Tue, 13 Jun 2023 16:40:01 +0200 Subject: [PATCH] Refactor code-style --- lib/index.js | 56 ++++++++++++-------- package.json | 2 +- test.js | 142 ++++++++++++++++++++++++++------------------------- 3 files changed, 109 insertions(+), 91 deletions(-) diff --git a/lib/index.js b/lib/index.js index c79f267..554aeab 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,11 +1,13 @@ /** - * @typedef {import('vfile').VFileValue} Value - * @typedef {import('vfile').VFileOptions} Options * @typedef {import('vfile').BufferEncoding} BufferEncoding * Encodings supported by the buffer class. * * This is a copy of the types from Node and `VFile`. - * + * @typedef {import('vfile').VFileOptions} Options + * @typedef {import('vfile').VFileValue} Value + */ + +/** * @typedef ReadOptions * Configuration for `fs.readFile`. * @property {BufferEncoding | null | undefined} [encoding] @@ -17,16 +19,16 @@ * Configuration for `fs.writeFile`. * @property {BufferEncoding | null | undefined} [encoding] * Encoding to write file as. - * @property {number | string | undefined} [mode] - * File mode (permission and sticky bits) if the file was newly created. * @property {string | undefined} [flag] * File system flags to use. + * @property {number | string | undefined} [mode] + * File mode (permission and sticky bits) if the file was newly created. * * @typedef {URL | Value} Path * URL to file or path to file. * * > 👉 **Note**: `Value` is used here because it’s a smarter `Buffer` - * @typedef {Path | Options | VFile} Compatible + * @typedef {Options | Path | VFile} Compatible * URL to file, path to file, options for file, or actual file. */ @@ -37,6 +39,20 @@ * Error when reading or writing was not successful. * @param {VFile | null | undefined} file * File when reading or writing was successful. + * + * @callback Resolve + * @param {VFile} result + * File. + * @returns {void} + * Nothing (note: has to be `void` for TS’s `Promise` interface). + * + * @callback Reject + * @param {NodeJS.ErrnoException} error + * Error. + * @param {VFile | undefined} [result] + * File. + * @returns {void} + * Nothing (note: has to be `void` for TS’s `Promise` interface). */ import fs from 'fs' @@ -70,10 +86,8 @@ export function toVFile(description) { description = {path: String(description)} } - return looksLikeAVFile(description) - ? description - : // To do: remove when `VFile` allows explicit `null`. - new VFile(description || undefined) + // To do: do not return given file. + return looksLikeAVFile(description) ? description : new VFile(description) } /** @@ -124,8 +138,8 @@ export function writeSync(description, options) { export const read = /** * @type {{ - * (description: Compatible, options: BufferEncoding | ReadOptions | null | undefined, callback: Callback): void - * (description: Compatible, callback: Callback): void + * (description: Compatible, options: BufferEncoding | ReadOptions | null | undefined, callback: Callback): undefined + * (description: Compatible, callback: Callback): undefined * (description: Compatible, options?: BufferEncoding | ReadOptions | null | undefined): Promise * }} */ @@ -158,8 +172,10 @@ export const read = } /** - * @param {(error: VFile) => void} resolve - * @param {(error: NodeJS.ErrnoException, file?: VFile | undefined) => void} reject + * @param {Resolve} resolve + * @param {Reject} reject + * @returns {void} + * Nothing (note: has to be `void` for TS’s `Promise` interface). */ function executor(resolve, reject) { /** @type {string} */ @@ -206,8 +222,8 @@ export const read = export const write = /** * @type {{ - * (description: Compatible, options: BufferEncoding | WriteOptions | null | undefined, callback: Callback): void - * (description: Compatible, callback: Callback): void + * (description: Compatible, options: BufferEncoding | WriteOptions | null | undefined, callback: Callback): undefined + * (description: Compatible, callback: Callback): undefined * (description: Compatible, options?: BufferEncoding | WriteOptions | null | undefined): Promise * }} */ @@ -241,8 +257,8 @@ export const write = } /** - * @param {(error: VFile) => void} resolve - * @param {(error: NodeJS.ErrnoException, file: VFile | null) => void} reject + * @param {Resolve} resolve + * @param {Reject} reject */ function executor(resolve, reject) { /** @type {string} */ @@ -252,7 +268,7 @@ export const write = fp = path.resolve(file.cwd, file.path) } catch (error) { const exception = /** @type {NodeJS.ErrnoException} */ (error) - return reject(exception, null) + return reject(exception) } fs.writeFile(fp, file.value || '', options || null, done) @@ -262,7 +278,7 @@ export const write = */ function done(error) { if (error) { - reject(error, null) + reject(error) } else { resolve(file) } diff --git a/package.json b/package.json index e0ea993..10e7c1b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "to-vfile", "version": "7.2.4", - "description": "vfile utility to create a vfile from a filepath", + "description": "vfile utility to read and write to the file system", "license": "MIT", "keywords": [ "vfile", diff --git a/test.js b/test.js index 23d8702..19f844a 100644 --- a/test.js +++ b/test.js @@ -7,15 +7,14 @@ import {fileURLToPath, URL} from 'node:url' import test from 'node:test' import buffer from 'is-buffer' import {toVFile, read, readSync, write, writeSync} from './index.js' -import * as mod from './index.js' const join = path.join const fixture = fs.readFileSync('readme.md', 'utf8') -test('toVFile', async (t) => { +test('toVFile', async function (t) { assert.deepEqual( - Object.keys(mod).sort(), + Object.keys(await import('./index.js')).sort(), ['read', 'readSync', 'toVFile', 'write', 'writeSync'], 'should expose the public api' ) @@ -26,7 +25,7 @@ test('toVFile', async (t) => { 'should expose the individual functions on `toVFile`' ) - await t.test('should accept a string as `.path`', () => { + await t.test('should accept a string as `.path`', function () { const file = toVFile(join('foo', 'bar', 'baz.qux')) assert.equal(file.path, join('foo', 'bar', 'baz.qux')) @@ -37,14 +36,14 @@ test('toVFile', async (t) => { assert.equal(file.value, undefined) }) - await t.test('should accept a buffer as `.path`', () => { + await t.test('should accept a buffer as `.path`', function () { const file = toVFile(Buffer.from('readme.md')) assert.equal(file.path, 'readme.md') assert.equal(file.value, undefined) }) - await t.test('should accept an object', () => { + await t.test('should accept an object', function () { const file = toVFile({ dirname: join('foo', 'bar'), stem: 'baz', @@ -59,14 +58,14 @@ test('toVFile', async (t) => { assert.equal(file.value, undefined) }) - await t.test('should accept a vfile', () => { + await t.test('should accept a vfile', function () { const first = toVFile() const second = toVFile(first) assert.equal(first, second) }) - await t.test('should accept a WHATWG URL object', () => { + await t.test('should accept a WHATWG URL object', function () { const dir = fileURLToPath(new URL('./', import.meta.url)) const file = toVFile(new URL('baz.qux', import.meta.url)) @@ -79,15 +78,15 @@ test('toVFile', async (t) => { }) }) -test('readSync', async (t) => { - await t.test('should fail without path', () => { - assert.throws(() => { +test('readSync', async function (t) { + await t.test('should fail without path', function () { + assert.throws(function () { // @ts-expect-error runtime. readSync() }, /path/i) }) - await t.test('should work (buffer without encoding)', () => { + await t.test('should work (buffer without encoding)', function () { const file = readSync('readme.md') assert.equal(file.path, 'readme.md') @@ -95,7 +94,7 @@ test('readSync', async (t) => { assert.equal(file.toString(), fixture) }) - await t.test('should work (string with encoding)', () => { + await t.test('should work (string with encoding)', function () { const file = readSync('readme.md', 'utf8') assert.equal(file.path, 'readme.md') @@ -104,14 +103,14 @@ test('readSync', async (t) => { }) assert.throws( - () => { + function () { readSync('missing.md') }, /ENOENT/, 'should throw on non-existing files' ) - await t.test('should honor file.cwd when file.path is relative', () => { + await t.test('should honor file.cwd when file.path is relative', function () { const cwd = path.join(process.cwd(), 'lib') const file = readSync({path: 'index.js', cwd}, 'utf8') @@ -120,7 +119,7 @@ test('readSync', async (t) => { await t.test( 'should honor file.cwd when file.path is relative, even with relative cwd', - () => { + function () { const file = readSync({path: 'index.js', cwd: 'lib'}, 'utf8') assert.equal(typeof file.value, 'string') @@ -128,7 +127,7 @@ test('readSync', async (t) => { ) assert.throws( - () => { + function () { readSync({ path: path.join(process.cwd(), 'core.js'), cwd: path.join(process.cwd(), 'lib') @@ -139,20 +138,20 @@ test('readSync', async (t) => { ) }) -test('read', async (t) => { - await t.test('should pass an error without path', async () => { - await new Promise((ok) => { +test('read', async function (t) { + await t.test('should pass an error without path', async function () { + await new Promise(function (ok) { // @ts-expect-error: not a path. - read(null, (error) => { + read(null, function (error) { assert.ok(/path/i.test(String(error))) ok(undefined) }) }) }) - await t.test('should work (buffer without encoding)', async () => { - await new Promise((ok) => { - read('readme.md', (error, file) => { + await t.test('should work (buffer without encoding)', async function () { + await new Promise(function (ok) { + read('readme.md', function (error, file) { assert.ifError(error) assert(file, 'expected file') assert.equal(file.path, 'readme.md') @@ -165,7 +164,7 @@ test('read', async (t) => { await t.test( 'should work in promise mode (buffer without encoding)', - async () => { + async function () { const result = await read('readme.md') assert.equal(result.path, 'readme.md') assert.ok(buffer(result.value)) @@ -173,9 +172,9 @@ test('read', async (t) => { } ) - await t.test('should work (string with encoding)', async () => { - await new Promise((ok) => { - read('readme.md', 'utf8', (error, file) => { + await t.test('should work (string with encoding)', async function () { + await new Promise(function (ok) { + read('readme.md', 'utf8', function (error, file) { assert.ifError(error) assert(file, 'expected file') assert.equal(file.path, 'readme.md') @@ -188,7 +187,7 @@ test('read', async (t) => { await t.test( 'should work in promise mode (string with encoding)', - async () => { + async function () { const result = await read('readme.md', 'utf8') assert.equal(result.path, 'readme.md') @@ -197,21 +196,24 @@ test('read', async (t) => { } ) - await t.test('should return an error on non-existing files', async () => { - await new Promise((ok) => { - read('missing.md', 'utf8', (error, file) => { - assert(error, 'expected error') - assert.equal(file, undefined) - assert.ok(error instanceof Error) - assert.ok(/ENOENT/.test(error.message)) - ok(undefined) + await t.test( + 'should return an error on non-existing files', + async function () { + await new Promise(function (ok) { + read('missing.md', 'utf8', function (error, file) { + assert(error, 'expected error') + assert.equal(file, undefined) + assert.ok(error instanceof Error) + assert.ok(/ENOENT/.test(error.message)) + ok(undefined) + }) }) - }) - }) + } + ) await t.test( 'should reject on non-existing files in promise mode', - async () => { + async function () { try { await read('missing.md') assert.fail('should reject, not resolve') @@ -223,18 +225,18 @@ test('read', async (t) => { ) }) -test('writeSync', async (t) => { +test('writeSync', async function (t) { const filePath = 'fixture.txt' const invalidFilePath = join('invalid', 'path', 'to', 'fixture.txt') - await t.test('should fail without path', () => { - assert.throws(() => { + await t.test('should fail without path', function () { + assert.throws(function () { // @ts-expect-error runtime. writeSync() }, /path/i) }) - await t.test('should work (buffer without encoding)', () => { + await t.test('should work (buffer without encoding)', function () { const result = writeSync({ path: filePath, value: Buffer.from('föo') @@ -245,7 +247,7 @@ test('writeSync', async (t) => { assert.equal(fs.readFileSync(filePath, 'utf8'), 'föo') }) - await t.test('should work (string)', () => { + await t.test('should work (string)', function () { const result = writeSync({path: filePath, value: 'bär'}) assert.equal(result.path, filePath) @@ -253,7 +255,7 @@ test('writeSync', async (t) => { assert.equal(fs.readFileSync(filePath, 'utf8'), 'bär') }) - await t.test('should work (null)', () => { + await t.test('should work (null)', function () { const result = writeSync(filePath) assert.equal(result.path, filePath) @@ -264,7 +266,7 @@ test('writeSync', async (t) => { }) assert.throws( - () => { + function () { writeSync(invalidFilePath) }, /ENOENT/, @@ -272,25 +274,25 @@ test('writeSync', async (t) => { ) }) -test('write', async (t) => { +test('write', async function (t) { const filePath = 'fixture.txt' const invalidFilePath = join('invalid', 'path', 'to', 'fixture.txt') - await t.test('should pass an error without path', async () => { - await new Promise((ok) => { + await t.test('should pass an error without path', async function () { + await new Promise(function (ok) { // @ts-expect-error: missing path. - write(null, (error) => { + write(null, function (error) { assert.ok(/path/i.test(String(error))) ok(undefined) }) }) }) - await t.test('should work (buffer without encoding)', async () => { + await t.test('should work (buffer without encoding)', async function () { const file = {path: filePath, value: Buffer.from('bäz')} - await new Promise((ok) => { - write(file, (error, result) => { + await new Promise(function (ok) { + write(file, function (error, result) { assert.ifError(error) assert(result, 'expected result') assert.equal(result.path, filePath) @@ -300,11 +302,11 @@ test('write', async (t) => { }) }) - await t.test('should work (string)', async () => { + await t.test('should work (string)', async function () { const file = {path: filePath, value: 'qüx'} - await new Promise((ok) => { - write(file, (error, result) => { + await new Promise(function (ok) { + write(file, function (error, result) { assert.ifError(error) assert(result, 'expected result') assert.equal(result.path, filePath) @@ -314,17 +316,17 @@ test('write', async (t) => { }) }) - await t.test('should work in promise mode (string)', async () => { + await t.test('should work in promise mode (string)', async function () { const result = await write({path: filePath, value: 'qüx-promise'}) assert.equal(result.path, filePath) assert.equal(fs.readFileSync(filePath, 'utf8'), 'qüx-promise') }) - await t.test('should work (string with encoding)', async () => { + await t.test('should work (string with encoding)', async function () { const file = {path: filePath, value: '62c3a472'} - await new Promise((ok) => { - write(file, 'hex', (error, result) => { + await new Promise(function (ok) { + write(file, 'hex', function (error, result) { assert.ifError(error) assert(result, 'expected result') assert.equal(result.path, filePath) @@ -336,7 +338,7 @@ test('write', async (t) => { await t.test( 'should work in promise mode (string with encoding)', - async () => { + async function () { const result = await write( {path: filePath, value: '62c3a4722d70726f6d697365'}, 'hex' @@ -346,9 +348,9 @@ test('write', async (t) => { } ) - await t.test('should work (null)', async () => { - await new Promise((ok) => { - write(filePath, (error, result) => { + await t.test('should work (null)', async function () { + await new Promise(function (ok) { + write(filePath, function (error, result) { const doc = fs.readFileSync(filePath, 'utf8') fs.unlinkSync(filePath) @@ -362,7 +364,7 @@ test('write', async (t) => { }) }) - await t.test('should work in promise mode (null)', async () => { + await t.test('should work in promise mode (null)', async function () { const result = await write(filePath) const doc = fs.readFileSync(filePath, 'utf8') @@ -375,9 +377,9 @@ test('write', async (t) => { await t.test( 'should pass an error for files that cannot be written', - async () => { - await new Promise((ok) => { - write(invalidFilePath, (error) => { + async function () { + await new Promise(function (ok) { + write(invalidFilePath, function (error) { assert(error, 'expected error') assert.ok(/ENOENT/.test(error.message)) ok(undefined) @@ -388,7 +390,7 @@ test('write', async (t) => { await t.test( 'should reject for files that cannot be written in promise mode', - async () => { + async function () { try { await write(invalidFilePath) assert.fail('should reject, not resolve')