diff --git a/.husky/pre-commit b/.husky/pre-commit index 375d2a1..c3fef93 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -2,3 +2,4 @@ . "$(dirname -- "$0")/_/husky.sh" bun run lint-staged +git add \ No newline at end of file diff --git a/package.json b/package.json index dd76793..89473a3 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/core/compilers/CompilerFactory.test.ts b/src/core/compilers/CompilerFactory.test.ts new file mode 100644 index 0000000..4f34b5b --- /dev/null +++ b/src/core/compilers/CompilerFactory.test.ts @@ -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}` + ); + } + }); +}); diff --git a/src/core/compilers/CompilerType.test.ts b/src/core/compilers/CompilerType.test.ts new file mode 100644 index 0000000..ef54575 --- /dev/null +++ b/src/core/compilers/CompilerType.test.ts @@ -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'); + }); +}); diff --git a/src/core/compilers/HandlebarsCompiler.test.ts b/src/core/compilers/HandlebarsCompiler.test.ts new file mode 100644 index 0000000..c7970eb --- /dev/null +++ b/src/core/compilers/HandlebarsCompiler.test.ts @@ -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(); + } + }); +}); diff --git a/src/core/compilers/HandlebarsCompiler.ts b/src/core/compilers/HandlebarsCompiler.ts index 1a26631..87fc5c2 100644 --- a/src/core/compilers/HandlebarsCompiler.ts +++ b/src/core/compilers/HandlebarsCompiler.ts @@ -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() {} diff --git a/src/core/io/FileManager.test.ts b/src/core/io/FileManager.test.ts new file mode 100644 index 0000000..b4146c4 --- /dev/null +++ b/src/core/io/FileManager.test.ts @@ -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'" + ); + }); +}); diff --git a/src/core/io/FileManager.ts b/src/core/io/FileManager.ts index f63a156..11a5016 100644 --- a/src/core/io/FileManager.ts +++ b/src/core/io/FileManager.ts @@ -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} A promise that resolves when the file is removed. + */ + public static async remove(filePath: string): Promise { + if (existsSync(filePath)) { + writeFileSync(filePath, '', { encoding: 'utf-8', flag: 'w' }); + } else { + throw new Error(`File not found: ${filePath}`); + } + } } diff --git a/src/core/parsers/YamlParser.test.ts b/src/core/parsers/YamlParser.test.ts index 41eb084..ddce8e4 100644 --- a/src/core/parsers/YamlParser.test.ts +++ b/src/core/parsers/YamlParser.test.ts @@ -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; diff --git a/tests/core/io/test.txt b/tests/core/io/test.txt new file mode 100644 index 0000000..af27ff4 --- /dev/null +++ b/tests/core/io/test.txt @@ -0,0 +1 @@ +This is a test file. \ No newline at end of file