def test_superfluous_arguments(self): program_w_superfluous_argument = program_abs_stx.FullProgramAbsStx( program_abs_stx.ARBITRARY_TRANSFORMABLE_PROGRAM, transformation=str_trans_abs_stx.StringTransformerCompositionAbsStx( [ StringTransformerSymbolReferenceAbsStx('str_trans_sym_1'), StringTransformerSymbolReferenceAbsStx('str_trans_sym_1'), ], within_parens=False, allow_elements_on_separate_lines=False, ) ) for phase_is_after_act in [False, True]: for output_file in ProcOutputFile: for ignore_exit_code in [False, True]: instruction_syntax = instr_abs_stx.create_w_explicit_contents( ARBITRARY_ALLOWED_DST_FILE_RELATIVITY.path_abs_stx_of_name('dst-file'), string_source_abs_stx.StringSourceOfProgramAbsStx( output_file, program_w_superfluous_argument, ignore_exit_code=ignore_exit_code) ) with self.subTest(output_file=output_file, phase_is_after_act=phase_is_after_act, ignore_exit_code=ignore_exit_code): parse_check.check_invalid_syntax__abs_stx( self, instruction_syntax, )
def test_WHEN_program_is_non_non_existing_system_command_THEN_result_SHOULD_be_error_message(self): failing_program_builder = program_abs_stx.TransformableProgramAbsStxBuilder( program_abs_stx.ProgramOfSystemCommandLineAbsStx.of_str(NON_EXISTING_SYSTEM_PROGRAM) ) transformer = TO_UPPER_TRANSFORMER_SYMBOL symbols = transformer.symbol_table cases = failing_program_builder.with_and_without_transformer_cases(transformer.abstract_syntax) for transformation_case in cases: instruction_syntax = instr_abs_stx.create_w_explicit_contents( path_abs_stx.DefaultRelPathAbsStx('dst-file'), string_source_abs_stx.StringSourceOfProgramAbsStx( ProcOutputFile.STDOUT, transformation_case.value, ignore_exit_code=False) ) for phase_is_after_act in [False, True]: checker = integration_check.checker(phase_is_after_act) with self.subTest(phase_is_after_act=phase_is_after_act, transformation=transformation_case.name): checker.check__abs_stx__std_layouts_and_source_variants( self, instruction_syntax, Arrangement.phase_agnostic( symbols=symbols, tcds=TcdsArrangement(), ), MultiSourceExpectation.phase_agnostic( symbol_usages=asrt.anything_goes(), main_result=IS_FAILURE, ) )
def test_transformer_component(self): checker = integration_check.checker__w_arbitrary_file_relativities() for validation_case in failing_validation_cases(): transformer_symbol = validation_case.value.symbol_context program_syntax = program_abs_stx.FullProgramAbsStx( program_abs_stx.ProgramOfSystemCommandLineAbsStx.of_str( 'a-system-command'), transformation=transformer_symbol.abstract_syntax, ) string_source_syntax = string_source_abs_stx.StringSourceOfProgramAbsStx( ProcOutputFile.STDOUT, program_syntax, ignore_exit_code=False, ) with self.subTest(validation_case.name): checker.check__abs_stx__layouts__source_variants__wo_input( self, equivalent_source_variants__for_expr_parse__s__nsc, OptionallyOnNewLine(string_source_syntax), arrangement_wo_tcds( symbols=transformer_symbol.symbol_table), MultiSourceExpectation( symbol_references=transformer_symbol. references_assertion, execution=ExecutionExpectation( validation=validation_case.value.expectation)))
def runTest(self): non_zero_exit_code = 1 program_string_source_syntax = string_source_abs_stx.StringSourceOfProgramAbsStx( ProcOutputFile.STDOUT, program_abs_stx.ProgramOfPythonInterpreterAbsStx. of_execute_python_src_string( py_programs.single_line_pgm_that_exists_with( non_zero_exit_code)), ignore_exit_code=False, ) instruction_syntax = instr_abs_stx.create_w_explicit_contents( conf_rel_non_hds( RelNonHdsOptionType.REL_TMP).path_abs_stx_of_name('dst.txt'), program_string_source_syntax, ) for source_case in equivalent_source_variants__with_source_check__consume_last_line__abs_stx( instruction_syntax): with self.subTest(source_case.name): self.conf.run_test( self, source_case.value.source, self.conf.arrangement(), self.conf.expect_hard_error_of_main__any(), )
def _mk_explicit_contents(program: ProgramAbsStx) -> fs_abs_stx.FileContentsExplicitAbsStx: return fs_abs_stx.FileContentsExplicitAbsStx( fs_abs_stx.ModificationType.CREATE, string_source_abs_stx.StringSourceOfProgramAbsStx( ProcOutputFile.STDOUT, program, ) )
def runTest(self): text_printed_by_program = 'single line of output' expected_file_contents = text_printed_by_program.upper() expected_file = fs.File('dst-file.txt', expected_file_contents) to_upper_transformer = StringTransformerSymbolContext.of_primitive( 'TO_UPPER_CASE', to_uppercase(), ) symbols = to_upper_transformer.symbol_table dst_rel_opt_conf = conf_rel_non_hds(RelNonHdsOptionType.REL_TMP) program_syntax = string_source_abs_stx.StringSourceOfProgramAbsStx( ProcOutputFile.STDOUT, program_abs_stx.FullProgramAbsStx( program_abs_stx.ProgramOfPythonInterpreterAbsStx. of_execute_python_src_string( py_programs.single_line_pgm_that_prints_to( ProcOutputFile.STDOUT, text_printed_by_program)), transformation=to_upper_transformer.abstract_syntax, )) instruction_syntax = instr_abs_stx.create_w_explicit_contents( dst_rel_opt_conf.path_abs_stx_of_name(expected_file.name), program_syntax, ) instruction_checker = self.conf.instruction_checker parser = self.conf.parser() for source_case in equivalent_source_variants__with_source_check__consume_last_line__abs_stx( instruction_syntax): with self.subTest(source_case.name): source = source_case.value.source # ACT # instruction = parser.parse(ARBITRARY_FS_LOCATION_INFO, source) # ASSERT # source_case.value.expectation.apply_with_message( self, source, 'source-after-parse') # ACT & ASSERT # instruction_checker.check( self, instruction, self.conf.arrangement( pre_contents_population_action= SETUP_CWD_INSIDE_SDS_BUT_NOT_A_SDS_DIR, symbols=symbols), self.conf.expect_success( symbol_usages=asrt.matches_sequence([ to_upper_transformer.reference_assertion, ]), main_side_effects_on_sds=non_hds_dir_contains_exactly( dst_rel_opt_conf.root_dir__non_hds, fs.DirContents([expected_file])), ))
def runTest(self): # ARRANGE # text_printed_by_program = StringSymbolContext.of_constant('STRING_TO_PRINT_SYMBOL', 'hello world') dst_file_symbol = ConstantSuffixPathDdvSymbolContext( 'DST_FILE_SYMBOL', RelOptionType.REL_ACT, 'dst-file-name.txt', sut.REL_OPT_ARG_CONF.options.accepted_relativity_variants, ) to_upper_transformer = TO_UPPER_TRANSFORMER_SYMBOL transformed_program_output_contents_syntax = string_source_abs_stx.StringSourceOfProgramAbsStx( ProcOutputFile.STDOUT, program_abs_stx.FullProgramAbsStx( program_abs_stx.ProgramOfPythonInterpreterAbsStx.of_execute_python_src_string( py_programs.single_line_pgm_that_prints_to( ProcOutputFile.STDOUT, text_printed_by_program.name__sym_ref_syntax ) ), transformation=to_upper_transformer.abstract_syntax, ) ) instruction_syntax = instr_abs_stx.create_w_explicit_contents( dst_file_symbol.abstract_syntax, transformed_program_output_contents_syntax ) symbols = SymbolContext.symbol_table_of_contexts([ dst_file_symbol, text_printed_by_program, to_upper_transformer, ]) # ACT & ASSERT # checker = integration_check.checker(False) checker.check__abs_stx__std_layouts_and_source_variants( self, instruction_syntax, Arrangement.phase_agnostic( symbols=symbols, tcds=TcdsArrangement(), ), MultiSourceExpectation.phase_agnostic( main_result=IS_SUCCESS, symbol_usages=asrt.matches_sequence([ dst_file_symbol.reference_assertion__path_or_string, text_printed_by_program.reference_assertion__w_str_rendering, to_upper_transformer.reference_assertion, ]), ) )
def runTest(self): # ARRANGE # text_printed_by_program = StringConstantSymbolContext( 'STRING_TO_PRINT_SYMBOL', 'hello world') to_upper_transformer = TO_UPPER_TRANSFORMER_SYMBOL expected_output = text_printed_by_program.str_value.upper() transformed_program_output_contents_syntax = string_source_abs_stx.StringSourceOfProgramAbsStx( ProcOutputFile.STDOUT, program_abs_stx.FullProgramAbsStx( program_abs_stx.ProgramOfPythonInterpreterAbsStx. of_execute_python_src_string( py_programs.single_line_pgm_that_prints_to( ProcOutputFile.STDOUT, text_printed_by_program.name__sym_ref_syntax)), transformation=to_upper_transformer.abstract_syntax, )) symbols = SymbolContext.symbol_table_of_contexts([ text_printed_by_program, to_upper_transformer, ]) checker = integration_check.checker__w_arbitrary_file_relativities() # ACT & ASSERT # checker.check__abs_stx__layouts__std_source_variants__wo_input( self, OptionallyOnNewLine(transformed_program_output_contents_syntax), arrangement_w_tcds(symbols=symbols, ), MultiSourceExpectation. of_prim__const(symbol_references=asrt.matches_sequence([ text_printed_by_program.reference_assertion__w_str_rendering, to_upper_transformer.reference_assertion, ]), primitive=asrt_string_source. pre_post_freeze__matches_str__const_2( expected_output, may_depend_on_external_resources=True, frozen_may_depend_on_external_resources=asrt. anything_goes(), )))
def runTest(self): # ARRANGE # cases = [ NArrEx( 'pre SDS validation failure SHOULD cause validation error', RelOptionType.REL_HDS_CASE, MultiSourceExpectation.phase_agnostic( validation=ValidationAssertions.pre_sds_fails__w_any_msg() ), ), NArrEx( 'post SDS validation failure SHOULD cause main error', RelOptionType.REL_ACT, MultiSourceExpectation.phase_agnostic( validation=ValidationAssertions.post_sds_fails__w_any_msg() ), ), ] for case in cases: program_with_ref_to_non_existing_file = program_abs_stx.ProgramOfExecutableFileCommandLineAbsStx( path_abs_stx.RelOptPathAbsStx(case.arrangement, 'non-existing-file') ) instruction_syntax = instr_abs_stx.create_w_explicit_contents( path_abs_stx.DefaultRelPathAbsStx('dst-file'), string_source_abs_stx.StringSourceOfProgramAbsStx(ProcOutputFile.STDOUT, program_with_ref_to_non_existing_file, ignore_exit_code=False) ) # ACT & ASSERT # for phase_is_after_act in [False, True]: checker = integration_check.checker(phase_is_after_act) with self.subTest(phase_is_after_act=phase_is_after_act, step=case.name): checker.check__abs_stx__std_layouts_and_source_variants( self, instruction_syntax, Arrangement.phase_agnostic(), case.expectation, )
def test_WHEN_program_is_non_non_existing_system_command_THEN_result_SHOULD_be_hard_error(self): failing_program_builder = program_abs_stx.TransformableProgramAbsStxBuilder( program_abs_stx.ProgramOfSystemCommandLineAbsStx.of_str(NON_EXISTING_SYSTEM_PROGRAM) ) transformer = TO_UPPER_TRANSFORMER_SYMBOL symbols = transformer.symbol_table cases = failing_program_builder.with_and_without_transformer_cases(transformer.abstract_syntax) for ignore_exit_code in [False, True]: for transformation_case in cases: syntax = string_source_abs_stx.StringSourceOfProgramAbsStx( ProcOutputFile.STDOUT, transformation_case.value, ignore_exit_code=ignore_exit_code, ) checker = integration_check.checker__w_arbitrary_file_relativities() with self.subTest(transformation=transformation_case.name, ignore_exit_code=ignore_exit_code): # ACT & ASSERT # checker.check__abs_stx__layouts__source_variants__wo_input( self, equivalent_source_variants__for_full_line_expr_parse__s__nsc, OptionallyOnNewLine(syntax), arrangement_w_tcds( symbols=symbols, ), MultiSourceExpectation.of_const( symbol_references=asrt.anything_goes(), primitive=asrt_string_source.pre_post_freeze( asrt_str_src_contents.contents_raises_hard_error( may_depend_on_external_resources=asrt.equals(True) ), asrt_str_src_contents.contents_raises_hard_error__including_ext_deps(), ), ) )
def _test(self, text_printed_by_program: str, expected_file_contents: str, make_arguments: Callable[[TransformableProgramAbsStxBuilder], ProgramAbsStx], additional_symbols: Dict[str, SymbolContainer], additional_symbol_references: List[Assertion[SymbolReference]], ): for proc_output_file in ProcOutputFile: python_source = py_programs.single_line_pgm_that_prints_to(proc_output_file, text_printed_by_program) program_that_executes_py_source_symbol = ProgramSymbolContext.of_sdv( 'PROGRAM_THAT_EXECUTES_PY_SOURCE', program_sdvs.for_py_source_on_command_line(python_source) ) program_cases = [ ProgramCase( 'python interpreter', program_abs_stx.ProgramOfPythonInterpreterAbsStx.of_execute_python_src_string(python_source), [] ), ProgramCase( 'symbol reference program', ProgramOfSymbolReferenceAbsStx(program_that_executes_py_source_symbol.name), [program_that_executes_py_source_symbol.reference_assertion], ), ] symbols_dict = { program_that_executes_py_source_symbol.name: program_that_executes_py_source_symbol.symbol_table_container, } symbols_dict.update(additional_symbols) symbols = SymbolTable(symbols_dict) checker = integration_check.checker__w_arbitrary_file_relativities() for program_case in program_cases: program_syntax_builder = TransformableProgramAbsStxBuilder(program_case.source) program_syntax = make_arguments(program_syntax_builder) expected_symbol_references = program_case.expected_references + additional_symbol_references syntax = string_source_abs_stx.StringSourceOfProgramAbsStx( proc_output_file, program_syntax, ignore_exit_code=False, ) with self.subTest(program=program_case.name, output_channel=proc_output_file): checker.check__abs_stx__layouts__source_variants__wo_input( self, equivalent_source_variants__for_full_line_expr_parse__s__nsc, OptionallyOnNewLine(syntax), arrangement_w_tcds( symbols=symbols, ), MultiSourceExpectation.of_prim__const( symbol_references=asrt.matches_sequence(expected_symbol_references), primitive=asrt_string_source.pre_post_freeze__matches_str__const_2( expected_file_contents, may_depend_on_external_resources=True, frozen_may_depend_on_external_resources=asrt.anything_goes(), ), ) )
def runTest(self): non_zero_exit_code = 1 text_printed_by_program = 'the output from the program' py_file = File( 'exit-with-hard-coded-exit-code.py', py_programs.py_pgm_with_stdout_stderr_exit_code( stdout_output=text_printed_by_program, stderr_output='', exit_code=non_zero_exit_code, ), ) expected_file = fs.File( 'dst-file.txt', text_printed_by_program.upper(), ) to_upper_transformer = StringTransformerSymbolContext.of_primitive( 'TO_UPPER_CASE', to_uppercase(), ) symbols = to_upper_transformer.symbol_table py_src_file_rel_opt_conf = rel_opt.conf_rel_any( RelOptionType.REL_HDS_CASE) dst_file_rel_opt_conf = conf_rel_non_hds(RelNonHdsOptionType.REL_TMP) program_string_source_syntax = string_source_abs_stx.StringSourceOfProgramAbsStx( ProcOutputFile.STDOUT, program_abs_stx.FullProgramAbsStx( program_abs_stx.ProgramOfPythonInterpreterAbsStx. of_execute_python_src_file( py_src_file_rel_opt_conf.path_abs_stx_of_name( py_file.name)), transformation=to_upper_transformer.abstract_syntax, ), ignore_exit_code=True, ) instruction_syntax = instr_abs_stx.create_w_explicit_contents( dst_file_rel_opt_conf.path_abs_stx_of_name(expected_file.name), program_string_source_syntax, ) instruction_checker = self.conf.instruction_checker parser = self.conf.parser() for source_case in equivalent_source_variants__with_source_check__consume_last_line__abs_stx( instruction_syntax): with self.subTest(source_case.name): source = source_case.value.source # ACT # instruction = parser.parse(ARBITRARY_FS_LOCATION_INFO, source) # ASSERT # source_case.value.expectation.apply_with_message( self, source, 'source-after-parse') # ACT & ASSERT # instruction_checker.check( self, instruction, self.conf.arrangement( pre_contents_population_action= SETUP_CWD_INSIDE_SDS_BUT_NOT_A_SDS_DIR, symbols=symbols, tcds_contents=py_src_file_rel_opt_conf. populator_for_relativity_option_root( DirContents([py_file]))), self.conf.expect_success( symbol_usages=asrt.matches_sequence([ to_upper_transformer.reference_assertion, ]), main_side_effects_on_sds=non_hds_dir_contains_exactly( dst_file_rel_opt_conf.root_dir__non_hds, fs.DirContents([expected_file])), ))
def test_non_transformer_components(self): # ARRANGE # relativity_cases = [ NArrEx( 'pre SDS validation failure', RelOptionType.REL_HDS_CASE, ValidationAssertions.pre_sds_fails__w_any_msg(), ), NArrEx( 'post SDS validation failure', RelOptionType.REL_ACT, ValidationAssertions.post_sds_fails__w_any_msg(), ), ] def make_pgm_w_ref_to_executable_file( relativity: RelOptionType) -> ProgramAbsStx: return program_abs_stx.ProgramOfExecutableFileCommandLineAbsStx( path_abs_stx.RelOptPathAbsStx(relativity, 'non-existing-file')) def make_pgm_w_ref_to_stdin_file( relativity: RelOptionType) -> ProgramAbsStx: return program_abs_stx.FullProgramAbsStx( program_abs_stx.ProgramOfSystemCommandLineAbsStx.of_str( 'a-system-command'), stdin=string_source_abs_stx.StringSourceOfFileAbsStx( path_abs_stx.RelOptPathAbsStx(relativity, 'non-existing-file'))) def make_pgm_w_ref_to_argument_file( relativity: RelOptionType) -> ProgramAbsStx: return program_abs_stx.ProgramOfSystemCommandLineAbsStx.of_str( 'a-system-command', [ ArgumentOfExistingPathAbsStx( path_abs_stx.RelOptPathAbsStx(relativity, 'non-existing-file')) ]) program_cases = [ NameAndValue( 'missing executable file', make_pgm_w_ref_to_executable_file, ), NameAndValue( 'missing argument file', make_pgm_w_ref_to_argument_file, ), NameAndValue( 'missing stdin file', make_pgm_w_ref_to_stdin_file, ), ] for relativity_case in relativity_cases: for program_case in program_cases: string_source_syntax = string_source_abs_stx.StringSourceOfProgramAbsStx( ProcOutputFile.STDOUT, program_case.value(relativity_case.arrangement), ignore_exit_code=False, ) # ACT & ASSERT # checker = integration_check.checker__w_arbitrary_file_relativities( ) with self.subTest(step=relativity_case.name, program=program_case.name): checker.check__abs_stx__layouts__source_variants__wo_input( self, equivalent_source_variants__for_full_line_expr_parse__s__nsc, OptionallyOnNewLine(string_source_syntax), arrangement_w_tcds(), MultiSourceExpectation(execution=ExecutionExpectation( validation=relativity_case.expectation)))
def test_string_transformer_should_be_parsed_as_simple_expression(self): the_layout = LayoutSpec.of_default() output_from_program = 'untransformed output from the program' sym_ref_program_syntax = ProgramOfSymbolReferenceAbsStx( 'PROGRAM_THAT_EXECUTES_PY_FILE') str_trans__unused = StringTransformerSymbolReferenceAbsStx( 'UNUSED_TRANSFORMER') program_w_complex_str_trans_wo_parentheses = program_abs_stx.FullProgramAbsStx( ProgramOfSymbolReferenceAbsStx(sym_ref_program_syntax.symbol_name), transformation=str_trans_abs_stx. StringTransformerCompositionAbsStx( [ TO_UPPER_TRANSFORMER_SYMBOL.abstract_syntax, str_trans__unused, ], within_parens=False, allow_elements_on_separate_lines=False, )) expected_remaining_tokens = TokenSequence.concat([ TokenSequence.singleton( str_trans_abs_stx.names.SEQUENCE_OPERATOR_NAME), str_trans__unused.tokenization(), ]) expected_remaining_source = expected_remaining_tokens.layout( the_layout) checker = integration_check.checker__w_arbitrary_file_relativities() py_program_file = File( 'program.py', py_programs.py_pgm_with_stdout_stderr_exit_code( exit_code=0, stdout_output=output_from_program, stderr_output=output_from_program, ), ) py_file_rel_conf = rel_opt.conf_rel_any(RelOptionType.REL_HDS_CASE) py_file_conf = py_file_rel_conf.named_file_conf(py_program_file.name) program_symbol__that_executes_py_file = ProgramSymbolContext.of_sdv( sym_ref_program_syntax.symbol_name, program_sdvs.interpret_py_source_file_that_must_exist( py_file_conf.path_sdv)) symbols = [ program_symbol__that_executes_py_file, TO_UPPER_TRANSFORMER_SYMBOL, ] for output_file in ProcOutputFile: for ignore_exit_code in [False, True]: syntax = string_source_abs_stx.StringSourceOfProgramAbsStx( output_file, program_w_complex_str_trans_wo_parentheses, ignore_exit_code=ignore_exit_code, ) with self.subTest(output_file=output_file, ignore_exit_code=ignore_exit_code): checker.check__abs_stx__wo_input( self, syntax, arrangement_w_tcds( symbols=SymbolContext.symbol_table_of_contexts( symbols), tcds_contents=py_file_rel_conf. populator_for_relativity_option_root( DirContents([py_program_file]))), Expectation( ParseExpectation( source=asrt_source.source_is_not_at_end( remaining_source=asrt.equals( expected_remaining_source)), symbol_references=SymbolContext. references_assertion_of_contexts(symbols), )), the_layout, )
def _check_exit_codes(self, exit_code_cases: List[int], ignore_exit_code: bool, expected_primitive: Callable[[str], Assertion[StringSource]], ): # ARRANGE # program_output = { ProcOutputFile.STDOUT: 'output on stdout', ProcOutputFile.STDERR: 'output on stderr', } transformer = TO_UPPER_TRANSFORMER_SYMBOL sym_ref_program = ProgramOfSymbolReferenceAbsStx('PROGRAM_SYMBOL_NAME') program_builder = program_abs_stx.TransformableProgramAbsStxBuilder( ProgramOfSymbolReferenceAbsStx(sym_ref_program.symbol_name) ) program_cases = [ ProgramAndSymbolsCase( 'without transformation', program_builder.without_transformation(), [], adapt_expected_program_output=lambda s: s ), ProgramAndSymbolsCase( 'with transformation', program_builder.with_transformation(transformer.abstract_syntax), [transformer], adapt_expected_program_output=str.upper ), ] program_builder.with_and_without_transformer_cases(transformer.abstract_syntax) py_file_rel_conf = rel_opt.conf_rel_any(RelOptionType.REL_HDS_CASE) for exit_code in exit_code_cases: py_file = File('exit-with-hard-coded-exit-code.py', py_programs.py_pgm_with_stdout_stderr_exit_code( exit_code=exit_code, stdout_output=program_output[ProcOutputFile.STDOUT], stderr_output=program_output[ProcOutputFile.STDERR], ), ) py_file_conf = py_file_rel_conf.named_file_conf(py_file.name) program_symbol = ProgramSymbolContext.of_sdv( sym_ref_program.symbol_name, program_sdvs.interpret_py_source_file_that_must_exist(py_file_conf.path_sdv) ) for output_file in ProcOutputFile: for program_case in program_cases: syntax = string_source_abs_stx.StringSourceOfProgramAbsStx( output_file, program_case.syntax, ignore_exit_code=ignore_exit_code, ) expected_program_output = program_case.adapt_expected_program_output(program_output[output_file]) symbol_contexts = [program_symbol] + program_case.additional_symbols # ACT && ASSERT # checker = integration_check.checker__w_arbitrary_file_relativities() with self.subTest(exit_code=exit_code, output_file=output_file, program=program_case.name): checker.check__abs_stx( self, syntax, None, arrangement_w_tcds( symbols=SymbolContext.symbol_table_of_contexts(symbol_contexts), tcds_contents=py_file_rel_conf.populator_for_relativity_option_root( DirContents([py_file]) ) ), Expectation( ParseExpectation( symbol_references=SymbolContext.references_assertion_of_contexts(symbol_contexts), ), primitive=prim_asrt__constant( expected_primitive(expected_program_output) ), ), ),
def test_syntax_layout_variants(self): # ARRANGE # exit_code_from_program = 1 output_from_program = 'the output from the program' transformer = TO_UPPER_TRANSFORMER_SYMBOL sym_ref_program = ProgramOfSymbolReferenceAbsStx('PROGRAM_SYMBOL_NAME') program_builder = program_abs_stx.TransformableProgramAbsStxBuilder( ProgramOfSymbolReferenceAbsStx(sym_ref_program.symbol_name) ) output_cases = [ OutputFileCase( ProcOutputFile.STDOUT, { ProcOutputFile.STDOUT: output_from_program, ProcOutputFile.STDERR: '', } ), OutputFileCase( ProcOutputFile.STDERR, { ProcOutputFile.STDOUT: '', ProcOutputFile.STDERR: output_from_program, } ), ] program_cases = [ ProgramAndSymbolsCase( 'without transformation', program_builder.without_transformation(), [], adapt_expected_program_output=lambda s: s ), ProgramAndSymbolsCase( 'with transformation', program_builder.with_transformation(transformer.abstract_syntax), [transformer], adapt_expected_program_output=str.upper ), ] py_file_rel_conf = rel_opt.conf_rel_any(RelOptionType.REL_HDS_CASE) for output_case in output_cases: py_file = File('exit-with-hard-coded-exit-code.py', py_programs.py_pgm_with_stdout_stderr_exit_code_2( exit_code=exit_code_from_program, output=output_case.program_output, ), ) py_file_conf = py_file_rel_conf.named_file_conf(py_file.name) program_symbol = ProgramSymbolContext.of_sdv( sym_ref_program.symbol_name, program_sdvs.interpret_py_source_file_that_must_exist(py_file_conf.path_sdv) ) for program_case in program_cases: syntax = string_source_abs_stx.StringSourceOfProgramAbsStx( output_case.output_file, program_case.syntax, ignore_exit_code=True, ) expected_program_output = program_case.adapt_expected_program_output(output_from_program) symbol_contexts = [program_symbol] + program_case.additional_symbols # ACT && ASSERT # checker = integration_check.checker__w_arbitrary_file_relativities() with self.subTest(output_file=output_case.output_file, program=program_case.name): checker.check__abs_stx__layouts__source_variants__wo_input( self, equivalent_source_variants__for_full_line_expr_parse__s__nsc, OptionallyOnNewLine(syntax), arrangement_w_tcds( symbols=SymbolContext.symbol_table_of_contexts(symbol_contexts), tcds_contents=py_file_rel_conf.populator_for_relativity_option_root( DirContents([py_file]) ) ), MultiSourceExpectation.of_const( symbol_references=SymbolContext.references_assertion_of_contexts(symbol_contexts), primitive=asrt_string_source.pre_post_freeze__matches_str__const_2( expected_program_output, may_depend_on_external_resources=True, frozen_may_depend_on_external_resources=asrt.anything_goes(), ), ), ),
def _check_exit_codes(self, exit_code_cases: List[int], ignore_exit_code: bool, main_result: Assertion[Optional[TextRenderer]], expected_output_dir_contents: Optional[Callable[[str, str], DirContents]], ): # ARRANGE # destination_file_name = 'dst-file.txt' program_output = { ProcOutputFile.STDOUT: 'output on stdout', ProcOutputFile.STDERR: 'output on stderr', } transformer = TO_UPPER_TRANSFORMER_SYMBOL sym_ref_program = ProgramOfSymbolReferenceAbsStx('PROGRAM_SYMBOL_NAME') program_builder = program_abs_stx.TransformableProgramAbsStxBuilder( ProgramOfSymbolReferenceAbsStx(sym_ref_program.symbol_name) ) program_cases = [ ProgramAndSymbolsCase( 'without transformation', program_builder.without_transformation(), [], adapt_expected_program_output=lambda s: s ), ProgramAndSymbolsCase( 'with transformation', program_builder.with_transformation(transformer.abstract_syntax), [transformer], adapt_expected_program_output=str.upper ), ] program_builder.with_and_without_transformer_cases(transformer.abstract_syntax) py_file_rel_conf = rel_opt.conf_rel_any(RelOptionType.REL_HDS_CASE) dst_file_rel_conf = ARBITRARY_ALLOWED_DST_FILE_RELATIVITY for output_file in ProcOutputFile: for exit_code in exit_code_cases: py_file = File('exit-with-hard-coded-exit-code.py', py_programs.py_pgm_with_stdout_stderr_exit_code( exit_code=exit_code, stdout_output=program_output[ProcOutputFile.STDOUT], stderr_output=program_output[ProcOutputFile.STDERR], ), ) py_file_conf = py_file_rel_conf.named_file_conf(py_file.name) dst_file_conf = dst_file_rel_conf.named_file_conf(destination_file_name) program_symbol = ProgramSymbolContext.of_sdv( sym_ref_program.symbol_name, program_sdvs.interpret_py_source_file_that_must_exist(py_file_conf.path_sdv) ) for program_case in program_cases: instruction_syntax = instr_abs_stx.create_w_explicit_contents( dst_file_conf.abstract_syntax, string_source_abs_stx.StringSourceOfProgramAbsStx( output_file, program_case.syntax, ignore_exit_code=ignore_exit_code) ) expected_program_output = program_case.adapt_expected_program_output(program_output[output_file]) main_side_effects_on_sds = ( dst_file_rel_conf.assert_root_dir_contains_exactly( expected_output_dir_contents(dst_file_conf.name, expected_program_output) ) if expected_output_dir_contents is not None else asrt.anything_goes() ) symbol_contexts = [program_symbol] + program_case.additional_symbols # ACT && ASSERT # for phase_is_after_act in [False, True]: checker = integration_check.checker(phase_is_after_act) checker.check__abs_stx__std_layouts_and_source_variants( self, instruction_syntax, Arrangement.phase_agnostic( symbols=SymbolContext.symbol_table_of_contexts(symbol_contexts), tcds=TcdsArrangement( tcds_contents=py_file_rel_conf.populator_for_relativity_option_root( DirContents([py_file]) ) ), ), MultiSourceExpectation.phase_agnostic( symbol_usages=SymbolContext.usages_assertion_of_contexts(symbol_contexts), main_result=main_result, main_side_effects_on_sds=main_side_effects_on_sds, ), sub_test_identifiers={ 'exit_code': exit_code, 'output_file': output_file, 'program': program_case.name, 'phase_is_after_act': phase_is_after_act, }, )
def _test(self, text_printed_by_program: str, expected_file_contents: str, make_arguments: Callable[[TransformableProgramAbsStxBuilder], ProgramAbsStx], additional_symbols: Dict[str, SymbolContainer], additional_symbol_references: List[Assertion[SymbolReference]], ): expected_file = fs.File('a-file-name.txt', expected_file_contents) for proc_output_file in ProcOutputFile: python_source = py_programs.single_line_pgm_that_prints_to(proc_output_file, text_printed_by_program) program_that_executes_py_source_symbol = ProgramSymbolContext.of_sdv( 'PROGRAM_THAT_EXECUTES_PY_SOURCE', program_sdvs.for_py_source_on_command_line(python_source) ) program_cases = [ ProgramCase( 'python interpreter', program_abs_stx.ProgramOfPythonInterpreterAbsStx.of_execute_python_src_string(python_source), [] ), ProgramCase( 'symbol reference program', ProgramOfSymbolReferenceAbsStx(program_that_executes_py_source_symbol.name), [program_that_executes_py_source_symbol.reference_assertion], ), ] symbols_dict = { program_that_executes_py_source_symbol.name: program_that_executes_py_source_symbol.symbol_table_container, } symbols_dict.update(additional_symbols) symbols = SymbolTable(symbols_dict) for program_case in program_cases: program_syntax_builder = TransformableProgramAbsStxBuilder(program_case.source) program_syntax = make_arguments(program_syntax_builder) rel_opt_conf = ARBITRARY_ALLOWED_DST_FILE_RELATIVITY expected_symbol_references = program_case.expected_references + additional_symbol_references instruction_syntax = instr_abs_stx.create_w_explicit_contents( rel_opt_conf.path_abs_stx_of_name(expected_file.name), string_source_abs_stx.StringSourceOfProgramAbsStx(proc_output_file, program_syntax, ignore_exit_code=False) ) with self.subTest(relativity_option_string=str(rel_opt_conf.option_argument), program=program_case.name, output_channel=proc_output_file): integration_check.CHECKER__BEFORE_ACT.check__abs_stx__layout_and_source_variants( self, instruction_syntax, Arrangement.phase_agnostic( symbols=symbols, tcds=TcdsArrangement(), ), MultiSourceExpectation.phase_agnostic( main_result=IS_SUCCESS, side_effects_on_hds=f_asrt.dir_is_empty(), symbol_usages=asrt.matches_sequence(expected_symbol_references), main_side_effects_on_sds=non_hds_dir_contains_exactly(rel_opt_conf.root_dir__non_hds, fs.DirContents([expected_file])), ) )