feat: add Compiler and HandlebarsCompiler with tests; improve FileManager and YamlParser functionality

This commit is contained in:
Lucàs
2025-07-14 14:03:59 +02:00
parent a672169e92
commit 9590e60372
10 changed files with 143 additions and 2 deletions
+1
View File
@@ -2,3 +2,4 @@
. "$(dirname -- "$0")/_/husky.sh"
bun run lint-staged
git add
+3 -1
View File
@@ -9,7 +9,9 @@
"format": "bunx prettier --write .",
"format:check": "bunx prettier --check .",
"test": "bun test",
"prepare": "husky install"
"prepare": "husky install",
"dev": "bun run format:check && bun run lint && bun run build",
"dev:watch": "bun run --watch src -- bun run dev"
},
"devDependencies": {
"@eslint/css": "^0.10.0",
@@ -0,0 +1,26 @@
import { CompilerFactory } from './CompilerFactory.ts';
import { CompilerType } from './CompilerType.ts';
import { describe, expect, it } from 'bun:test';
import type { Compiler } from './Compiler.ts';
describe('CompilerFactory', () => {
it('should return a valid compiler instance for each supported type', () => {
const fixture: CompilerType[] = [CompilerType.HANDLEBARS];
for (const type of fixture) {
const compiler: Compiler = CompilerFactory.getCompiler(type);
expect(compiler).toBeDefined();
expect(compiler).toHaveProperty('compile');
}
});
it('should throw an error for unsupported compiler types', () => {
const fixture: CompilerType[] = ['UNSUPPORTED_TYPE' as unknown as CompilerType];
for (const type of fixture) {
expect(() => CompilerFactory.getCompiler(type)).toThrowError(
`Unsupported compiler type: ${type}`
);
}
});
});
+9
View File
@@ -0,0 +1,9 @@
import { CompilerType } from './CompilerType';
import { describe, expect, it } from 'bun:test';
describe('CompilerType', () => {
it('should be an enum', () => {
expect(typeof CompilerType).toBe('object');
expect(Object.keys(CompilerType)).toContain('HANDLEBARS');
});
});
@@ -0,0 +1,62 @@
import { HandlebarsCompiler } from './HandlebarsCompiler';
import { CompilerType } from './CompilerType';
import { describe, expect, it } from 'bun:test';
describe('HandlebarsCompiler', () => {
const compiler = HandlebarsCompiler.getInstance();
it('should return the singleton instance', () => {
expect(compiler).toBeInstanceOf(HandlebarsCompiler);
expect(HandlebarsCompiler.getInstance()).toBe(compiler);
});
it('should have the correct compiler type', () => {
expect(HandlebarsCompiler.TYPE).toBe(CompilerType.HANDLEBARS);
});
it('should compile valid Handlebars templates', () => {
type Fixture = {
actual: {
template: string;
data: object;
};
expected: string;
};
const fixture: Fixture[] = [
{
actual: {
template: `Hello, {{name}}!`,
data: { name: 'World' },
},
expected: 'Hello, World!',
},
];
for (const { actual, expected } of fixture) {
expect(compiler.compile(actual.template, actual.data)).toBe(expected);
}
});
it('should throw an error for invalid Handlebars templates', () => {
type Fixture = {
actual: {
template: string;
data: object;
};
};
const fixture: Fixture[] = [
{
actual: {
template: `Hello, {{name!}}`,
data: { name: 'World' },
},
},
];
for (const { actual } of fixture) {
expect(() => compiler.compile(actual.template, actual.data)).toThrowError();
}
});
});
+1 -1
View File
@@ -2,7 +2,7 @@ import { type Compiler, CompilerType } from '.';
import { compile } from 'handlebars';
export class HandlebarsCompiler implements Compiler {
static readonly TYPE: CompilerType = CompilerType.HANDLEBARS;
public static readonly TYPE: CompilerType = CompilerType.HANDLEBARS;
private static instance: HandlebarsCompiler;
private constructor() {}
+17
View File
@@ -0,0 +1,17 @@
import { FileManager } from './FileManager';
import { describe, expect, it } from 'bun:test';
describe('FileManager', () => {
it('should read a file successfully', async () => {
const content = await FileManager.read('tests/core/io/test.txt');
expect(content).toBeDefined();
expect(typeof content).toBe('string');
expect(content).toContain('This is a test file.');
});
it('should throw an error for a non-existent file', async () => {
expect(FileManager.read('./non-existent.txt')).rejects.toThrow(
"ENOENT: no such file or directory, open './non-existent.txt'"
);
});
});
+13
View File
@@ -36,4 +36,17 @@ export class FileManager {
flag: 'w',
});
}
/**
* Removes a file at the specified path.
* @param {string} filePath - The path to the file to remove.
* @returns {Promise<void>} A promise that resolves when the file is removed.
*/
public static async remove(filePath: string): Promise<void> {
if (existsSync(filePath)) {
writeFileSync(filePath, '', { encoding: 'utf-8', flag: 'w' });
} else {
throw new Error(`File not found: ${filePath}`);
}
}
}
+10
View File
@@ -1,9 +1,19 @@
import { YamlParser } from './YamlParser';
import { ParserType } from './ParserType';
import { describe, expect, it } from 'bun:test';
describe('YamlParser', () => {
const parser = YamlParser.getInstance();
it('should return the singleton instance', () => {
expect(parser).toBeInstanceOf(YamlParser);
expect(YamlParser.getInstance()).toBe(parser);
});
it('should have the correct parser type', () => {
expect(YamlParser.TYPE).toBe(ParserType.YAML);
});
it('should parse valid YAML data', () => {
type Fixture = {
actual: string;
+1
View File
@@ -0,0 +1 @@
This is a test file.