From b5724418e9ad506080f96447b0084946b6fa0b6a Mon Sep 17 00:00:00 2001 From: lasercata <67599917+lasercata@users.noreply.github.com> Date: Wed, 12 Nov 2025 01:28:08 +0100 Subject: [PATCH 01/12] Preparing code for tests + better anasy doc --- src/anasyn.py | 52 +++++++++++++++++++++++++----------------------- src/parser_ui.py | 17 +++++++++++++--- 2 files changed, 41 insertions(+), 28 deletions(-) diff --git a/src/anasyn.py b/src/anasyn.py index 6acd000..23d1074 100644 --- a/src/anasyn.py +++ b/src/anasyn.py @@ -970,6 +970,9 @@ def compile(self, show_ident_table: bool = False) -> str: Args: :show_ident_table: if True, prints the identifier table. + + Output: + The compiled instructions ''' try: @@ -988,54 +991,53 @@ def compile(self, show_ident_table: bool = False) -> str: ######################################################################## -def main_anasyn(file_content: str, fn_out: str, show_ident_table: bool, debug_lvl): +def main_anasyn(file_content: str, fn_out: str, show_ident_table: bool, debug_lvl) -> str: ''' - TODO: Docstring for main_anasyn. + Main function for the syntax analysis, and generation of the compiled instructions. + + In: + - file_content: the content of the file (the NNP program) ; + - fn_out: the name of the potential output file. If "", prints to stdout instead ; + - show_ident_table: if true, displays the ident table ; + - debug_lvl: indicates the logging level. - - file_content : the content of the file (the NNP program) ; - - fn_out : the name of the potential output file. If "", prints to stdout instead ; - - show_ident_table : if true, displays the ident table ; - - debug_lvl : indicates the logging level. + Out: + The generated compiled instructions. + + Throws: + SyntaxError if there is a syntax error + FileNotFoundError if there is a problem to open the output file + RuntimeError if no instructions are generated ''' #---Run the analysis G = Grammar(file_content, debug_lvl) - try: - instructions_str = G.compile(show_ident_table) + instructions_str = G.compile(show_ident_table) - except SyntaxError as err: - print(f'Syntax error: {err}') - return + if instructions_str == '': + raise RuntimeError('No instruction generated!') #---Write to file / stdout #-Select file or stdout if fn_out != '': - try: - output_file = open(fn_out, 'w') - - except: - print("Error: can't open output file!") - return + output_file = open(fn_out, 'w') else: output_file = sys.stdout #-Write - if instructions_str != '': - output_file.write(instructions_str) - - if debug_lvl == logging.DEBUG: - print(f'Output to file: "{fn_out}"') + output_file.write(instructions_str) - else: - if debug_lvl == logging.DEBUG: - print('No instruction generated!') + if debug_lvl == logging.DEBUG: + print(f'Output to file: "{fn_out}"') #-Close file if fn_out != '': output_file.close() + return instructions_str + ######################################################################## diff --git a/src/parser_ui.py b/src/parser_ui.py index aa3317f..fade440 100644 --- a/src/parser_ui.py +++ b/src/parser_ui.py @@ -49,9 +49,9 @@ def __init__(self): #---Init examples = 'Examples :' examples += '\n\t./main.py c -h' - examples += '\n\t./main.py c tests/nna/correct1.nno -o correct1.obj' + examples += '\n\t./main.py c nn_programs/nna/correct1.nno -o correct1.obj' examples += '\n\t./main.py r correct1.obj' - examples += '\n\t./main.py r tests/nna/correct1.nno -c' + examples += '\n\t./main.py r nn_programs/nna/correct1.nno -c' self.parser = argparse.ArgumentParser( # prog='anasyn', @@ -190,7 +190,17 @@ def parse_compile(self, args): src_code = get_file_content(args.inputfile[0], self.parser_c) - main_anasyn(src_code, args.outputfile, args.show_ident_table, args.debug) + try: + main_anasyn(src_code, args.outputfile, args.show_ident_table, args.debug) + + except SyntaxError as err: + print(f'Syntax error: {err}') + + except FileNotFoundError: + print("Error: can't open output file!") + + except RuntimeError as err: + print(f'Error: {err}') def parse_run(self, args): '''Parse the arguments for the `compile` mode''' @@ -202,6 +212,7 @@ def parse_run(self, args): try: instructions = G.compile() print(instructions) + except SyntaxError as err: # self.parser_r.error('syntax error: ' + str(err)) print('Syntax error: ' + str(err)) From b5b2a3f101e02212d5471554a107db524440c0c7 Mon Sep 17 00:00:00 2001 From: lasercata <67599917+lasercata@users.noreply.github.com> Date: Wed, 12 Nov 2025 01:30:58 +0100 Subject: [PATCH 02/12] Renaming `tests` to `nn_programs` --- .gitignore | 4 +++- README.md | 6 +++--- {tests => nn_programs}/convert_encoding.sh | 0 {tests => nn_programs}/nna/correct1.nno | 0 {tests => nn_programs}/nna/correct2.nno | 0 {tests => nn_programs}/nna/correct3.nno | 0 {tests => nn_programs}/nna/correct4.nno | 0 {tests => nn_programs}/nna/error1.nno | 0 {tests => nn_programs}/nna/error2.nno | 0 {tests => nn_programs}/nna/error3.nno | 0 {tests => nn_programs}/nna/error4.nno | 0 {tests => nn_programs}/nna/error5.nno | 0 {tests => nn_programs}/nna/error6.nno | 0 {tests => nn_programs}/nna/error7.nno | 0 {tests => nn_programs}/nna/expected/correct1.nno.expected | 0 {tests => nn_programs}/nna/expected/correct2.nno.expected | 0 {tests => nn_programs}/nna/expected/correct3.nno.expected | 0 .../nna/expected/correct3_alt.nno.expected | 0 {tests => nn_programs}/nna/expected/correct4.nno.expected | 0 {tests => nn_programs}/nnp/correct1.nno | 0 {tests => nn_programs}/nnp/correct2.nno | 0 {tests => nn_programs}/nnp/correct3.nno | 0 {tests => nn_programs}/nnp/correct4.nno | 0 {tests => nn_programs}/nnp/correct5.nno | 0 {tests => nn_programs}/nnp/expected/correct1.nno.expected | 0 {tests => nn_programs}/nnp/expected/correct2.nno.expected | 0 {tests => nn_programs}/nnp/expected/correct3.nno.expected | 0 {tests => nn_programs}/nnp/expected/correct4.nno.expected | 0 {tests => nn_programs}/nnp/expected/correct5.nno.expected | 0 29 files changed, 6 insertions(+), 4 deletions(-) rename {tests => nn_programs}/convert_encoding.sh (100%) rename {tests => nn_programs}/nna/correct1.nno (100%) rename {tests => nn_programs}/nna/correct2.nno (100%) rename {tests => nn_programs}/nna/correct3.nno (100%) rename {tests => nn_programs}/nna/correct4.nno (100%) rename {tests => nn_programs}/nna/error1.nno (100%) rename {tests => nn_programs}/nna/error2.nno (100%) rename {tests => nn_programs}/nna/error3.nno (100%) rename {tests => nn_programs}/nna/error4.nno (100%) rename {tests => nn_programs}/nna/error5.nno (100%) rename {tests => nn_programs}/nna/error6.nno (100%) rename {tests => nn_programs}/nna/error7.nno (100%) rename {tests => nn_programs}/nna/expected/correct1.nno.expected (100%) rename {tests => nn_programs}/nna/expected/correct2.nno.expected (100%) rename {tests => nn_programs}/nna/expected/correct3.nno.expected (100%) rename {tests => nn_programs}/nna/expected/correct3_alt.nno.expected (100%) rename {tests => nn_programs}/nna/expected/correct4.nno.expected (100%) rename {tests => nn_programs}/nnp/correct1.nno (100%) rename {tests => nn_programs}/nnp/correct2.nno (100%) rename {tests => nn_programs}/nnp/correct3.nno (100%) rename {tests => nn_programs}/nnp/correct4.nno (100%) rename {tests => nn_programs}/nnp/correct5.nno (100%) rename {tests => nn_programs}/nnp/expected/correct1.nno.expected (100%) rename {tests => nn_programs}/nnp/expected/correct2.nno.expected (100%) rename {tests => nn_programs}/nnp/expected/correct3.nno.expected (100%) rename {tests => nn_programs}/nnp/expected/correct4.nno.expected (100%) rename {tests => nn_programs}/nnp/expected/correct5.nno.expected (100%) diff --git a/.gitignore b/.gitignore index d2e529e..8f4008a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ *.pyc __pycache__/ -.idea/ \ No newline at end of file +.idea/ + +Projet Compilation.pdf diff --git a/README.md b/README.md index 0da5dbf..a2a45e5 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ A simple tool to **analyze**, **compile**, and **run** NNP programs. │   ├── parser_ui.py │   └── utils.py │ -└── tests/ +└── nn_programs/ ├── nna/ │   ├── correct1.nno │   ├── ... @@ -107,9 +107,9 @@ options: ```bash ./main.py c -h -./main.py c tests/nna/correct1.nno -o correct1.obj +./main.py c nn_programs/nna/correct1.nno -o correct1.obj ./main.py r correct1.obj -./main.py r tests/nna/correct1.nno -c +./main.py r nn_programs/nna/correct1.nno -c ``` --- diff --git a/tests/convert_encoding.sh b/nn_programs/convert_encoding.sh similarity index 100% rename from tests/convert_encoding.sh rename to nn_programs/convert_encoding.sh diff --git a/tests/nna/correct1.nno b/nn_programs/nna/correct1.nno similarity index 100% rename from tests/nna/correct1.nno rename to nn_programs/nna/correct1.nno diff --git a/tests/nna/correct2.nno b/nn_programs/nna/correct2.nno similarity index 100% rename from tests/nna/correct2.nno rename to nn_programs/nna/correct2.nno diff --git a/tests/nna/correct3.nno b/nn_programs/nna/correct3.nno similarity index 100% rename from tests/nna/correct3.nno rename to nn_programs/nna/correct3.nno diff --git a/tests/nna/correct4.nno b/nn_programs/nna/correct4.nno similarity index 100% rename from tests/nna/correct4.nno rename to nn_programs/nna/correct4.nno diff --git a/tests/nna/error1.nno b/nn_programs/nna/error1.nno similarity index 100% rename from tests/nna/error1.nno rename to nn_programs/nna/error1.nno diff --git a/tests/nna/error2.nno b/nn_programs/nna/error2.nno similarity index 100% rename from tests/nna/error2.nno rename to nn_programs/nna/error2.nno diff --git a/tests/nna/error3.nno b/nn_programs/nna/error3.nno similarity index 100% rename from tests/nna/error3.nno rename to nn_programs/nna/error3.nno diff --git a/tests/nna/error4.nno b/nn_programs/nna/error4.nno similarity index 100% rename from tests/nna/error4.nno rename to nn_programs/nna/error4.nno diff --git a/tests/nna/error5.nno b/nn_programs/nna/error5.nno similarity index 100% rename from tests/nna/error5.nno rename to nn_programs/nna/error5.nno diff --git a/tests/nna/error6.nno b/nn_programs/nna/error6.nno similarity index 100% rename from tests/nna/error6.nno rename to nn_programs/nna/error6.nno diff --git a/tests/nna/error7.nno b/nn_programs/nna/error7.nno similarity index 100% rename from tests/nna/error7.nno rename to nn_programs/nna/error7.nno diff --git a/tests/nna/expected/correct1.nno.expected b/nn_programs/nna/expected/correct1.nno.expected similarity index 100% rename from tests/nna/expected/correct1.nno.expected rename to nn_programs/nna/expected/correct1.nno.expected diff --git a/tests/nna/expected/correct2.nno.expected b/nn_programs/nna/expected/correct2.nno.expected similarity index 100% rename from tests/nna/expected/correct2.nno.expected rename to nn_programs/nna/expected/correct2.nno.expected diff --git a/tests/nna/expected/correct3.nno.expected b/nn_programs/nna/expected/correct3.nno.expected similarity index 100% rename from tests/nna/expected/correct3.nno.expected rename to nn_programs/nna/expected/correct3.nno.expected diff --git a/tests/nna/expected/correct3_alt.nno.expected b/nn_programs/nna/expected/correct3_alt.nno.expected similarity index 100% rename from tests/nna/expected/correct3_alt.nno.expected rename to nn_programs/nna/expected/correct3_alt.nno.expected diff --git a/tests/nna/expected/correct4.nno.expected b/nn_programs/nna/expected/correct4.nno.expected similarity index 100% rename from tests/nna/expected/correct4.nno.expected rename to nn_programs/nna/expected/correct4.nno.expected diff --git a/tests/nnp/correct1.nno b/nn_programs/nnp/correct1.nno similarity index 100% rename from tests/nnp/correct1.nno rename to nn_programs/nnp/correct1.nno diff --git a/tests/nnp/correct2.nno b/nn_programs/nnp/correct2.nno similarity index 100% rename from tests/nnp/correct2.nno rename to nn_programs/nnp/correct2.nno diff --git a/tests/nnp/correct3.nno b/nn_programs/nnp/correct3.nno similarity index 100% rename from tests/nnp/correct3.nno rename to nn_programs/nnp/correct3.nno diff --git a/tests/nnp/correct4.nno b/nn_programs/nnp/correct4.nno similarity index 100% rename from tests/nnp/correct4.nno rename to nn_programs/nnp/correct4.nno diff --git a/tests/nnp/correct5.nno b/nn_programs/nnp/correct5.nno similarity index 100% rename from tests/nnp/correct5.nno rename to nn_programs/nnp/correct5.nno diff --git a/tests/nnp/expected/correct1.nno.expected b/nn_programs/nnp/expected/correct1.nno.expected similarity index 100% rename from tests/nnp/expected/correct1.nno.expected rename to nn_programs/nnp/expected/correct1.nno.expected diff --git a/tests/nnp/expected/correct2.nno.expected b/nn_programs/nnp/expected/correct2.nno.expected similarity index 100% rename from tests/nnp/expected/correct2.nno.expected rename to nn_programs/nnp/expected/correct2.nno.expected diff --git a/tests/nnp/expected/correct3.nno.expected b/nn_programs/nnp/expected/correct3.nno.expected similarity index 100% rename from tests/nnp/expected/correct3.nno.expected rename to nn_programs/nnp/expected/correct3.nno.expected diff --git a/tests/nnp/expected/correct4.nno.expected b/nn_programs/nnp/expected/correct4.nno.expected similarity index 100% rename from tests/nnp/expected/correct4.nno.expected rename to nn_programs/nnp/expected/correct4.nno.expected diff --git a/tests/nnp/expected/correct5.nno.expected b/nn_programs/nnp/expected/correct5.nno.expected similarity index 100% rename from tests/nnp/expected/correct5.nno.expected rename to nn_programs/nnp/expected/correct5.nno.expected From b3f639de4ee16ccf1b6fe2e75002c0231934a986 Mon Sep 17 00:00:00 2001 From: lasercata <67599917+lasercata@users.noreply.github.com> Date: Wed, 12 Nov 2025 02:49:00 +0100 Subject: [PATCH 03/12] Adding pytest tests --- .gitignore | 2 + README.md | 13 +++++ .../nnp/expected/correct1.nno.expected | 4 +- .../nnp/expected/correct2.nno.expected | 4 +- .../nnp/expected/correct3.nno.expected | 4 +- .../nnp/expected/correct4.nno.expected | 6 +-- .../nnp/expected/correct5.nno.expected | 4 +- src/anasyn.py | 2 +- tests/test_anasyn.py | 50 +++++++++++++++++++ 9 files changed, 77 insertions(+), 12 deletions(-) create mode 100644 tests/test_anasyn.py diff --git a/.gitignore b/.gitignore index 8f4008a..8c67949 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,6 @@ __pycache__/ .idea/ +.pytest_cache + Projet Compilation.pdf diff --git a/README.md b/README.md index a2a45e5..7b369e8 100644 --- a/README.md +++ b/README.md @@ -113,3 +113,16 @@ options: ``` --- + +### Run tests +To run all the tests: +``` +python -m pytest +``` + +To have the details: +``` +python -m pytest -vv +``` + +--- diff --git a/nn_programs/nnp/expected/correct1.nno.expected b/nn_programs/nnp/expected/correct1.nno.expected index 0846176..c154cc1 100644 --- a/nn_programs/nnp/expected/correct1.nno.expected +++ b/nn_programs/nnp/expected/correct1.nno.expected @@ -37,7 +37,7 @@ tra(7) retourProc() reserver(3) reserverBloc() -traStat(3,0) +traStat(3, 0) empiler(0) get() empiler(1) @@ -49,4 +49,4 @@ affectation() empiler(1) valeurPile() put() -finProg() \ No newline at end of file +finProg() diff --git a/nn_programs/nnp/expected/correct2.nno.expected b/nn_programs/nnp/expected/correct2.nno.expected index da7eafb..43a9968 100644 --- a/nn_programs/nnp/expected/correct2.nno.expected +++ b/nn_programs/nnp/expected/correct2.nno.expected @@ -12,7 +12,7 @@ reserver(3) reserverBloc() empiler(3) empiler(4) -traStat(3,2) +traStat(3, 2) empiler(0) get() empiler(1) @@ -24,4 +24,4 @@ affectation() empiler(1) valeurPile() put() -finProg() \ No newline at end of file +finProg() diff --git a/nn_programs/nnp/expected/correct3.nno.expected b/nn_programs/nnp/expected/correct3.nno.expected index 0090385..f2a4bf0 100644 --- a/nn_programs/nnp/expected/correct3.nno.expected +++ b/nn_programs/nnp/expected/correct3.nno.expected @@ -7,6 +7,6 @@ mult() retourFonct() reserverBloc() empiler(7) -traStat(3,1) +traStat(3, 1) put() -finProg() \ No newline at end of file +finProg() diff --git a/nn_programs/nnp/expected/correct4.nno.expected b/nn_programs/nnp/expected/correct4.nno.expected index 8dc15b5..2290ee2 100644 --- a/nn_programs/nnp/expected/correct4.nno.expected +++ b/nn_programs/nnp/expected/correct4.nno.expected @@ -15,11 +15,11 @@ empilerAd(0) valeurPile() empiler(1) sous() -traStat(3,1) +traStat(3, 1) mult() retourFonct() reserverBloc() empiler(3) -traStat(3,1) +traStat(3, 1) put() -finProg() \ No newline at end of file +finProg() diff --git a/nn_programs/nnp/expected/correct5.nno.expected b/nn_programs/nnp/expected/correct5.nno.expected index 48b3f16..53fe58a 100644 --- a/nn_programs/nnp/expected/correct5.nno.expected +++ b/nn_programs/nnp/expected/correct5.nno.expected @@ -16,5 +16,5 @@ reserverBloc() empiler(2) empiler(0) valeurPile() -traStat(3,2) -finProg() \ No newline at end of file +traStat(3, 2) +finProg() diff --git a/src/anasyn.py b/src/anasyn.py index 23d1074..dad8587 100644 --- a/src/anasyn.py +++ b/src/anasyn.py @@ -991,7 +991,7 @@ def compile(self, show_ident_table: bool = False) -> str: ######################################################################## -def main_anasyn(file_content: str, fn_out: str, show_ident_table: bool, debug_lvl) -> str: +def main_anasyn(file_content: str, fn_out: str = '', show_ident_table: bool = False, debug_lvl=logging.INFO) -> str: ''' Main function for the syntax analysis, and generation of the compiled instructions. diff --git a/tests/test_anasyn.py b/tests/test_anasyn.py new file mode 100644 index 0000000..60ae4ce --- /dev/null +++ b/tests/test_anasyn.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +##-Imports +#---General +from os import listdir + +import pytest + +#---Project +from src.anasyn import main_anasyn + + +##-Init +nna_path = 'nn_programs/nna/' +nnp_path = 'nn_programs/nnp/' + +files_nna = sorted([f for f in listdir(nna_path) if 'correct' in f]) +files_nnp = sorted([f for f in listdir(nnp_path) if 'correct' in f]) + +nna_tuples = [('nna', nna_path + src, nna_path + 'expected/' + src + '.expected') for src in files_nna] +nnp_tuples = [('nnp', nnp_path + src, nnp_path + 'expected/' + src + '.expected') for src in files_nnp] + +error_programs = sorted([nna_path + f for f in listdir(nna_path) if 'error' in f]) + + +##-Tests +class TestAnasyn: + '''Tests `main_anasyn`''' + + @pytest.mark.parametrize('nn_type, src_fn, expected_compiled_fn', nna_tuples + nnp_tuples) + def test_correct(self, nn_type: str, src_fn: str, expected_compiled_fn: str): + '''Tests to compile the correct programs''' + + with open(src_fn) as src_file: + with open(expected_compiled_fn) as compiled_file: + src = src_file.read() + compiled = compiled_file.read().strip() + + assert main_anasyn(src).strip() == compiled, f'Failed for file {nn_type}/"{src_fn}"' + + @pytest.mark.parametrize('src_fn', error_programs) + def test_error(self, src_fn: str): + '''Tests to compile the programs with errors''' + + with open(src_fn) as src_file: + src = src_file.read() + + with pytest.raises(SyntaxError): + main_anasyn(src).strip() From c1734c69894799c41e3033dc293a5db5f8fbff52 Mon Sep 17 00:00:00 2001 From: lasercata <67599917+lasercata@users.noreply.github.com> Date: Wed, 12 Nov 2025 02:49:15 +0100 Subject: [PATCH 04/12] Adding github workflow --- .github/workflows/python-tests.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/python-tests.yml diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml new file mode 100644 index 0000000..df083ff --- /dev/null +++ b/.github/workflows/python-tests.yml @@ -0,0 +1,28 @@ +name: Python tests + +on: + push: + branches: [ "main", "*" ] + pull_request: + branches: [ "main", "*" ] + +jobs: + test: + runs-on: ubuntu-lastest + steps: + - uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.12" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install pytest + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + + - name: Test with pytest + run: | + pytest From 8c74dee283a116aed76404dc228ff8918789eb79 Mon Sep 17 00:00:00 2001 From: lasercata <67599917+lasercata@users.noreply.github.com> Date: Wed, 12 Nov 2025 08:37:51 +0100 Subject: [PATCH 05/12] Trying to fix the workflow for tests --- .github/workflows/python-tests.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index df083ff..cd04988 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -2,15 +2,17 @@ name: Python tests on: push: - branches: [ "main", "*" ] + branches: + - '**' pull_request: - branches: [ "main", "*" ] + branches: [ "main" ] jobs: test: runs-on: ubuntu-lastest steps: - - uses: actions/checkout@v3 + - name: "Checkout" + uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v4 From fb13857cf96914a924c0b229cee669adfe1cc8a6 Mon Sep 17 00:00:00 2001 From: lasercata <67599917+lasercata@users.noreply.github.com> Date: Wed, 12 Nov 2025 09:38:30 +0100 Subject: [PATCH 06/12] Trying to fix the workflow for tests --- .github/workflows/python-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index cd04988..6db5bfc 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -15,7 +15,7 @@ jobs: uses: actions/checkout@v3 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v2 with: python-version: "3.12" From e0e21af15c2a99800e4ec493c3b24a12321c3061 Mon Sep 17 00:00:00 2001 From: lasercata <67599917+lasercata@users.noreply.github.com> Date: Wed, 12 Nov 2025 09:41:36 +0100 Subject: [PATCH 07/12] Fix the workflow for tests --- .github/workflows/python-tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index 6db5bfc..027babb 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -9,13 +9,13 @@ on: jobs: test: - runs-on: ubuntu-lastest + runs-on: ubuntu-latest steps: - name: "Checkout" uses: actions/checkout@v3 - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: "3.12" From 058c980de62074bbcd65a756351c506f04c72d97 Mon Sep 17 00:00:00 2001 From: lasercata <67599917+lasercata@users.noreply.github.com> Date: Wed, 12 Nov 2025 09:49:29 +0100 Subject: [PATCH 08/12] Adding needed file for pytest to run --- tests/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/__init__.py diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 From 528fecac5f0df8f39b53fb6433b1ef7a5b1d1048 Mon Sep 17 00:00:00 2001 From: lasercata <67599917+lasercata@users.noreply.github.com> Date: Wed, 12 Nov 2025 10:06:11 +0100 Subject: [PATCH 09/12] Workflow now run only on branch main (push & PR) --- .github/workflows/python-tests.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index 027babb..ed75c0e 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -2,22 +2,21 @@ name: Python tests on: push: - branches: - - '**' + branches: [ 'main' ] pull_request: - branches: [ "main" ] + branches: [ 'main' ] jobs: test: runs-on: ubuntu-latest steps: - - name: "Checkout" + - name: 'Checkout' uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v4 with: - python-version: "3.12" + python-version: '3.12' - name: Install dependencies run: | From 70fa5215aa71942e4c07ffaf0ae454d03ce6f275 Mon Sep 17 00:00:00 2001 From: lasercata <67599917+lasercata@users.noreply.github.com> Date: Wed, 12 Nov 2025 10:10:33 +0100 Subject: [PATCH 10/12] test_anasyn: remove useless class --- tests/test_anasyn.py | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/tests/test_anasyn.py b/tests/test_anasyn.py index 60ae4ce..f50cfff 100644 --- a/tests/test_anasyn.py +++ b/tests/test_anasyn.py @@ -18,33 +18,30 @@ files_nna = sorted([f for f in listdir(nna_path) if 'correct' in f]) files_nnp = sorted([f for f in listdir(nnp_path) if 'correct' in f]) -nna_tuples = [('nna', nna_path + src, nna_path + 'expected/' + src + '.expected') for src in files_nna] -nnp_tuples = [('nnp', nnp_path + src, nnp_path + 'expected/' + src + '.expected') for src in files_nnp] +nna_tuples = [(nna_path + src, nna_path + 'expected/' + src + '.expected') for src in files_nna] +nnp_tuples = [(nnp_path + src, nnp_path + 'expected/' + src + '.expected') for src in files_nnp] error_programs = sorted([nna_path + f for f in listdir(nna_path) if 'error' in f]) ##-Tests -class TestAnasyn: - '''Tests `main_anasyn`''' +@pytest.mark.parametrize('src_fn, expected_compiled_fn', nna_tuples + nnp_tuples) +def test_correct(src_fn: str, expected_compiled_fn: str): + '''Tests to compile the correct programs''' - @pytest.mark.parametrize('nn_type, src_fn, expected_compiled_fn', nna_tuples + nnp_tuples) - def test_correct(self, nn_type: str, src_fn: str, expected_compiled_fn: str): - '''Tests to compile the correct programs''' - - with open(src_fn) as src_file: - with open(expected_compiled_fn) as compiled_file: - src = src_file.read() - compiled = compiled_file.read().strip() + with open(src_fn) as src_file: + with open(expected_compiled_fn) as compiled_file: + src = src_file.read() + compiled = compiled_file.read().strip() - assert main_anasyn(src).strip() == compiled, f'Failed for file {nn_type}/"{src_fn}"' + assert main_anasyn(src).strip() == compiled, f'Failed for file "{src_fn}"' - @pytest.mark.parametrize('src_fn', error_programs) - def test_error(self, src_fn: str): - '''Tests to compile the programs with errors''' +@pytest.mark.parametrize('src_fn', error_programs) +def test_error(src_fn: str): + '''Tests to compile the programs with errors''' - with open(src_fn) as src_file: - src = src_file.read() + with open(src_fn) as src_file: + src = src_file.read() - with pytest.raises(SyntaxError): - main_anasyn(src).strip() + with pytest.raises(SyntaxError): + main_anasyn(src).strip() From da8b05362a4f2b18e54930713aa30e0dc52e27b8 Mon Sep 17 00:00:00 2001 From: lasercata <67599917+lasercata@users.noreply.github.com> Date: Wed, 12 Nov 2025 12:22:48 +0100 Subject: [PATCH 11/12] Adding tests for the interpretor --- tests/test_vm.py | 106 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 tests/test_vm.py diff --git a/tests/test_vm.py b/tests/test_vm.py new file mode 100644 index 0000000..a3e7ce4 --- /dev/null +++ b/tests/test_vm.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +##-Imports +#---General +from subprocess import run + +import pytest + +#---Project +# from src.anasyn import main_anasyn + + +##-Init +test_expected_values = [ + #nn_type, nb, input, expected_output + ('nna', 1, (), '1\n2\n3\n4\n'*4), + + ('nna', 2, (), 1), + + ('nna', 3, (0,), -34), + ('nna', 3, (2,), -34), + ('nna', 3, (20,), 20*3), + ('nna', 3, (18,), ''), + + ('nna', 4, (0,), 0), + ('nna', 4, (1, 0,), 0), + ('nna', 4, (1, 1, 1, 1, 0,), 0), + ('nna', 4, (2, 0,), 1), + ('nna', 4, (2, 2, 0,), 2), + ('nna', 4, (2, 2, 2, 0,), 3), + ('nna', 4, (1, 2, 0,), 1), + ('nna', 4, (2, 1, 0,), 1), + ('nna', 4, (2, 1, 8, 0,), 2), + ('nna', 4, (2, 4, 6, 8, 10, 12, 14, 16, 0,), 8), + + ('nnp', 1, (0,), '1\n2\n3\n4\n'*4 + '>1'), # there is '>' because it is the user prompt + ('nnp', 1, (1,), '1\n2\n3\n4\n'*4 + '>2'), + ('nnp', 1, (-1,), '1\n2\n3\n4\n'*4 + '>0'), + + ('nnp', 2, (0,), '3\n4\n' + '>1'), # there is '>' because it is the user prompt + ('nnp', 2, (1,), '3\n4\n' + '>2'), + ('nnp', 2, (-1,), '3\n4\n' + '>0'), + + ('nnp', 3, (), 14), + + ('nnp', 4, (), 6), + + ('nnp', 5, (), ''), +] + + +##-Utils +def make_run_command(nn_type: str, nb: int) -> list[str]: + ''' + Crafts the command to run the given compiled file. + + In: + - nn_type: either 'nna' or 'nnp' + - nb: the number of the program (e.g 1 for correct1) + Out: + the command to run the given compiled file + ''' + + return f'python main.py r nn_programs/{nn_type}/expected/correct{nb}.nno.expected'.split(' ') + +def make_input_command(*inputs) -> list[str]: + ''' + Crafts the command to send the inputs to the main program + + In: + - *inputs: the inputs + Out: + The echo command to send the inputs + ''' + + inputs_str = '\n'.join(str(i) for i in inputs) + + return ['echo', '-e', f'"{inputs_str}"'] + + +##-Tests +@pytest.mark.parametrize('nn_type, nb, inputs, expected_output', test_expected_values) +def test_run(nn_type: str, nb: int, inputs: tuple, expected_output: str | int): + ''' + Run the test for file `nn_type`/correct`nb`.nno.expected. + + In: + - nn_type: either 'nna' or 'nnp' + - nb: the number of the program (e.g 1 for correct1) + - inputs: the input tuple for this run. If no input, set it to `()`. + - expected_output: the expected output for this run + Out: + None, or AssertionError + ''' + + if inputs == (): + command = make_run_command(nn_type, nb) + else: + command = make_input_command(*inputs) + ['|'] + make_run_command(nn_type, nb) + command = ['bash', '-c', ' '.join(command)] + + result = run(command, capture_output=True, text=True) + output = result.stdout.strip().strip('>') + + assert output == str(expected_output).strip(), 'Failed for file "{nn_type}/correct{nb}.nno.expected"' From d04e110abe0b37d4dbae58448e0623a8190555ce Mon Sep 17 00:00:00 2001 From: lasercata <67599917+lasercata@users.noreply.github.com> Date: Wed, 12 Nov 2025 12:37:43 +0100 Subject: [PATCH 12/12] Adding test status badge in the readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 7b369e8..d8e45df 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ A simple tool to **analyze**, **compile**, and **run** NNP programs. +[![Python tests](https://github.com/lasercata/Compilation_project/actions/workflows/python-tests.yml/badge.svg)](https://github.com/lasercata/Compilation_project/actions/workflows/python-tests.yml) + --- ## 📁 Project Structure