Skip to content

Commit

Permalink
Added more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonnathan committed Oct 12, 2024
1 parent 863f113 commit fa6bdda
Show file tree
Hide file tree
Showing 2 changed files with 153 additions and 14 deletions.
19 changes: 13 additions & 6 deletions skeletor.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -158,23 +158,28 @@ export async function printUsage() {
}
}

function parseArguments() {
const args = Bun.argv.slice(2);
const options = { overwrite: false }; // default to not overwriting files
export function parseArguments(args = Bun.argv.slice(2)) {
const options = { overwrite: false }; // Default to not overwriting files
for (let i = 0; i < args.length; i++) {
const arg = args[i];
if (arg === "--input" || (arg === "-i" && args[i + 1])) {
if ((arg === "--input" || arg === "-i") && args[i + 1]) {
options.inputFilePath = path.resolve(args[i + 1]);
i++;
i++; // Skip the next argument as it’s the file path
} else if (arg === "--help" || arg === "-h") {
options.help = true;
} else if (arg === "--overwrite" || arg === "-o") {
options.overwrite = true;
} else {
logError(`Unknown argument: ${args[i]}`);
logError(`Unknown argument: ${arg}`);
options.help = true;
}
}

// Set default inputFilePath if not provided
if (!options.inputFilePath) {
options.inputFilePath = path.resolve(".skeletorrc");
}

return options;
}

Expand Down Expand Up @@ -240,3 +245,5 @@ if (import.meta.url === `file://${process.argv[1]}`) {
}
});
}


148 changes: 140 additions & 8 deletions skeletor.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import {
traverseStructure,
countTotalTasks,
createFilesAndDirectories,
printUsage
printUsage ,
parseArguments
} from "./skeletor.mjs"; // Import the functions

// Test directory where Skeletor will generate files and directories
Expand Down Expand Up @@ -51,27 +52,34 @@ it("should create file with directories and respect overwrite option", (done) =>

it("should traverse directory structure correctly", () => {
const structure = {
"src": {
src: {
"index.js": "console.log('Hello, world!');",
"components": {
"Header.js": "// Header component"
components: {
"Header.js": "// Header component",
"Footer.js": "// Footer component"
}
}
};

// Traverse the directory structure
const paths = Array.from(traverseStructure(testDir, structure));

// Expected paths (unordered)
// Define the expected paths
const expectedPaths = [
{ type: "dir", path: path.join(testDir, "src") },
{ type: "dir", path: path.join(testDir, "src", "components") },
{ type: "file", path: path.join(testDir, "src", "index.js"), content: "console.log('Hello, world!');" },
{ type: "file", path: path.join(testDir, "src", "components", "Header.js"), content: "// Header component" }
{ type: "file", path: path.join(testDir, "src", "components", "Header.js"), content: "// Header component" },
{ type: "file", path: path.join(testDir, "src", "components", "Footer.js"), content: "// Footer component" }
];

// Check that paths match expectedPaths (regardless of order)
// Verify that each expected path exists in the generated paths array
expectedPaths.forEach(expected => {
expect(paths).toEqual(expect.arrayContaining([expected]));
const found = paths.find(p => p.path === expected.path && p.type === expected.type);
expect(found).toBeTruthy();
if (expected.content) {
expect(found.content).toBe(expected.content);
}
});
});

Expand Down Expand Up @@ -126,3 +134,127 @@ it("should display help information when --help argument is passed", async () =>
// Restore the original console.log
console.log = originalConsoleLog;
});

it("should parse command-line arguments correctly", () => {
const options = parseArguments(["--input", "structure.yaml", "--overwrite"]);

expect(options.inputFilePath).toBe(path.resolve("structure.yaml"));
expect(options.overwrite).toBe(true);
});

it("should set default options when no arguments are provided", () => {
const options = parseArguments([]);

expect(options.inputFilePath).toBe(path.resolve(".skeletorrc"));
expect(options.overwrite).toBe(false);
});

it("should handle file creation errors", (done) => {
const faultyPath = "/invalid/path/to/file.txt";
writeFileWithDirs(faultyPath, "content", false, (err) => {
expect(err).not.toBeNull(); // Expect an error to be returned
done();
});
});

it("should handle invalid YAML input", (done) => {
const invalidYaml = "invalid: yaml: data"; // Invalid YAML format

fs.writeFileSync(path.join(testDir, ".skeletorrc"), invalidYaml);
fs.readFile(path.join(testDir, ".skeletorrc"), "utf8", (err, data) => {
expect(() => yaml.parse(data)).toThrow(); // Expect YAML parsing to fail
done();
});
});

it("should create directories and display progress", (done) => {
const structure = {
"src": {
"index.js": "console.log('Hello, world!');",
"components": {
"Header.js": "// Header component"
}
}
};

// Mock console.clear and process.stdout.write to capture progress output
const originalConsoleClear = console.clear;
const originalProcessWrite = process.stdout.write;
let progressOutput = "";

console.clear = () => {}; // No-op
process.stdout.write = (chunk) => { progressOutput += chunk; };

createFilesAndDirectories(testDir, structure, false, (err, stats) => {
expect(err).toBeNull();
expect(progressOutput).toContain("Progress: 100.00%"); // Verify progress
console.clear = originalConsoleClear;
process.stdout.write = originalProcessWrite;
done();
});
});

it("should handle empty directory structure", () => {
const structure = {}; // No directories or files
const paths = Array.from(traverseStructure(testDir, structure));

expect(paths.length).toBe(0); // No paths should be generated
});

it("should handle missing .skeletorrc file", (done) => {
const missingFilePath = path.join(testDir, ".skeletorrc");

fs.rmSync(missingFilePath, { force: true }); // Ensure file is missing
fs.readFile(missingFilePath, "utf8", (err) => {
expect(err).not.toBeNull(); // Expect an error when reading a non-existent file
done();
});
});

it("should handle error reading usage file in printUsage", async () => {
const originalReadFileSync = fs.readFileSync;
fs.readFileSync = () => { throw new Error("File read error"); }; // Simulate file read error

const originalConsoleError = console.error;
let errorOutput = "";
console.error = (output) => { errorOutput += output; }; // Capture console.error

await printUsage();
expect(errorOutput).toContain("\u001B[31m");

fs.readFileSync = originalReadFileSync; // Restore original function
console.error = originalConsoleError; // Restore console.error
});

it("should correctly count the total number of tasks (directories and files)", () => {
const structure = {
src: {
"index.js": "console.log('Hello, world!');",
components: {
"Header.js": "// Header component",
"Footer.js": "// Footer component"
}
},
config: {
"app.config": "config content",
}
};

const totalTasks = countTotalTasks(structure);

// We expect 6 tasks in total:
// 2 directories (src, components)
// 4 files (index.js, Header.js, Footer.js, app.config)
expect(totalTasks).toBe(7);
});

it("should handle file write errors gracefully", (done) => {
const filePath = path.join(testDir, "testfile.txt");

// Simulate a file system write error by providing an invalid path
writeFileWithDirs("/invalid/path/to/file.txt", "content", false, (err) => {
expect(err).not.toBeNull();
done();
});
});

0 comments on commit fa6bdda

Please # to comment.