diff --git a/extensions/ql-vscode/src/common/unzip.ts b/extensions/ql-vscode/src/common/unzip.ts index acd24510f..77052fe52 100644 --- a/extensions/ql-vscode/src/common/unzip.ts +++ b/extensions/ql-vscode/src/common/unzip.ts @@ -28,12 +28,7 @@ export function readZipEntries(zipFile: ZipFile): Promise { zipFile.readEntry(); zipFile.on("entry", (entry: ZipEntry) => { - if (/\/$/.test(entry.fileName)) { - // Directory file names end with '/' - // We don't need to do anything for directories. - } else { - files.push(entry); - } + files.push(entry); zipFile.readEntry(); }); diff --git a/extensions/ql-vscode/test/unit-tests/common/unzip.test.ts b/extensions/ql-vscode/test/unit-tests/common/unzip.test.ts new file mode 100644 index 000000000..931517fac --- /dev/null +++ b/extensions/ql-vscode/test/unit-tests/common/unzip.test.ts @@ -0,0 +1,113 @@ +import { resolve } from "path"; +import { + excludeDirectories, + openZip, + openZipBuffer, + readZipEntries, +} from "../../../src/common/unzip"; + +const zipWithSingleFilePath = resolve( + __dirname, + "../../vscode-tests/no-workspace/data/archive-filesystem-provider-test/single_file.zip", +); +const zipWithFolderPath = resolve( + __dirname, + "../../vscode-tests/no-workspace/data/archive-filesystem-provider-test/zip_with_folder.zip", +); + +describe("openZip", () => { + it("can open a zip file", async () => { + const zipFile = await openZip(zipWithFolderPath, { + lazyEntries: false, + }); + + expect(zipFile.entryCount).toEqual(8); + }); +}); + +describe("readZipEntries", () => { + it("can read the entries when there is a single file", async () => { + const zipFile = await openZip(zipWithSingleFilePath, { + lazyEntries: true, + }); + const entries = await readZipEntries(zipFile); + + expect(entries.map((entry) => entry.fileName).sort()).toEqual([ + "src_archive/", + "src_archive/aFileName.txt", + ]); + }); + + it("can read the entries when there are multiple folders", async () => { + const zipFile = await openZip(zipWithFolderPath, { + lazyEntries: true, + }); + const entries = await readZipEntries(zipFile); + + expect(entries.map((entry) => entry.fileName).sort()).toEqual([ + "__MACOSX/._folder1", + "__MACOSX/folder1/._textFile.txt", + "__MACOSX/folder1/._textFile2.txt", + "folder1/", + "folder1/folder2/", + "folder1/folder2/textFile3.txt", + "folder1/textFile.txt", + "folder1/textFile2.txt", + ]); + }); +}); + +describe("excludeDirectories", () => { + it("excludes directories when there is a single file", async () => { + const zipFile = await openZip(zipWithSingleFilePath, { + lazyEntries: true, + }); + const entries = await readZipEntries(zipFile); + const entriesWithoutDirectories = excludeDirectories(entries); + + expect( + entriesWithoutDirectories.map((entry) => entry.fileName).sort(), + ).toEqual(["src_archive/aFileName.txt"]); + }); + + it("excludes directories when there are multiple folders", async () => { + const zipFile = await openZip(zipWithFolderPath, { + lazyEntries: true, + }); + const entries = await readZipEntries(zipFile); + const entriesWithoutDirectories = excludeDirectories(entries); + + expect( + entriesWithoutDirectories.map((entry) => entry.fileName).sort(), + ).toEqual([ + "__MACOSX/._folder1", + "__MACOSX/folder1/._textFile.txt", + "__MACOSX/folder1/._textFile2.txt", + "folder1/folder2/textFile3.txt", + "folder1/textFile.txt", + "folder1/textFile2.txt", + ]); + }); +}); + +describe("openZipBuffer", () => { + it("can read an entry in the zip file", async () => { + const zipFile = await openZip(zipWithFolderPath, { + lazyEntries: true, + autoClose: false, + }); + const entries = await readZipEntries(zipFile); + + const entry = entries.find( + (entry) => entry.fileName === "folder1/textFile.txt", + ); + expect(entry).toBeDefined(); + if (!entry) { + return; + } + + const buffer = await openZipBuffer(zipFile, entry); + expect(buffer).toHaveLength(12); + expect(buffer.toString("utf8")).toEqual("I am a text\n"); + }); +});