chore: Add a unit testing framework (#49)
Add vitest as a unit testing framework Reviewed-on: #49
This commit was merged in pull request #49.
This commit is contained in:
199
__tests__/index.test.js
Normal file
199
__tests__/index.test.js
Normal file
@@ -0,0 +1,199 @@
|
||||
const {
|
||||
validateAuthentication,
|
||||
replacePlaceholders,
|
||||
readReplaceAndWriteFiles,
|
||||
readFilesIntoDict,
|
||||
} = require("../index");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const os = require("os");
|
||||
const { glob } = require("glob");
|
||||
|
||||
describe("validateAuthentication", () => {
|
||||
it("should return null when only token is provided", () => {
|
||||
expect(validateAuthentication("token", null, null)).toBeNull();
|
||||
});
|
||||
|
||||
it("should return an error message when token and username are provided", () => {
|
||||
expect(validateAuthentication("token", "user", null)).toBe(
|
||||
"Token is defined along with username and/or password.",
|
||||
);
|
||||
});
|
||||
|
||||
it("should return an error message when token and password are provided", () => {
|
||||
expect(validateAuthentication("token", null, "pass")).toBe(
|
||||
"Token is defined along with username and/or password.",
|
||||
);
|
||||
});
|
||||
|
||||
it("should return an error message when token, username, and password are provided", () => {
|
||||
expect(validateAuthentication("token", "user", "pass")).toBe(
|
||||
"Token is defined along with username and/or password.",
|
||||
);
|
||||
});
|
||||
|
||||
it("should return an error message when no credentials are provided", () => {
|
||||
expect(validateAuthentication(null, null, null)).toBe(
|
||||
"Neither token nor password and username are defined.",
|
||||
);
|
||||
});
|
||||
|
||||
it("should return an error message when only username is provided", () => {
|
||||
expect(validateAuthentication(null, "user", null)).toBe(
|
||||
"Username is defined but no password is provided.",
|
||||
);
|
||||
});
|
||||
|
||||
it("should return an error message when only password is provided", () => {
|
||||
expect(validateAuthentication(null, null, "pass")).toBe(
|
||||
"Password is defined but no username is provided.",
|
||||
);
|
||||
});
|
||||
|
||||
it("should return null when username and password are provided", () => {
|
||||
expect(validateAuthentication(null, "user", "pass")).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("replacePlaceholders", () => {
|
||||
beforeEach(() => {
|
||||
process.env.GITHUB_SHA = "test-sha";
|
||||
process.env.GITHUB_REF = "test-ref";
|
||||
});
|
||||
|
||||
it("should replace all placeholders", () => {
|
||||
const content =
|
||||
"hash: {{gitHash}}, ref: {{gitRef}}, time: {{deployTime}}, host: {{hostname}}";
|
||||
const replacedContent = replacePlaceholders(content, "test-host");
|
||||
expect(replacedContent).toMatch(/hash: test-sha/);
|
||||
expect(replacedContent).toMatch(/ref: test-ref/);
|
||||
expect(replacedContent).toMatch(/time: .*/);
|
||||
expect(replacedContent).toMatch(/host: test-host/);
|
||||
});
|
||||
});
|
||||
|
||||
describe("readReplaceAndWriteFiles", () => {
|
||||
let tempDir;
|
||||
|
||||
beforeEach(async () => {
|
||||
tempDir = await fs.promises.mkdtemp(
|
||||
path.join(os.tmpdir(), "replace-test-"),
|
||||
);
|
||||
process.env.GITHUB_SHA = "test-sha";
|
||||
process.env.GITHUB_REF = "test-ref";
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
if (tempDir) {
|
||||
await fs.promises.rm(tempDir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
it("should find files and replace placeholders", async () => {
|
||||
const fileName = "test.js";
|
||||
const filePath = path.join(tempDir, fileName);
|
||||
const content = "hash: {{gitHash}}, ref: {{gitRef}}, host: {{hostname}}";
|
||||
await fs.promises.writeFile(filePath, content);
|
||||
|
||||
const pattern = "*.js";
|
||||
// We pass tempDir as the prefix so glob searches inside it
|
||||
await readReplaceAndWriteFiles(pattern, tempDir, "test-host");
|
||||
|
||||
const updatedContent = await fs.promises.readFile(filePath, "utf8");
|
||||
|
||||
expect(updatedContent).toContain("hash: test-sha");
|
||||
expect(updatedContent).toContain("ref: test-ref");
|
||||
expect(updatedContent).toContain("host: test-host");
|
||||
});
|
||||
});
|
||||
|
||||
describe("readFilesIntoDict", () => {
|
||||
let tempDir;
|
||||
|
||||
beforeEach(async () => {
|
||||
tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "read-test-"));
|
||||
await fs.promises.mkdir(path.join(tempDir, "subdir"), { recursive: true });
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
if (tempDir) {
|
||||
await fs.promises.rm(tempDir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
it("should read files into a dictionary with correct keys", async () => {
|
||||
const file1 = "file1.js";
|
||||
const content1 = "content1";
|
||||
await fs.promises.writeFile(path.join(tempDir, file1), content1);
|
||||
|
||||
const file2 = "subdir/file2.js";
|
||||
const content2 = "content2";
|
||||
await fs.promises.writeFile(path.join(tempDir, file2), content2);
|
||||
|
||||
const pattern = "**/*.js";
|
||||
const result = await readFilesIntoDict(pattern, tempDir);
|
||||
|
||||
// Keys should be relative paths without extension
|
||||
// On Windows, the path separator might differ, so we should be careful or just check contents
|
||||
|
||||
// Based on implementation:
|
||||
// key = key.slice(prefix.length);
|
||||
// key = path.basename(key, path.extname(key)); // Drop the file suffix -> THIS IS BUGGY for subdirs?
|
||||
|
||||
// Let's check the implementation of readFilesIntoDict again in index.js
|
||||
// It does: key = path.basename(key, path.extname(key));
|
||||
// This removes the directory part! So subdir/file2.js becomes file2
|
||||
|
||||
expect(result["file1"]).toBe(content1);
|
||||
expect(result["file2"]).toBe(content2);
|
||||
});
|
||||
});
|
||||
|
||||
describe("glob functionality", () => {
|
||||
let tempDir;
|
||||
|
||||
beforeEach(async () => {
|
||||
tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "glob-test-"));
|
||||
await fs.promises.mkdir(path.join(tempDir, "lib"), { recursive: true });
|
||||
await fs.promises.mkdir(path.join(tempDir, "deep", "folder"), {
|
||||
recursive: true,
|
||||
});
|
||||
await fs.promises.writeFile(path.join(tempDir, "main.js"), "content");
|
||||
await fs.promises.writeFile(path.join(tempDir, "utils.js"), "content");
|
||||
await fs.promises.writeFile(
|
||||
path.join(tempDir, "lib", "helper.js"),
|
||||
"content",
|
||||
);
|
||||
await fs.promises.writeFile(
|
||||
path.join(tempDir, "lib", "data.json"),
|
||||
"content",
|
||||
);
|
||||
await fs.promises.writeFile(
|
||||
path.join(tempDir, "deep", "folder", "main.js"),
|
||||
"content",
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
if (tempDir) {
|
||||
await fs.promises.rm(tempDir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
it("should find all javascript files in the directory", async () => {
|
||||
// Ensure pattern uses forward slashes for glob
|
||||
const pattern = path.join(tempDir, "**", "*.js").split(path.sep).join("/");
|
||||
const files = await glob(pattern);
|
||||
|
||||
// Normalize file paths to system separator (backslashes on Windows)
|
||||
const normalizedFiles = files.map((f) => path.normalize(f));
|
||||
|
||||
const expectedFiles = [
|
||||
path.join(tempDir, "deep", "folder", "main.js"),
|
||||
path.join(tempDir, "lib", "helper.js"),
|
||||
path.join(tempDir, "main.js"),
|
||||
path.join(tempDir, "utils.js"),
|
||||
].sort();
|
||||
expect(normalizedFiles.sort()).toEqual(expectedFiles);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user