diff --git a/package.json b/package.json index a310c03..e4ca011 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "lint-dockerfile": "docker run --rm -i hadolint/hadolint:latest-alpine < docker/Dockerfile", "lint-watch": "git ls-files | entr npm run lint", "schema": "cpy ./node_modules/markdownlint/schema/markdownlint-config-schema.json ./schema --flat", - "test": "ava --timeout=1m test/append-to-array-test.js test/fs-mock-test.js test/markdownlint-cli2-test.js test/markdownlint-cli2-test-exec.js test/markdownlint-cli2-test-exports.js test/markdownlint-cli2-test-fs.js test/markdownlint-cli2-test-main.js test/merge-options-test.js test/resolve-and-require-test.js", + "test": "ava --timeout=1m test/append-to-array-test.js test/fs-mock-test.js test/fs-virtual-test.js test/markdownlint-cli2-test.js test/markdownlint-cli2-test-exec.js test/markdownlint-cli2-test-exports.js test/markdownlint-cli2-test-fs.js test/markdownlint-cli2-test-main.js test/merge-options-test.js test/resolve-and-require-test.js", "test-cover": "c8 --100 npm test", "test-docker-hub-image": "VERSION=$(node -e \"process.stdout.write(require('./package.json').version)\") && docker image rm davidanson/markdownlint-cli2:v$VERSION davidanson/markdownlint-cli2:latest || true && docker run --rm -v $PWD:/workdir davidanson/markdownlint-cli2:v$VERSION \"*.md\" && docker run --rm -v $PWD:/workdir davidanson/markdownlint-cli2:latest \"*.md\"", "test-docker-hub-image-rules": "VERSION=$(node -e \"process.stdout.write(require('./package.json').version)\") && docker image rm davidanson/markdownlint-cli2-rules:v$VERSION davidanson/markdownlint-cli2-rules:latest || true && docker run --rm -v $PWD:/workdir davidanson/markdownlint-cli2-rules:v$VERSION \"*.md\" && docker run --rm -v $PWD:/workdir davidanson/markdownlint-cli2-rules:latest \"*.md\"", diff --git a/test/fs-virtual-test.js b/test/fs-virtual-test.js new file mode 100644 index 0000000..1887bc7 --- /dev/null +++ b/test/fs-virtual-test.js @@ -0,0 +1,92 @@ +// @ts-check + +"use strict"; + +const path = require("node:path"); +const { promisify } = require("node:util"); +const test = require("ava").default; +const FsVirtual = require("../webworker/fs-virtual"); + +const mockPath = "/mock"; +const thisFile = path.basename(__filename); +const testFile = path.join(mockPath, thisFile); +const missingFile = `${mockPath}/missing`; + +const virtualFiles = [ + [ "/mock/fs-virtual-test.js", "// content" ] +]; + +test("fsVirtual.stat", async (t) => { + t.plan(1); + const fs = new FsVirtual(virtualFiles); + const fsStat = promisify(fs.stat); + // @ts-ignore + const stat = await fsStat(testFile); + t.truthy(stat); +}); + +test("fsVirtual.lstat", async (t) => { + t.plan(10); + const fs = new FsVirtual(virtualFiles); + const fsLstat = promisify(fs.lstat); + // @ts-ignore + const stat = await fsLstat(testFile); + t.truthy(stat); + t.false(stat.isBlockDevice()); + t.false(stat.isCharacterDevice()); + t.false(stat.isDirectory()); + t.false(stat.isFIFO()); + t.true(stat.isFile()); + t.false(stat.isSocket()); + t.false(stat.isSymbolicLink()); + // @ts-ignore + const missingStat = await fsLstat(missingFile); + t.truthy(missingStat); + t.true(missingStat.isDirectory()); +}); + +test("fsVirtual.readdir", async (t) => { + t.plan(3); + const fs = new FsVirtual(virtualFiles); + const fsReaddir = promisify(fs.readdir); + // @ts-ignore + const files = await fsReaddir(`${mockPath}/`); + t.true(Array.isArray(files)); + t.true(files.length > 0); + t.true(files.includes(thisFile)); +}); + +test("fsVirtual.*", async (t) => { + t.plan(3); + const fs = new FsVirtual(virtualFiles); + const fsAccess = promisify(fs.access); + // @ts-ignore + await fsAccess(testFile); + const fsLstat = promisify(fs.lstat); + // @ts-ignore + await fsLstat(testFile); + const fsStat = promisify(fs.lstat); + // @ts-ignore + await fsStat(testFile); + const fsReadFile = promisify(fs.readFile); + // @ts-ignore + const content = await fsReadFile(testFile, "utf8"); + t.true(content.length > 0); + // @ts-ignore + await t.throwsAsync(() => fsAccess(missingFile)); + // @ts-ignore + await t.throwsAsync(() => fsReadFile(missingFile)); +}); + +test("fsVirtual.promises.*", async (t) => { + t.plan(3); + const fs = new FsVirtual(virtualFiles); + const tempName = "fs-mock.tmp"; + const tempFile = path.join(mockPath, tempName); + await t.throwsAsync(() => fs.promises.access(tempFile)); + await fs.promises.writeFile(tempFile, tempFile, "utf8"); + await fs.promises.access(tempFile); + await fs.promises.stat(tempFile); + t.is(await fs.promises.readFile(tempFile, "utf8"), tempFile); + await t.throwsAsync(() => fs.promises.readFile(missingFile, "utf8")); +}); diff --git a/webworker/fs-virtual.js b/webworker/fs-virtual.js index 6faef05..14d1ef3 100644 --- a/webworker/fs-virtual.js +++ b/webworker/fs-virtual.js @@ -2,8 +2,6 @@ "use strict"; -/* c8 ignore start */ - const dirent = (path, directory) => { const name = path.replace(/^.*\//u, ""); return { @@ -67,7 +65,8 @@ class FsVirtual { return (callback || mode)(new Error(`fs-virtual:access(${path})`)); }; - this.lstat = (path, callback) => { + // eslint-disable-next-line no-multi-assign + this.stat = this.lstat = (path, callback) => { path = normalize(path); if (this.files.has(path)) { return callback(null, dirent(path, false)); @@ -79,8 +78,8 @@ class FsVirtual { path = normalize(path); const names = []; for (const file of this.files.keys()) { - if (file.startsWith(path)) { - const name = file.slice(path.length).replace(/\/.*$/u, ""); + if (file.startsWith(`${path}`)) { + const [ name ] = file.slice(path.length).split("/"); if (!names.includes(name)) { names.push(name); } @@ -100,8 +99,6 @@ class FsVirtual { } } -/* c8 ignore stop */ - if (typeof module !== "undefined") { module.exports = FsVirtual; }