Skip to content

Commit b0461bb

Browse files
committed
Added vitests for archive module
1 parent d49a5b7 commit b0461bb

File tree

1 file changed

+199
-0
lines changed

1 file changed

+199
-0
lines changed

vitest/tests/archive.test.ts

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2024, Mattias Aabmets
5+
*
6+
* The contents of this file are subject to the terms and conditions defined in the License.
7+
* You may not use, modify, or distribute this file except in compliance with the License.
8+
*
9+
* SPDX-License-Identifier: Apache-2.0
10+
*/
11+
12+
import type { Dirent } from "node:fs";
13+
import fsp from "node:fs/promises";
14+
import archive from "@src/archive";
15+
import type * as t from "@types";
16+
import type { DecompressOptions, File } from "decompress";
17+
import { afterEach, describe, expect, it, vi } from "vitest";
18+
19+
vi.mock("decompress", () => {
20+
return {
21+
default: vi.fn((_, __, opts: DecompressOptions): File[] => {
22+
const file: File = {
23+
data: Buffer.from("asdfg"),
24+
mode: 1,
25+
mtime: "mtime",
26+
type: "file",
27+
path: "/absolute/path/only_file.txt",
28+
};
29+
if (opts?.filter) {
30+
return opts.filter(file) ? [file] : [];
31+
}
32+
return [file];
33+
}),
34+
};
35+
});
36+
import decompress from "decompress";
37+
38+
describe("digestDecompressionOptions", () => {
39+
it("should return empty string when arg is undefined", () => {
40+
const result = archive.digestDecompressionOptions(undefined);
41+
expect(result).toEqual("");
42+
});
43+
44+
it("should return a digest when arg is boolean", () => {
45+
const result = archive.digestDecompressionOptions(true);
46+
expect(typeof result).toEqual("string");
47+
expect(result.length).toBeGreaterThanOrEqual(32);
48+
});
49+
50+
it("should return a digest when arg is an object", () => {
51+
for (const obj of [{}, { filter: ["asdfg", /\w/], strip: 3 }]) {
52+
const result = archive.digestDecompressionOptions(obj);
53+
expect(typeof result).toEqual("string");
54+
expect(result.length).toBeGreaterThanOrEqual(32);
55+
}
56+
});
57+
});
58+
59+
describe("allDecompressedFilesExist", () => {
60+
afterEach(vi.clearAllMocks);
61+
62+
it("should check if all decompressed files exist", async () => {
63+
const entry: t.HistoryFileEntry = {
64+
url: "",
65+
dest: "",
66+
blobOptionsDigest: "",
67+
decompression: {
68+
optionsDigest: "",
69+
filesList: ["asdfgh.txt", "qwerty.txt", "zxcvbn.txt"],
70+
},
71+
};
72+
const details: t.DestDetails = {
73+
fileName: "",
74+
fileExists: false,
75+
filePath: "",
76+
dirExists: true,
77+
dirPath: "/absolute/path",
78+
};
79+
const spy = vi.spyOn(fsp, "access");
80+
81+
spy.mockImplementation(() => new Promise((resolve) => resolve(undefined)));
82+
const result1 = await archive.allDecompressedFilesExist(entry, details);
83+
expect(result1).toEqual(true);
84+
expect(spy).toHaveBeenCalledTimes(3);
85+
86+
spy.mockClear();
87+
88+
spy.mockImplementation(() => new Promise((_, reject) => reject(undefined)));
89+
const result2 = await archive.allDecompressedFilesExist(entry, details);
90+
expect(result2).toEqual(false);
91+
expect(spy).toHaveBeenCalledTimes(3);
92+
});
93+
});
94+
95+
describe("removeAllDecompressedFiles", () => {
96+
afterEach(vi.clearAllMocks);
97+
98+
const details: t.DestDetails = {
99+
fileName: "",
100+
fileExists: false,
101+
filePath: "",
102+
dirExists: true,
103+
dirPath: "/absolute/path",
104+
};
105+
const entry: t.HistoryFileEntry = {
106+
url: "",
107+
dest: "",
108+
blobOptionsDigest: "",
109+
decompression: {
110+
optionsDigest: "",
111+
filesList: [],
112+
},
113+
};
114+
115+
it("should return early when filesList is empty", async () => {
116+
const rmdirSpy = vi.spyOn(fsp, "rmdir");
117+
const unlinkSpy = vi.spyOn(fsp, "unlink");
118+
const readdirSpy = vi.spyOn(fsp, "readdir");
119+
120+
await archive.removeAllDecompressedFiles(entry, details);
121+
expect(unlinkSpy).toHaveBeenCalledTimes(0);
122+
expect(readdirSpy).toHaveBeenCalledTimes(0);
123+
expect(rmdirSpy).toHaveBeenCalledTimes(0);
124+
});
125+
126+
it("should remove all decompressed files", async () => {
127+
const entryWithFiles = {
128+
...entry,
129+
decompression: {
130+
optionsDigest: "",
131+
filesList: ["asdfgh.txt", "qwerty.txt", "zxcvbn.txt"],
132+
},
133+
};
134+
const rmdirSpy = vi.spyOn(fsp, "rmdir");
135+
const unlinkSpy = vi.spyOn(fsp, "unlink");
136+
const readdirSpy = vi.spyOn(fsp, "readdir");
137+
138+
rmdirSpy.mockImplementation(() => new Promise((resolve) => resolve(undefined)));
139+
unlinkSpy.mockImplementation(() => new Promise((resolve) => resolve(undefined)));
140+
readdirSpy.mockImplementationOnce(() => new Promise((resolve) => resolve([])));
141+
142+
await archive.removeAllDecompressedFiles(entryWithFiles, details);
143+
expect(unlinkSpy).toHaveBeenCalledTimes(3);
144+
expect(readdirSpy).toHaveBeenCalledTimes(1);
145+
expect(rmdirSpy).toHaveBeenCalledTimes(1);
146+
147+
rmdirSpy.mockClear();
148+
unlinkSpy.mockClear();
149+
readdirSpy.mockClear();
150+
readdirSpy.mockImplementationOnce(() => new Promise((resolve) => resolve([{} as Dirent])));
151+
152+
await archive.removeAllDecompressedFiles(entryWithFiles, details);
153+
expect(unlinkSpy).toHaveBeenCalledTimes(3);
154+
expect(readdirSpy).toHaveBeenCalledTimes(1);
155+
expect(rmdirSpy).toHaveBeenCalledTimes(0);
156+
});
157+
});
158+
159+
describe("decompressArchive", () => {
160+
afterEach(vi.clearAllMocks);
161+
const option: t.RemoteBlobOption = { url: "", dest: "" };
162+
const details: t.DestDetails = {
163+
fileName: "",
164+
fileExists: false,
165+
filePath: "",
166+
dirExists: true,
167+
dirPath: "/absolute/path",
168+
};
169+
170+
it("should decompress archive without options", async () => {
171+
const spy1 = vi.spyOn(fsp, "unlink");
172+
const result = await archive.decompressArchive({ option, details });
173+
expect(result).toEqual(["/absolute/path/only_file.txt"]);
174+
expect(decompress).toHaveBeenCalledOnce();
175+
expect(spy1).toHaveBeenCalledOnce();
176+
});
177+
178+
it("should decompress archive with empty option", async () => {
179+
const spy = vi.spyOn(fsp, "unlink");
180+
const result = await archive.decompressArchive({
181+
option: { ...option, decompress: {} },
182+
details,
183+
});
184+
expect(result).toEqual(["/absolute/path/only_file.txt"]);
185+
expect(decompress).toHaveBeenCalledOnce();
186+
expect(spy).toHaveBeenCalledOnce();
187+
});
188+
189+
it("should decompress archive with filtering option", async () => {
190+
const spy = vi.spyOn(fsp, "unlink");
191+
const result = await archive.decompressArchive({
192+
option: { ...option, decompress: { filter: ["only_file.txt"] } },
193+
details,
194+
});
195+
expect(result).toEqual(["/absolute/path/only_file.txt"]);
196+
expect(decompress).toHaveBeenCalledOnce();
197+
expect(spy).toHaveBeenCalledOnce();
198+
});
199+
});

0 commit comments

Comments
 (0)