diff --git a/analscript.js b/analscript.js index 3da3f4f..94001f5 100644 --- a/analscript.js +++ b/analscript.js @@ -1,4 +1,4 @@ -import { anallify, stringify } from './lib/stdlib.js'; +import { anallify, stringify } from './lib/std.js'; export { anallify, stringify }; export default { anallify, stringify }; diff --git a/cli.js b/cli.js index 67a9e2a..6f21ee8 100644 --- a/cli.js +++ b/cli.js @@ -1,12 +1,13 @@ #!/usr/bin/env node import help from './lib/help.js'; +import { graceful } from './lib/utils.js'; import { run, compile, anallify, stringify, -} from './lib/stdlib.js'; +} from './lib/std.js'; import { RUN, @@ -33,4 +34,4 @@ function cli() { process.stdout.write(`${output}\n`); } -cli(); +graceful(cli); diff --git a/lib/stdlib.js b/lib/std.js similarity index 75% rename from lib/stdlib.js rename to lib/std.js index 1a0e1c4..505049f 100644 --- a/lib/stdlib.js +++ b/lib/std.js @@ -1,18 +1,16 @@ import fs from 'node:fs'; -import checker from './utils.js'; +import { checker } from './utils.js'; import { ERROR, SUCCESS } from './dictionary.js'; import { ANAL_CHARACTERS } from './constants.js'; export function anallify(string) { if (!checker(string)) { - process.stderr.write(`${ERROR.notString}\n`); - return process.exit(1); + throw new Error(ERROR.notString); } if (!string) { - process.stderr.write(`${ERROR.missingArgument}\n`); - return process.exit(1); + throw new Error(ERROR.missingArgument); } let anal = ''; @@ -29,13 +27,11 @@ export function anallify(string) { export function stringify(anal) { if (!checker(anal)) { - process.stderr.write(`${ERROR.notString}\n`); - return process.exit(1); + throw new Error(ERROR.notString); } if (!anal) { - process.stderr.write(`${ERROR.missingArgument}\n`); - return process.exit(1); + throw new Error(ERROR.missingArgument); } let string = ''; @@ -56,23 +52,20 @@ export function run(file) { const contents = fs.readFileSync(file, { encoding: 'utf-8' }); return stringify(contents); } catch (error) { - process.stderr.write(`${ERROR.fileNotFound}\n`); - return process.exit(1); + throw new Error(ERROR.fileNotFound); } } export function compile(file) { try { const contents = fs.readFileSync(file, { encoding: 'utf-8' }); - let filename = file.split('.'); filename = filename.filter((element, index) => index < filename.length - 1); filename = filename.join('.'); - fs.writeFileSync(`${filename}.anal`, anallify(contents), { encoding: 'utf-8' }); process.stdout.write(`${SUCCESS.compileSuccess}`); + return true; } catch (error) { - process.stderr.write(`${ERROR.fileNotFound}\n`); - process.exit(1); + throw new Error(ERROR.fileNotFound); } } diff --git a/lib/utils.js b/lib/utils.js index 526170d..ec47d2c 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1,3 +1,12 @@ -export default function checker(input) { +export function checker(input) { return typeof input === 'string'; } + +export function graceful(fn) { + try { + fn(); + } catch (error) { + process.stderr.write(`${error.message}\n`); + process.exit(1); + } +} diff --git a/tests/hello.anus b/tests/hello.anus new file mode 100644 index 0000000..99f615c --- /dev/null +++ b/tests/hello.anus @@ -0,0 +1 @@ +Hello, Analscript! \ No newline at end of file diff --git a/tests/seeds.js b/tests/seeds.js index 2d3d790..182320f 100644 --- a/tests/seeds.js +++ b/tests/seeds.js @@ -1,3 +1,6 @@ +export const NUMERIC_INPUT = 1; +export const EMPTY_STRING_INPUT = ''; + export const STRINGIFY_CORRECT_OUTPUT = 'B'; export const STRINGIFY_WRONG_OUTPUT = '🍑🍆🍑🍆'; export const STRINGIFY_INPUT = '🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆'; @@ -9,3 +12,7 @@ export const ANALLIFY_CORRECT_OUTPUT = '🍑🍆🍑🍆🍑🍆🍑🍆🍑🍆 export const ANAL_FILE_LOCATION = 'tests/script.anal'; export const RUN_CORRECT_OUTPUT = 'Welcome to Analscript!'; export const RUN_WRONG_OUTPUT = 'Welcome to Jurassic Park!'; + +export const COMPILE_CORRECT_OUTPUT = true; +export const FILE_LOCATION = 'tests/hello.anus'; +export const COMPILED_FILE_LOCATION = 'tests/hello.anal'; diff --git a/tests/std.test.js b/tests/std.test.js new file mode 100644 index 0000000..f45eb79 --- /dev/null +++ b/tests/std.test.js @@ -0,0 +1,89 @@ +import fs from 'node:fs'; +import { test, expect, describe } from 'vitest'; + +import { + FILE_LOCATION, + NUMERIC_INPUT, + ANALLIFY_INPUT, + STRINGIFY_INPUT, + RUN_WRONG_OUTPUT, + ANAL_FILE_LOCATION, + EMPTY_STRING_INPUT, + RUN_CORRECT_OUTPUT, + ANALLIFY_WRONG_OUTPUT, + STRINGIFY_WRONG_OUTPUT, + COMPILE_CORRECT_OUTPUT, + COMPILED_FILE_LOCATION, + ANALLIFY_CORRECT_OUTPUT, + STRINGIFY_CORRECT_OUTPUT, +} from './seeds.js'; + +import { + run, + anallify, + stringify, + compile, +} from '../lib/std.js'; +import { ERROR } from '../lib/dictionary.js'; + +describe('Anallify', () => { + test('Encode string to anal', () => { + expect(anallify(ANALLIFY_INPUT)).toBe(ANALLIFY_CORRECT_OUTPUT); + expect(anallify(ANALLIFY_INPUT)).not.toBe(ANALLIFY_WRONG_OUTPUT); + }); + + test('Throw error if argument is not a string', () => { + expect(() => anallify(1)).toThrowError(Error(ERROR.notString)); + }); + + test('Throw error if argument is missing', () => { + expect(() => anallify(EMPTY_STRING_INPUT)).toThrowError( + Error(ERROR.missingArgument), + ); + }); +}); + +describe('Stringify', () => { + test('Decode anal to string', () => { + expect(stringify(STRINGIFY_INPUT)).toBe(STRINGIFY_CORRECT_OUTPUT); + expect(stringify(STRINGIFY_INPUT)).not.toBe(STRINGIFY_WRONG_OUTPUT); + }); + + test('Throw error if argument is not a string', () => { + expect(() => stringify(NUMERIC_INPUT)).toThrowError( + Error(ERROR.notString), + ); + }); + + test('Throw error if argument is missing', () => { + expect(() => stringify(EMPTY_STRING_INPUT)).toThrowError( + Error(ERROR.missingArgument), + ); + }); +}); + +describe('Run', () => { + test('Run .anal file', () => { + expect(run(ANAL_FILE_LOCATION)).toBe(RUN_CORRECT_OUTPUT); + expect(run(ANAL_FILE_LOCATION)).not.toBe(RUN_WRONG_OUTPUT); + }); + + test('Throw error if file is not found', () => { + expect(() => run(EMPTY_STRING_INPUT)).toThrowError( + Error(ERROR.fileNotFound), + ); + }); +}); + +describe('Compile', () => { + test('Compile file to .anal', () => { + expect(compile(FILE_LOCATION)).toBe(COMPILE_CORRECT_OUTPUT); + fs.rmSync(COMPILED_FILE_LOCATION); + }); + + test('Throw error if file is not found', () => { + expect(() => compile(EMPTY_STRING_INPUT)).toThrowError( + Error(ERROR.fileNotFound), + ); + }); +}); diff --git a/tests/stdlib.test.js b/tests/stdlib.test.js deleted file mode 100644 index b25089b..0000000 --- a/tests/stdlib.test.js +++ /dev/null @@ -1,34 +0,0 @@ -import { test, expect } from 'vitest'; - -import { - ANALLIFY_INPUT, - STRINGIFY_INPUT, - RUN_WRONG_OUTPUT, - ANAL_FILE_LOCATION, - RUN_CORRECT_OUTPUT, - ANALLIFY_WRONG_OUTPUT, - STRINGIFY_WRONG_OUTPUT, - ANALLIFY_CORRECT_OUTPUT, - STRINGIFY_CORRECT_OUTPUT, -} from './seeds.js'; - -import { - run, - anallify, - stringify, -} from '../lib/stdlib.js'; - -test('Encode string to anal', () => { - expect(anallify(ANALLIFY_INPUT)).toBe(ANALLIFY_CORRECT_OUTPUT); - expect(anallify(ANALLIFY_INPUT)).not.toBe(ANALLIFY_WRONG_OUTPUT); -}); - -test('Decode anal to string', () => { - expect(stringify(STRINGIFY_INPUT)).toBe(STRINGIFY_CORRECT_OUTPUT); - expect(stringify(STRINGIFY_INPUT)).not.toBe(STRINGIFY_WRONG_OUTPUT); -}); - -test('Run .anal file', () => { - expect(run(ANAL_FILE_LOCATION)).toBe(RUN_CORRECT_OUTPUT); - expect(run(ANAL_FILE_LOCATION)).not.toBe(RUN_WRONG_OUTPUT); -}); diff --git a/tests/utils.test.js b/tests/utils.test.js new file mode 100644 index 0000000..0ee5511 --- /dev/null +++ b/tests/utils.test.js @@ -0,0 +1,16 @@ +import { + vi, + test, + expect, + describe, +} from 'vitest'; + +import { graceful } from '../lib/utils'; + +describe('Graceful', () => { + test('Execute graceful', () => { + const fn = vi.fn(); + graceful(fn); + expect(fn).toBeCalled(); + }); +});