""" Test Message TestPlan: Message VERSION X """ from itertools import product from tests_rpl.rpltests.expressions import expression_testing from tests_rpl.rpltests.rpl_cases import RplCaseProgram, check_success_cases from tests_rpl.rpltests.rpl_testing import ( RplTestProgram, check_compile_issues, IssueCode, ) class TestMessageDeclaration: """Validates message declaration right behavior for correct and incorrect cases.""" success_case_programs = [] def collect_cases_a_1_declared_matched_name_matched_type(self): # Requirement: RPL-MSG-D01 """ Verifies that messages declared in the Messages module can be correctly sent and received when both the message name and data type matches. """ for idx, (t, v) in enumerate( expression_testing.ALL_TYPES_VALUES_EXAMPLES.items(), start=1 ): common_program = RplCaseProgram( additional_sources=[ "actor EmptyActor;", f"""\ module Messages; import EmptyActor; {expression_testing.ENUM_TYPE_ALIAS} message SendMessage_a_{idx} contains {t}; message SendMessage_b_{idx} contains {{}}; message SendMessage_c_{idx} contains {t}; message WaitMessage_b_{idx} contains {t}; message WaitMessage_c_{idx} contains {t}; """, f"""\ actor MyActor; import EmptyActor; import Messages; {expression_testing.ENUM_TYPE_ALIAS} {expression_testing.EMPTY_ACTOR_VARIABLES} on SendMessage_a_{idx}(s, d) {{}} on SendMessage_b_{idx}(s, d) {{send WaitMessage_b_{idx}({v}) >> s;}} on SendMessage_c_{idx}(s, d) {{send WaitMessage_c_{idx}(d) >> s;}} """, ], test_actor_imports="""\ import EmptyActor; import Messages; import MyActor; """, defs_block=f"""\ var myactor = create MyActor(); {expression_testing.ENUM_TYPE_ALIAS} {expression_testing.EMPTY_ACTOR_VARIABLES} """, main_body=f"""\ send SendMessage_a_{idx}({v}) >> myactor; send SendMessage_b_{idx} >> myactor; var result_b_{idx} = wait WaitMessage_b_{idx} << myactor; send SendMessage_c_{idx}({v}) >> myactor; var result_c_{idx} = wait WaitMessage_c_{idx} << myactor; Testing.complete(); """, ) self.success_case_programs.append(common_program) def test_a_2_undeclared_matched_name_matched_type(self): # Requirement: RPL-MSG-D01 """ Verifies that attempting to send or receive a message that was never declared, even if the name and data type matches leads to CTE E_Undefined. """ for _, v in expression_testing.ALL_TYPES_VALUES_EXAMPLES.items(): program_a = RplTestProgram( additional_sources=[ "actor EmptyActor;", "module Messages;", """ actor MyActor; import Messages; on SendMessage(s, d) {} """, ], test_actor_imports="""\ import EmptyActor; import Messages; import MyActor; """, test_actor_contents=f"""\ var myactor = create MyActor(); {expression_testing.ENUM_TYPE_ALIAS} {expression_testing.EMPTY_ACTOR_VARIABLES} """, main_body=f"""\ send SendMessage({v}) >> myactor; """, ) check_compile_issues(program_a, IssueCode.E_Undefined) program_b = RplTestProgram( additional_sources=[ "actor EmptyActor;", "module Messages;", f"""\ actor MyActor; import Messages; import EmptyActor; {expression_testing.ENUM_TYPE_ALIAS} {expression_testing.EMPTY_ACTOR_VARIABLES} on SendMessage(s, d) {{ send WaitMessage({v}) >> s; }} """, ], test_actor_imports="""\ import EmptyActor; import Messages; import MyActor; """, test_actor_contents=f"""\ var myactor = create MyActor(); {expression_testing.ENUM_TYPE_ALIAS} {expression_testing.EMPTY_ACTOR_VARIABLES} """, main_body="""\ send SendMessage >> myactor; var result = wait WaitMessage << myactor; """, ) check_compile_issues(program_b, IssueCode.E_Undefined) program_c = RplTestProgram( additional_sources=[ "actor EmptyActor;", "module Messages;", """ actor MyActor; import Messages; on SendMessage(s, d) { send WaitMessage(d) >> s; } """, ], test_actor_imports="""\ import EmptyActor; import Messages; import MyActor; """, test_actor_contents=f"""\ var myactor = create MyActor(); {expression_testing.ENUM_TYPE_ALIAS} {expression_testing.EMPTY_ACTOR_VARIABLES} """, main_body=f"""\ send SendMessage({v}) >> myactor; var result = wait WaitMessage << myactor; """, ) check_compile_issues(program_c, IssueCode.E_Undefined) def test_a_3_declared_undeclared_matched_name_matched_type(self): # Requirement: RPL-MSG-D01 """ Verifies that if one of the messages for send or wait is undeclared while the other one is declared with a matching name and type it leads to CTE E_Undefined. """ for t, v in expression_testing.ALL_TYPES_VALUES_EXAMPLES.items(): program_a = RplTestProgram( additional_sources=[ "actor EmptyActor;", f"""\ module Messages; import EmptyActor; {expression_testing.ENUM_TYPE_ALIAS} message WaitMessage contains {t}; """, """ actor MyActor; import Messages; on SendMessage(s, d) { send WaitMessage(d) >> s; } """, ], test_actor_imports="""\ import EmptyActor; import Messages; import MyActor; """, test_actor_contents=f"""\ var myactor = create MyActor(); {expression_testing.ENUM_TYPE_ALIAS} {expression_testing.EMPTY_ACTOR_VARIABLES} """, main_body=f"""\ send SendMessage({v}) >> myactor; var result = wait WaitMessage << myactor; """, ) check_compile_issues(program_a, IssueCode.E_Undefined) program_b = RplTestProgram( additional_sources=[ "actor EmptyActor;", f"""\ module Messages; import EmptyActor; {expression_testing.ENUM_TYPE_ALIAS} message SendMessage contains {t}; """, """ actor MyActor; import Messages; on SendMessage(s, d) { send WaitMessage(d) >> s; } """, ], test_actor_imports="""\ import EmptyActor; import Messages; import MyActor; """, test_actor_contents=f"""\ var myactor = create MyActor(); {expression_testing.ENUM_TYPE_ALIAS} {expression_testing.EMPTY_ACTOR_VARIABLES} """, main_body=f"""\ send SendMessage({v}) >> myactor; var result = wait WaitMessage << myactor; """, ) check_compile_issues(program_b, IssueCode.E_Undefined) def test_a_4_declared_unmatched_name_matched_type(self): # Requirement: RPL-MSG-D01 """ Verifies that if a message name used in send or wait does not match the declared name, even if the data type matches it leads to CTE E_Undefined. """ for t, v in expression_testing.ALL_TYPES_VALUES_EXAMPLES.items(): program_a = RplTestProgram( additional_sources=[ "actor EmptyActor;", f"""\ module Messages; import EmptyActor; {expression_testing.ENUM_TYPE_ALIAS} message SendMessage contains {t}; """, """ actor MyActor; import Messages; on SendMessage(s, d) {} """, ], test_actor_imports="""\ import EmptyActor; import Messages; import MyActor; """, test_actor_contents=f"""\ var myactor = create MyActor(); {expression_testing.ENUM_TYPE_ALIAS} {expression_testing.EMPTY_ACTOR_VARIABLES} """, main_body=f"""\ send SendMessageNew({v}) >> myactor; """, ) check_compile_issues(program_a, IssueCode.E_Undefined) program_b = RplTestProgram( additional_sources=[ "actor EmptyActor;", f"""\ module Messages; import EmptyActor; {expression_testing.ENUM_TYPE_ALIAS} message SendMessage contains {{}}; message WaitMessage contains {t}; """, f"""\ actor MyActor; import Messages; import EmptyActor; {expression_testing.ENUM_TYPE_ALIAS} {expression_testing.EMPTY_ACTOR_VARIABLES} on SendMessage(s, d) {{ send WaitMessage({v}) >> s; }} """, ], test_actor_imports="""\ import EmptyActor; import Messages; import MyActor; """, test_actor_contents=f"""\ var myactor = create MyActor(); {expression_testing.ENUM_TYPE_ALIAS} {expression_testing.EMPTY_ACTOR_VARIABLES} """, main_body="""\ send SendMessage >> myactor; var result = wait WaitMessageNew << myactor; """, ) check_compile_issues(program_b, IssueCode.E_Undefined) def test_a_5_declared_matched_name_unmatched_type(self): # Requirement: RPL-MSG-D01 """ Verifies that if a message name matches but the data type differs from the declared type it leads to CTE E_TypeCastError. """ for (t2, v2), (t1, _) in product( expression_testing.ALL_TYPES_VALUES_EXAMPLES.items(), expression_testing.ALL_TYPES_VALUES_EXAMPLES.items(), ): if ( t2 == t1 or (t2, t1) in expression_testing.IMPLICITLY_CASTABLE_TYPES_PAIRS ): continue program_a = RplTestProgram( additional_sources=[ "actor EmptyActor;", f"""\ module Messages; import EmptyActor; {expression_testing.ENUM_TYPE_ALIAS} message SendMessage contains {t1}; """, """ actor MyActor; import Messages; on SendMessage(s, d) {} """, ], test_actor_imports="""\ import EmptyActor; import Messages; import MyActor; """, test_actor_contents=f"""\ var myactor = create MyActor(); {expression_testing.ENUM_TYPE_ALIAS} {expression_testing.EMPTY_ACTOR_VARIABLES} """, main_body=f"""\ send SendMessage({v2}) >> myactor; """, ) check_compile_issues(program_a, IssueCode.E_TypeCastError) program_b = RplTestProgram( additional_sources=[ "actor EmptyActor;", f"""\ module Messages; import EmptyActor; {expression_testing.ENUM_TYPE_ALIAS} message SendMessage contains {{}}; message WaitMessage contains {t1}; """, f"""\ actor MyActor; import EmptyActor; import Messages; {expression_testing.ENUM_TYPE_ALIAS} {expression_testing.EMPTY_ACTOR_VARIABLES} on SendMessage(s, d) {{ send WaitMessage({v2}) >> s; }} """, ], test_actor_imports="""\ import EmptyActor; import Messages; import MyActor; """, test_actor_contents=f"""\ var myactor = create MyActor(); {expression_testing.ENUM_TYPE_ALIAS} {expression_testing.EMPTY_ACTOR_VARIABLES} """, main_body="""\ send SendMessage >> myactor; var result = wait WaitMessage << myactor; """, ) check_compile_issues(program_b, IssueCode.E_TypeCastError) def test_a_6_declared_unmatched_name_unmatched_type(self): # Requirement: RPL-MSG-D01 """ Verifies that messages with name and data type differing from the declaration one leads to CTE issues: - Undefined when a message name does not match - TypeCastError when a message type does not match """ for (t2, v2), (t1, _) in product( expression_testing.ALL_TYPES_VALUES_EXAMPLES.items(), expression_testing.ALL_TYPES_VALUES_EXAMPLES.items(), ): if ( t2 == t1 or (t2, t1) in expression_testing.IMPLICITLY_CASTABLE_TYPES_PAIRS ): continue program_a = RplTestProgram( additional_sources=[ "actor EmptyActor;", f"""\ module Messages; import EmptyActor; {expression_testing.ENUM_TYPE_ALIAS} message SendMessage contains {t1}; """, """ actor MyActor; import Messages; on SendMessage(s, d) {} """, ], test_actor_imports="""\ import EmptyActor; import Messages; import MyActor; """, test_actor_contents=f"""\ var myactor = create MyActor(); {expression_testing.ENUM_TYPE_ALIAS} {expression_testing.EMPTY_ACTOR_VARIABLES} """, main_body=f"""\ send SendMessageNew({v2}) >> myactor; """, ) check_compile_issues(program_a, IssueCode.E_Undefined) program_b = RplTestProgram( additional_sources=[ "actor EmptyActor;", f"""\ module Messages; import EmptyActor; {expression_testing.ENUM_TYPE_ALIAS} message SendMessage contains {{}}; message WaitMessage contains {t1}; """, f"""\ actor MyActor; import EmptyActor; import Messages; {expression_testing.ENUM_TYPE_ALIAS} {expression_testing.EMPTY_ACTOR_VARIABLES} on SendMessage(s, d) {{ send WaitMessage({v2}) >> s; }} """, ], test_actor_imports="""\ import EmptyActor; import Messages; import MyActor; """, test_actor_contents=f"""\ var myactor = create MyActor(); {expression_testing.ENUM_TYPE_ALIAS} {expression_testing.EMPTY_ACTOR_VARIABLES} """, main_body="""\ send SendMessage >> myactor; var result = wait WaitMessageNew << myactor; """, ) check_compile_issues(program_b, IssueCode.E_TypeCastError) def test_success_cases(self): """General executor for all success cases.""" self.collect_cases_a_1_declared_matched_name_matched_type() check_success_cases( { f"case_{num}": case for num, case in enumerate(self.success_case_programs, start=1) } )