From 6eb471b38b36085552c6a06f3d81aa556f7e5995 Mon Sep 17 00:00:00 2001 From: mateonunez Date: Sun, 30 Jul 2023 11:54:16 +0200 Subject: [PATCH 1/7] chore(stdlib): replace exit with throw Signed-off-by: mateonunez --- lib/stdlib.js | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/lib/stdlib.js b/lib/stdlib.js index 1a0e1c4..52d6035 100644 --- a/lib/stdlib.js +++ b/lib/stdlib.js @@ -6,13 +6,11 @@ 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,8 +52,7 @@ 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); } } @@ -72,7 +67,6 @@ export function compile(file) { fs.writeFileSync(`${filename}.anal`, anallify(contents), { encoding: 'utf-8' }); process.stdout.write(`${SUCCESS.compileSuccess}`); } catch (error) { - process.stderr.write(`${ERROR.fileNotFound}\n`); - process.exit(1); + throw new Error(ERROR.fileNotFound); } } From d7e2d0a5e9cc6fbaec97c4a92bbcfe0b15d4ea38 Mon Sep 17 00:00:00 2001 From: mateonunez Date: Sun, 30 Jul 2023 11:54:30 +0200 Subject: [PATCH 2/7] perf(cli): exit on error Signed-off-by: mateonunez --- cli.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cli.js b/cli.js index 67a9e2a..6006065 100644 --- a/cli.js +++ b/cli.js @@ -33,4 +33,9 @@ function cli() { process.stdout.write(`${output}\n`); } -cli(); +try { + cli(); +} catch (error) { + process.stderr.write(`${error.message}\n`); + process.exit(1); +} From 8c133f4c332772889001bc9e80fb7ef5f090cb16 Mon Sep 17 00:00:00 2001 From: mateonunez Date: Sun, 30 Jul 2023 11:54:44 +0200 Subject: [PATCH 3/7] test(stdlib): full coverage Signed-off-by: mateonunez --- tests/stdlib.test.js | 70 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 10 deletions(-) diff --git a/tests/stdlib.test.js b/tests/stdlib.test.js index b25089b..0bdd8d5 100644 --- a/tests/stdlib.test.js +++ b/tests/stdlib.test.js @@ -1,4 +1,4 @@ -import { test, expect } from 'vitest'; +import { test, expect, describe } from 'vitest'; import { ANALLIFY_INPUT, @@ -16,19 +16,69 @@ import { run, anallify, stringify, + compile, } from '../lib/stdlib.js'; +import { ERROR } from '../lib/dictionary.js'; -test('Encode string to anal', () => { - expect(anallify(ANALLIFY_INPUT)).toBe(ANALLIFY_CORRECT_OUTPUT); - expect(anallify(ANALLIFY_INPUT)).not.toBe(ANALLIFY_WRONG_OUTPUT); +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('')).toThrowError(Error(ERROR.missingArgument)); + }); }); -test('Decode anal to string', () => { - expect(stringify(STRINGIFY_INPUT)).toBe(STRINGIFY_CORRECT_OUTPUT); - expect(stringify(STRINGIFY_INPUT)).not.toBe(STRINGIFY_WRONG_OUTPUT); +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('Decode with correct chars', () => { + const ANAL_CHARACTERS = 'anal'; + const charCodeA = STRINGIFY_INPUT.length; + const charCodeB = STRINGIFY_INPUT.length * 2; + + const anal = `${ANAL_CHARACTERS.repeat(charCodeA)} ${ANAL_CHARACTERS.repeat(charCodeB)}`; + const result = stringify(anal); + + expect(result).toBe(String.fromCharCode(charCodeA) + String.fromCharCode(charCodeB)); + }); + + test('Throw error if argument is not a string', () => { + expect(() => stringify(1)).toThrowError(Error(ERROR.notString)); + }); + + test('Throw error if argument is missing', () => { + expect(() => stringify('')).toThrowError(Error(ERROR.missingArgument)); + }); }); -test('Run .anal file', () => { - expect(run(ANAL_FILE_LOCATION)).toBe(RUN_CORRECT_OUTPUT); - expect(run(ANAL_FILE_LOCATION)).not.toBe(RUN_WRONG_OUTPUT); +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('')).toThrowError(Error(ERROR.fileNotFound)); + }); +}); + +describe('Compile', () => { + test('Compile .anal file', () => { + expect(compile(ANAL_FILE_LOCATION)).toBe(RUN_CORRECT_OUTPUT); + expect(compile(ANAL_FILE_LOCATION)).not.toBe(RUN_WRONG_OUTPUT); + }); + + test('Throw error if file is not found', () => { + expect(() => run('')).toThrowError(Error(ERROR.fileNotFound)); + }); }); From eaea48124b24885b5f2d5e552b881c1349e91df5 Mon Sep 17 00:00:00 2001 From: mateonunez Date: Sun, 30 Jul 2023 12:26:46 +0200 Subject: [PATCH 4/7] chore(stdlib): remove useful compile test Signed-off-by: mateonunez --- tests/stdlib.test.js | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/tests/stdlib.test.js b/tests/stdlib.test.js index 0bdd8d5..343fdd7 100644 --- a/tests/stdlib.test.js +++ b/tests/stdlib.test.js @@ -1,4 +1,4 @@ -import { test, expect, describe } from 'vitest'; +import { test, expect, describe, is } from 'vitest'; import { ANALLIFY_INPUT, @@ -42,13 +42,13 @@ describe('Stringify', () => { }); test('Decode with correct chars', () => { - const ANAL_CHARACTERS = 'anal'; - const charCodeA = STRINGIFY_INPUT.length; - const charCodeB = STRINGIFY_INPUT.length * 2; + const ANAL_CHARACTERS = ''; + const charCodeA = ANAL_CHARACTERS.length; + const charCodeB = ANAL_CHARACTERS.length * 2; const anal = `${ANAL_CHARACTERS.repeat(charCodeA)} ${ANAL_CHARACTERS.repeat(charCodeB)}`; - const result = stringify(anal); + const result = stringify(anal); expect(result).toBe(String.fromCharCode(charCodeA) + String.fromCharCode(charCodeB)); }); @@ -73,12 +73,7 @@ describe('Run', () => { }); describe('Compile', () => { - test('Compile .anal file', () => { - expect(compile(ANAL_FILE_LOCATION)).toBe(RUN_CORRECT_OUTPUT); - expect(compile(ANAL_FILE_LOCATION)).not.toBe(RUN_WRONG_OUTPUT); - }); - test('Throw error if file is not found', () => { - expect(() => run('')).toThrowError(Error(ERROR.fileNotFound)); + expect(() => compile('')).toThrowError(Error(ERROR.fileNotFound)); }); }); From 059f3f3cfd06ef32e3388c306953312b5adabfc8 Mon Sep 17 00:00:00 2001 From: Airscript Date: Sun, 30 Jul 2023 15:25:39 +0200 Subject: [PATCH 5/7] test: add compile's functional test --- analscript.js | 2 +- cli.js | 10 ++---- lib/{stdlib.js => std.js} | 5 ++- lib/utils.js | 11 ++++++- tests/hello.anus | 1 + tests/seeds.js | 7 ++++ tests/{stdlib.test.js => std.test.js} | 46 ++++++++++++++++----------- 7 files changed, 52 insertions(+), 30 deletions(-) rename lib/{stdlib.js => std.js} (97%) create mode 100644 tests/hello.anus rename tests/{stdlib.test.js => std.test.js} (63%) 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 6006065..bd4250a 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,9 +34,4 @@ function cli() { process.stdout.write(`${output}\n`); } -try { - cli(); -} catch (error) { - process.stderr.write(`${error.message}\n`); - process.exit(1); -} +graceful(cli()); diff --git a/lib/stdlib.js b/lib/std.js similarity index 97% rename from lib/stdlib.js rename to lib/std.js index 52d6035..505049f 100644 --- a/lib/stdlib.js +++ b/lib/std.js @@ -1,6 +1,6 @@ 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'; @@ -59,13 +59,12 @@ export function run(file) { 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) { 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/stdlib.test.js b/tests/std.test.js similarity index 63% rename from tests/stdlib.test.js rename to tests/std.test.js index 343fdd7..f45eb79 100644 --- a/tests/stdlib.test.js +++ b/tests/std.test.js @@ -1,13 +1,19 @@ -import { test, expect, describe, is } from 'vitest'; +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'; @@ -17,7 +23,7 @@ import { anallify, stringify, compile, -} from '../lib/stdlib.js'; +} from '../lib/std.js'; import { ERROR } from '../lib/dictionary.js'; describe('Anallify', () => { @@ -31,7 +37,9 @@ describe('Anallify', () => { }); test('Throw error if argument is missing', () => { - expect(() => anallify('')).toThrowError(Error(ERROR.missingArgument)); + expect(() => anallify(EMPTY_STRING_INPUT)).toThrowError( + Error(ERROR.missingArgument), + ); }); }); @@ -41,23 +49,16 @@ describe('Stringify', () => { expect(stringify(STRINGIFY_INPUT)).not.toBe(STRINGIFY_WRONG_OUTPUT); }); - test('Decode with correct chars', () => { - const ANAL_CHARACTERS = ''; - const charCodeA = ANAL_CHARACTERS.length; - const charCodeB = ANAL_CHARACTERS.length * 2; - - const anal = `${ANAL_CHARACTERS.repeat(charCodeA)} ${ANAL_CHARACTERS.repeat(charCodeB)}`; - - const result = stringify(anal); - expect(result).toBe(String.fromCharCode(charCodeA) + String.fromCharCode(charCodeB)); - }); - test('Throw error if argument is not a string', () => { - expect(() => stringify(1)).toThrowError(Error(ERROR.notString)); + expect(() => stringify(NUMERIC_INPUT)).toThrowError( + Error(ERROR.notString), + ); }); test('Throw error if argument is missing', () => { - expect(() => stringify('')).toThrowError(Error(ERROR.missingArgument)); + expect(() => stringify(EMPTY_STRING_INPUT)).toThrowError( + Error(ERROR.missingArgument), + ); }); }); @@ -68,12 +69,21 @@ describe('Run', () => { }); test('Throw error if file is not found', () => { - expect(() => run('')).toThrowError(Error(ERROR.fileNotFound)); + 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('')).toThrowError(Error(ERROR.fileNotFound)); + expect(() => compile(EMPTY_STRING_INPUT)).toThrowError( + Error(ERROR.fileNotFound), + ); }); }); From f55449701aa2e05c96622da77423fcd59b7da184 Mon Sep 17 00:00:00 2001 From: Airscript Date: Sun, 30 Jul 2023 15:29:40 +0200 Subject: [PATCH 6/7] refactor: remove cli function invocation in graceful --- cli.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli.js b/cli.js index bd4250a..6f21ee8 100644 --- a/cli.js +++ b/cli.js @@ -34,4 +34,4 @@ function cli() { process.stdout.write(`${output}\n`); } -graceful(cli()); +graceful(cli); From 425542758e9ba4bf31e49800c2daf2672764f5a6 Mon Sep 17 00:00:00 2001 From: Airscript Date: Sun, 30 Jul 2023 15:43:45 +0200 Subject: [PATCH 7/7] test: add utils test suite --- tests/utils.test.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 tests/utils.test.js 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(); + }); +});