diff --git a/.gitignore b/.gitignore index 598a38d4bc6065d6caee19229d6a1b071ea030e4..7c41c1a26f994902b5a97d38a46cc7c40ee9cedc 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ __pycache__ .venv .idea dist/ -results*/ \ No newline at end of file +results*/ +*.candidate.nf \ No newline at end of file diff --git a/run_tests.py b/run_tests.py index 6e809a439e38ceacded74b2b4a039e1b6e610957..cbc9dc30a5837acddd375910e4e4e482cc7b7713 100755 --- a/run_tests.py +++ b/run_tests.py @@ -1,9 +1,16 @@ #!/usr/bin/env python +import sys import unittest -#Run all tests -if __name__ == '__main__': + +# Run all tests +def main(pattern='test_*.py', *args): test_loader = unittest.TestLoader() - test_suite = test_loader.discover('tests', pattern='test_*.py') + test_suite = test_loader.discover('tests', pattern=pattern) runner = unittest.TextTestRunner() - runner.run(test_suite) + results = runner.run(test_suite) + return results.wasSuccessful() + + +if __name__ == '__main__': + sys.exit(0 if main(*sys.argv[1:]) else 1) diff --git a/src/bioflowinsighterror.py b/src/bioflowinsighterror.py index dd222bb911354243c204a4ce080bf325f04eb2ee..0dfc769c67d643823b55529a1319d935dde46a3e 100644 --- a/src/bioflowinsighterror.py +++ b/src/bioflowinsighterror.py @@ -43,6 +43,8 @@ class BioFlowInsightError(Exception): #* [5] -> A ternary conditional operator was used with an tuple #* [7] -> Tuple with emit (ch1, ch2) = emit.out #* [9] -> Tuple with call (ch1, ch2) = wf() +#* [11] -> Failed to extract the operation or call at the line x. Try rewriting it in a simplified version. + diff --git a/src/nextflow_building_blocks.py b/src/nextflow_building_blocks.py index c436bf2b7d6b83b904e0c8869064b6fd8ede4e2b..ce5144c9088f598a39dc7741fa98dd50de672357 100644 --- a/src/nextflow_building_blocks.py +++ b/src/nextflow_building_blocks.py @@ -318,16 +318,24 @@ class Nextflow_Building_Blocks: if(match.group(1) in constant.LIST_OPERATORS): #TODO -> the function below might not work perfectly but i don't have any other ideas - #TODO -> IMPORTANT find another way of doing this -> for example if there isn't the same number of curlies/parentheses + #Use if there is an operator called right before opening the curlies/parenthse - curly_left, curly_right = get_curly_count(text[:start]), get_curly_count(text[end:]) + #curly_left, curly_right = get_curly_count(text[:start]), get_curly_count(text[end:]) parenthese_left, parenthese_right = get_parenthese_count(text[:start]), get_parenthese_count(text[end:]) #if(curly_left==0 and curly_right==0 and parenthese_left==0 and parenthese_right==0 and (start, end) not in searched): if(parenthese_left==0 and parenthese_right==0 and (start, end) not in searched): searched.append((start, end)) - pot = extract_executor_from_middle(text, start, end) + try: + pot = extract_executor_from_middle(text, start, end) + except: + try: + temp = text[start-10:end+10] + except: + temp = text[start:end] + raise BioFlowInsightError(f"Failed to extract the operation or call{self.get_string_line(temp)}. Try rewriting it in a simplified version.", num = 11, origin=self) + pot = expand_to_pipe_operators(text, pot) #If the thing which is extracted is not in the conditon of an if @@ -360,6 +368,7 @@ class Nextflow_Building_Blocks: self.executors.append(ope) searching = True break + #--------------------------------------------------------------- #STEP4 - Extract the Executors which only use the pipe operators (which start with a channel) diff --git a/src/nextflow_file.py b/src/nextflow_file.py index 69302228eb9ba9a08a89c300943f89524e6bc85c..70684e4f2c4f1346bd294de102bdb17258121f0d 100644 --- a/src/nextflow_file.py +++ b/src/nextflow_file.py @@ -91,13 +91,20 @@ class Nextflow_File(Nextflow_Building_Blocks): if(self.first_file): return self.output_dir else: - return self.origin.get_output_dir() + if(self.origin==None): + return self.output_dir + else: + return self.origin.get_output_dir() def get_display_info(self): if (self.first_file): return self.display_info else: - return self.origin.get_display_info() + if(self.origin==None): + return self.display_info + else: + return self.origin.get_display_info() + def set_name(self): diff --git a/src/ro_crate.py b/src/ro_crate.py index 098a437ce1e91c1a009c5247022306315292bf23..80d167647495aca656acb42be482fcaeb24e111f 100644 --- a/src/ro_crate.py +++ b/src/ro_crate.py @@ -80,7 +80,7 @@ class RO_Crate: current_directory = os.getcwd() os.chdir("/".join(self.workflow.nextflow_file.get_file_address().split("/")[:-1])) try: - os.system(f"git log {'--reverse'*reverse} {file} > temp_{id(self)}.txt") + os.system(f"git log {'--reverse'*reverse} \"{file}\" > temp_{id(self)}.txt") with open(f'temp_{id(self)}.txt') as f: info = f.read() os.system(f"rm temp_{id(self)}.txt") diff --git a/tests/test_channel.py b/tests/test_channel.py index b5c5547f7b3b336b32f05a52adcc053af4af27d9..b823d57b323a84889cd4eb09898c493903bd8612 100644 --- a/tests/test_channel.py +++ b/tests/test_channel.py @@ -3,26 +3,34 @@ from src.channel import * from src.nextflow_file import Nextflow_File +class EmptyNextflowFile(Nextflow_File): + def __init__(self, address="tests/ressources/channel/empty_wf.nf", display_info=False, *args, **kwargs): + super().__init__(address=address, display_info=display_info, *args, **kwargs) + + def check_file_correctness_after_DSL(self): + return + + class TestChannel(unittest.TestCase): def test_get_code(self): - wf1 = Nextflow_File("tests/ressources/channel/empty_wf.nf", display_info=False) + wf1 = EmptyNextflowFile() ch1 = Channel(name = "ch1", origin = wf1) self.assertIsInstance(ch1, Channel) self.assertEqual(ch1.get_code(), "ch1") def test_get_name(self): - wf1 = Nextflow_File("tests/ressources/channel/empty_wf.nf", display_info=False) + wf1 = EmptyNextflowFile() ch1 = Channel(name = "ch1", origin = wf1) self.assertEqual(ch1.get_name(), "ch1") def test_get_type(self): - wf1 = Nextflow_File("tests/ressources/channel/empty_wf.nf", display_info=False) + wf1 = EmptyNextflowFile() ch1 = Channel(name = "ch1", origin = wf1) self.assertEqual(ch1.get_type(), "Channel") def test_add_source(self): - wf1 = Nextflow_File("tests/ressources/channel/empty_wf.nf", display_info=False) + wf1 = EmptyNextflowFile() ch1 = Channel(name = "ch1", origin = wf1) self.assertEqual(ch1.get_source(), []) ele = "This is a test" @@ -30,7 +38,7 @@ class TestChannel(unittest.TestCase): self.assertEqual(ch1.get_source(), [ele]) def test_add_sink(self): - wf1 = Nextflow_File("tests/ressources/channel/empty_wf.nf", display_info=False) + wf1 = EmptyNextflowFile() ch1 = Channel(name = "ch1", origin = wf1) self.assertEqual(ch1.get_sink(), []) ele = "This is a test" @@ -38,7 +46,7 @@ class TestChannel(unittest.TestCase): self.assertEqual(ch1.get_sink(), [ele]) def test_set_sink_null(self): - wf1 = Nextflow_File("tests/ressources/channel/empty_wf.nf", display_info=False) + wf1 = EmptyNextflowFile() ch1 = Channel(name = "ch1", origin = wf1) ele = "This is a test" ch1.add_sink(ele) @@ -47,7 +55,7 @@ class TestChannel(unittest.TestCase): self.assertEqual(ch1.get_sink(), []) def test_remove_element_from_sink(self): - wf1 = Nextflow_File("tests/ressources/channel/empty_wf.nf", display_info=False) + wf1 = EmptyNextflowFile() ch1 = Channel(name = "ch1", origin = wf1) ele = "This is a test" ch1.add_sink(ele) @@ -56,7 +64,7 @@ class TestChannel(unittest.TestCase): self.assertEqual(ch1.get_sink(), []) def test_equal(self): - wf1 = Nextflow_File("tests/ressources/channel/empty_wf.nf", display_info=False) + wf1 = EmptyNextflowFile() ch1 = Channel(name = "ch1", origin = wf1) ch1_1 = Channel(name = "ch1", origin = wf1) ch2 = Channel(name = "ch2", origin = wf1) @@ -64,7 +72,7 @@ class TestChannel(unittest.TestCase): self.assertFalse(ch1.equal(channel=ch2)) def test_get_structure(self): - wf1 = Nextflow_File("tests/ressources/channel/empty_wf.nf", display_info=False) + wf1 = EmptyNextflowFile() ch1 = Channel(name = "ch1", origin = wf1) dico = {} dico['nodes'] = [] diff --git a/tests/test_cli.py b/tests/test_cli.py index 076721cecca10563ff6b3698c182db0c12ac49e5..fab491414d834305052fd08aa103e34ec896991f 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -7,7 +7,7 @@ from bioflow_insight_cli.main import cli class TestCall(unittest.TestCase): def test_cli_works(self): - cli("./wf_test/main.nf", render_graphs=True) + #cli("./wf_test/main.nf", render_graphs=False) cli("./wf_test/main.nf", render_graphs=False) def test_cli_output_considered(self): diff --git a/tests/test_code.py b/tests/test_code.py index b57f3515c438a53a130c59cc383a38dbadf44697..0dd7b5f0c4663b41c58cf209799441bcd52d29d9 100644 --- a/tests/test_code.py +++ b/tests/test_code.py @@ -3,25 +3,14 @@ from src.code_ import * class TestCode(unittest.TestCase): - def test_initialise(self): - with open("tests/ressources/outils/remove_comments_with.nf", 'r') as f: - code_with_comments = f.read() - - with open("tests/ressources/outils/remove_comments_wo.nf", 'r') as f: - code_wo_comments = f.read() - - code = Code(code_with_comments, origin=None) - self.assertIsInstance(code, Code) - self.assertEqual(code.code, '\n'+code_with_comments+'\n') - self.assertEqual(code.code_wo_comments, '\n'+code_wo_comments+'\n') - def test_get_code(self): with open("tests/ressources/outils/remove_comments_with.nf", 'r') as f: code_with_comments = f.read() with open("tests/ressources/outils/remove_comments_wo.nf", 'r') as f: code_wo_comments = f.read() - code = Code(code_with_comments, origin=None) + self.assertEqual(code.code, '\n'+code_with_comments+'\n') + self.assertEqual(code.code_wo_comments.strip(), code_wo_comments.strip()) self.assertEqual(code.get_code(), code_wo_comments.strip()) diff --git a/tests/test_outils.py b/tests/test_outils.py index 9fe2c7d9772e917a13dd02095e8759e220e4c34c..2143f18b7003813b517d3c2395c41a8520d6f05e 100644 --- a/tests/test_outils.py +++ b/tests/test_outils.py @@ -1,3 +1,4 @@ +import os import unittest from src.outils import * @@ -36,6 +37,10 @@ class TestOutils(unittest.TestCase): with open("tests/ressources/outils/remove_comments_wo.nf", 'r') as f: code_wo_comments = f.read() - self.assertEqual(remove_comments(code_with_comments), code_wo_comments) - + produced = remove_comments(code_with_comments) + with open(candidate := "tests/ressources/outils/remove_comments_wo.candidate.nf", 'w') as f: + f.write(produced) + + self.assertEqual(produced.strip(), code_wo_comments.strip()) + os.unlink(candidate) diff --git a/tests/test_process.py b/tests/test_process.py index 4c2f6400190fc2127e1b0e6a909ba385ea9c6262..ff40c83af42704aa802c4691d60b5795351d7223 100644 --- a/tests/test_process.py +++ b/tests/test_process.py @@ -10,20 +10,20 @@ class TestProcess(unittest.TestCase): def test_initialise_name(self): #DSL1 - file = Nextflow_File("tests/ressources/process/process_DSL1.nf", display_info=False) + file = Nextflow_File("tests/ressources/process/process_DSL1.nf", display_info=False, DSL = "DSL1") file.initialise() process_DSL1 = file.processes[0] self.assertEqual(process_DSL1.get_name(), "cleanSpeciesTree") self.assertEqual(process_DSL1.get_alias(), "cleanSpeciesTree") #DSL2 - file = Nextflow_File("tests/ressources/process/process_DSL2.nf", display_info=False) + file = Nextflow_File("tests/ressources/process/process_DSL2.nf", display_info=False, DSL = "DSL2") file.initialise() process_DSL2 = file.processes[0] self.assertEqual(process_DSL2.get_name(), "OPENMS_FALSEDISCOVERYRATE") self.assertEqual(process_DSL2.get_alias(), "OPENMS_FALSEDISCOVERYRATE") def test_set_alias(self): - file = Nextflow_File("tests/ressources/process/process_DSL2.nf", display_info=False) + file = Nextflow_File("tests/ressources/process/process_DSL2.nf", display_info=False, DSL = "DSL2") file.initialise() process_DSL2 = file.processes[0] self.assertEqual(process_DSL2.get_alias(), "OPENMS_FALSEDISCOVERYRATE") @@ -35,24 +35,24 @@ class TestProcess(unittest.TestCase): def test_which_DSL(self): #DSL1 - file = Nextflow_File("tests/ressources/process/process_DSL1.nf", display_info=False) + file = Nextflow_File("tests/ressources/process/process_DSL1.nf", display_info=False, DSL = "DSL1") file.initialise() process_DSL1 = file.processes[0] self.assertEqual(process_DSL1.which_DSL(), "DSL1") #DSL2 - file = Nextflow_File("tests/ressources/process/process_DSL2.nf", display_info=False) + file = Nextflow_File("tests/ressources/process/process_DSL2.nf", display_info=False, DSL = "DSL1") file.initialise() process_DSL2 = file.processes[0] self.assertEqual(process_DSL2.which_DSL(), "DSL2") def test_is_initialised(self): #DSL1 - file = Nextflow_File("tests/ressources/process/process_DSL1.nf", display_info=False) + file = Nextflow_File("tests/ressources/process/process_DSL1.nf", display_info=False, DSL = "DSL1") file.initialise() process_DSL1 = file.processes[0] self.assertTrue(process_DSL1.is_initialised()) #DSL2 - file = Nextflow_File("tests/ressources/process/process_DSL2.nf", display_info=False) + file = Nextflow_File("tests/ressources/process/process_DSL2.nf", display_info=False, DSL = "DSL2") file.initialise() process_DSL2 = file.processes[0] self.assertTrue(process_DSL2.is_initialised()) @@ -60,12 +60,12 @@ class TestProcess(unittest.TestCase): def test_get_type(self): #DSL1 - file = Nextflow_File("tests/ressources/process/process_DSL1.nf", display_info=False) + file = Nextflow_File("tests/ressources/process/process_DSL1.nf", display_info=False, DSL = "DSL1") file.initialise() process_DSL1 = file.processes[0] self.assertEqual(process_DSL1.get_type(), "Process") #DSL2 - file = Nextflow_File("tests/ressources/process/process_DSL2.nf", display_info=False) + file = Nextflow_File("tests/ressources/process/process_DSL2.nf", display_info=False, DSL = "DSL2") file.initialise() process_DSL2 = file.processes[0] self.assertEqual(process_DSL2.get_type(), "Process") @@ -74,7 +74,7 @@ class TestProcess(unittest.TestCase): def test_get_structure(self): #DSL1 - file = Nextflow_File("tests/ressources/process/process_DSL1.nf", display_info=False) + file = Nextflow_File("tests/ressources/process/process_DSL1.nf", display_info=False, DSL = "DSL1") file.initialise() process_DSL1 = file.processes[0] dico = {} @@ -82,10 +82,11 @@ class TestProcess(unittest.TestCase): dico['edges'] = [] dico['subworkflows'] = {} process_DSL1.get_structure(dico) - dico_true = {'nodes': [{'id': str(process_DSL1), 'name': 'cleanSpeciesTree', 'shape': 'ellipse', 'xlabel': ''}], 'edges': [], 'subworkflows': {}} + dico_true = {'nodes': [{'id': str(process_DSL1), 'name': 'cleanSpeciesTree', 'shape': 'ellipse', 'xlabel': '', 'fillcolor': ''}], 'edges': [], 'subworkflows': {}} self.assertEqual(dico, dico_true) + #DSL2 - file = Nextflow_File("tests/ressources/process/process_DSL2.nf", display_info=False) + file = Nextflow_File("tests/ressources/process/process_DSL2.nf", display_info=False, DSL = "DSL2") file.initialise() process_DSL2 = file.processes[0] dico = {} @@ -93,11 +94,11 @@ class TestProcess(unittest.TestCase): dico['edges'] = [] dico['subworkflows'] = {} process_DSL2.get_structure(dico) - dico_true = {'nodes': [{'id': str(process_DSL2), 'name': 'OPENMS_FALSEDISCOVERYRATE', 'shape': 'ellipse', 'xlabel': ''}], 'edges': [], 'subworkflows': {}} + dico_true = {'nodes': [{'id': str(process_DSL2), 'name': 'OPENMS_FALSEDISCOVERYRATE', 'shape': 'ellipse', 'xlabel': '', 'fillcolor': ''}], 'edges': [], 'subworkflows': {}} self.assertEqual(dico, dico_true) def test_(self): - file = Nextflow_File("tests/ressources/process/process_DSL1.nf", display_info=False) + file = Nextflow_File("tests/ressources/process/process_DSL1.nf", display_info=False, DSL = "DSL1") file.initialise() process_DSL1 = file.processes[0]