def _check(self, root_suite_file: File, suite_and_case_files: DirContents, expectation: ExpectedRecordingsAssertionConstructor, ): case_processors = [ NameAndValue('processor_that_should_not_pollute_current_process', processors.new_processor_that_should_not_pollute_current_process), NameAndValue('processor_that_is_allowed_to_pollute_current_process', processors.new_processor_that_is_allowed_to_pollute_current_process), ] with tmp_dir_as_cwd(suite_and_case_files) as abs_cwd_dir_path: suite_file_path = Path(root_suite_file.name) for case_processor_case in case_processors: with self.subTest(case_processor_case.name): recording_media = [] processor = self._new_processor(recording_media, case_processor_case.value) # ACT # return_value = processor.process(suite_file_path, null_output_files()) # ASSERT # self.assertEqual(ProcessingReporterThatDoesNothing.VALID_SUITE_EXIT_CODE, return_value, 'Sanity check of result indicator') expected_instruction_recording = expectation.assertion(abs_cwd_dir_path) expected_instruction_recording.apply_with_message(self, recording_media, 'recordings'),
def test_succeed(self): # ARRANGE # existing_dir = Dir.empty('a-dir') cwd_contents = DirContents([existing_dir]) cases = [ NameAndValue( 'existing dir', existing_dir.name_as_path, ), NameAndValue( 'non-existing dir', existing_dir.name_as_path / 'non-existing', ), NameAndValue( 'non-existing dir / multiple non-existing path components', existing_dir.name_as_path / 'non-existing-1' / 'non-existing-2', ), ] with tmp_dir.tmp_dir_as_cwd(cwd_contents): for case in cases: with self.subTest(case.name): path = case.value # ACT # sut.ensure_directory_exists(path) # ASSERT # self.assertTrue(path.is_dir())
def runTest(self): # ARRANGE cwd_registerer = CwdRegisterer() with tmp_dir_as_cwd() as expected_current_directory_pre_validate_post_setup: atc_that_records_current_dir = _ActionToCheckThatRecordsCurrentDir(cwd_registerer) actor = ActorForConstantAtc(atc_that_records_current_dir) # ACT # _execute(actor, _empty_test_case(), current_directory=expected_current_directory_pre_validate_post_setup) # ASSERT # phase_step_2_cwd = cwd_registerer.phase_step_2_cwd sds = atc_that_records_current_dir.actual_sds self.assertEqual(len(phase_step_2_cwd), 4, 'Expects recordings for 4 steps') self.assertEqual(phase_step_2_cwd[phase_step.ACT__VALIDATE_PRE_SDS], expected_current_directory_pre_validate_post_setup, 'Current dir for ' + str(phase_step.ACT__VALIDATE_PRE_SDS)) self.assertEqual(phase_step_2_cwd[phase_step.ACT__VALIDATE_POST_SETUP], sds.act_dir, 'Current dir for ' + str(phase_step.ACT__VALIDATE_POST_SETUP)) self.assertEqual(phase_step_2_cwd[phase_step.ACT__PREPARE], sds.act_dir, 'Current dir for ' + str(phase_step.ACT__PREPARE)) self.assertEqual(phase_step_2_cwd[phase_step.ACT__EXECUTE], sds.act_dir, 'Current dir for ' + str(phase_step.ACT__EXECUTE))
def runTest(self): # ARRANGE cwd_registerer = CwdRegisterer() with tmp_dir_as_cwd( ) as expected_current_directory_pre_validate_post_setup: atc_that_records_current_dir = _ActionToCheckThatRecordsCurrentDir( cwd_registerer) actor = ActorForConstantAtc(atc_that_records_current_dir) # ACT # _execute(actor, _empty_test_case(), current_directory= expected_current_directory_pre_validate_post_setup) # ASSERT # phase_step_2_cwd = cwd_registerer.phase_step_2_cwd sds = atc_that_records_current_dir.actual_sds self.assertEqual(len(phase_step_2_cwd), 4, 'Expects recordings for 4 steps') self.assertEqual( phase_step_2_cwd[phase_step.ACT__VALIDATE_PRE_SDS], expected_current_directory_pre_validate_post_setup, 'Current dir for ' + str(phase_step.ACT__VALIDATE_PRE_SDS)) self.assertEqual( phase_step_2_cwd[phase_step.ACT__VALIDATE_POST_SETUP], sds.act_dir, 'Current dir for ' + str(phase_step.ACT__VALIDATE_POST_SETUP)) self.assertEqual(phase_step_2_cwd[phase_step.ACT__PREPARE], sds.act_dir, 'Current dir for ' + str(phase_step.ACT__PREPARE)) self.assertEqual(phase_step_2_cwd[phase_step.ACT__EXECUTE], sds.act_dir, 'Current dir for ' + str(phase_step.ACT__EXECUTE))
def _expect_successful_parse(self, cwd_contents: DirContents, arguments: List[str], expected_file_path: Path): with tmp_dir_as_cwd(cwd_contents): actual_settings = sut.parse(self.handling_setup, arguments) self.assertEqual(expected_file_path, actual_settings.suite_root_file_path)
def test_relative_path_to_root_file_in_sub_dir_of_cwd(self): # ARRANGE # root_file_sub_dir_path = Path('sub-dir') root_file_in_sub_dir = file_with_lines('root-file-base-name.src', [ phase_names.CONFIGURATION.syntax, INSTR_THAT_ASSERTS_SOURCE_INFO_MATCHES_LOCATION, ]) cwd_dir_contents = DirContents([ Dir(str(root_file_sub_dir_path), [ root_file_in_sub_dir, ]) ]) file_arg_to_parser_rel_cwd = root_file_sub_dir_path / root_file_in_sub_dir.name with tmp_dir_as_cwd(cwd_dir_contents) as abs_cwd_dir_path: instruction_parser_file_loc_assertion = matches_file_location_info( abs_path_of_dir_containing_first_file_path=asrt.equals(abs_cwd_dir_path), file_path_rel_referrer=asrt.equals(file_arg_to_parser_rel_cwd), file_inclusion_chain=asrt.is_empty_sequence, ) # ACT & ASSERT # fail_if_test_case_does_not_pass( self, file_arg_to_parser_rel_cwd, test_case_definition_with_config_phase_assertion_instruction(self, instruction_parser_file_loc_assertion))
def test_relative_path_to_root_file_in_sub_dir_of_cwd(self): # ARRANGE # root_file_sub_dir_path = Path('sub-dir') root_file_base_name = 'root-file-base-name.src' root_file_in_sub_dir = file_with_lines(root_file_base_name, [ phase_names.CONFIGURATION.syntax, INSTR_THAT_ASSERTS_HDS_DIR_MATCHES_PATH, ]) cwd_dir_contents = DirContents( [Dir(str(root_file_sub_dir_path), [ root_file_in_sub_dir, ])]) file_arg_to_parser_rel_cwd = root_file_sub_dir_path / root_file_base_name with tmp_dir_as_cwd(cwd_dir_contents) as abs_cwd_dir_path: hds_dir_assertion = asrt.equals(abs_cwd_dir_path / root_file_sub_dir_path) # ACT & ASSERT # fail_if_test_case_does_not_pass( self, file_arg_to_parser_rel_cwd, test_case_definition_with_config_phase_assertion_instruction( self, hds_dir_assertion))
def test_relative_path_to_root_file_in_sub_dir_of_cwd(self): # ARRANGE # root_file_sub_dir_path = Path('sub-dir') root_file_in_sub_dir = file_with_lines('root-file-base-name.src', [ phase_names.CONFIGURATION.syntax, INSTR_THAT_ASSERTS_SOURCE_INFO_MATCHES_LOCATION, ]) cwd_dir_contents = DirContents([ Dir(str(root_file_sub_dir_path), [ root_file_in_sub_dir, ]) ]) file_arg_to_parser_rel_cwd = root_file_sub_dir_path / root_file_in_sub_dir.name with tmp_dir_as_cwd(cwd_dir_contents) as abs_cwd_dir_path: instruction_parser_file_loc_assertion = matches_file_location_info( abs_path_of_dir_containing_first_file_path=asrt.equals(abs_cwd_dir_path), file_path_rel_referrer=asrt.equals(file_arg_to_parser_rel_cwd), file_inclusion_chain=asrt.is_empty_sequence, ) # ACT & ASSERT # fail_if_test_case_does_not_pass( self, file_arg_to_parser_rel_cwd, test_case_definition_with_config_phase_assertion_instruction(self, instruction_parser_file_loc_assertion))
def test_with_error_of_path_below_relativity_root__file_names_from_applied_hierarchy_reader(self): # ARRANGE # elapsed_time = datetime.timedelta(seconds=1) num_test_cases = 6 case_file = empty_file('test.case') suite_file = File('test.suite', lines_content([case_file.name])) dir_with_suite = Dir('dir-with-suite', [suite_file, case_file]) with tmp_dir_as_cwd(DirContents([dir_with_suite])) as cwd_abs_path: read_suite_hierarchy = Reader(default_environment()).apply(dir_with_suite.name_as_path / suite_file.name) self.assertEqual(1, len(read_suite_hierarchy.test_cases), 'Sanity check: number of read cases') test_case_file_reference = read_suite_hierarchy.test_cases[0] the_exit_value = ExitValue(4, 'exit_identifier_4', ForegroundColor.RED) errors = {the_exit_value: [ test_case_file_reference, ], } # ACT # actual_lines = sut.format_final_result_for_valid_suite(num_test_cases, elapsed_time, cwd_abs_path, errors) # ASSERT # self._assert_at_least_one_line_was_generated(actual_lines) self._assert_line_is_number_of_executed_tests_line(actual_lines[0], num_test_cases) self.assertListEqual(['', the_exit_value.exit_identifier, ' ' + str(dir_with_suite.name_as_path / case_file.name_as_path), ], actual_lines[1:], 'Lines after "Ran ..."')
def _expect_successful_parse(self, cwd_contents: DirContents, arguments: List[str], expected_file_path: Path): with tmp_dir_as_cwd(cwd_contents): actual_settings = sut.parse(self.handling_setup, arguments) self.assertEqual(expected_file_path, actual_settings.suite_root_file_path)
def check_and_expect_exception(put: unittest.TestCase, arrangement: Arrangement, expected_exception: ValueAssertion[Exception]): with tmp_dir_as_cwd(arrangement.cwd_dir_contents): with put.assertRaises(Exception) as cm: # ACT & ASSERT # sut.parse(arrangement.sections_configuration, arrangement.root_file) expected_exception.apply_with_message(put, cm.exception, 'Exception')
def capture_output_from_main_program__in_tmp_dir( command_line_arguments: List[str], cwd_contents: DirContents, main_pgm: main_program.MainProgram, ) -> SubProcessResult: with tmp_dir_as_cwd(cwd_contents): return capture_output_from_main_program(command_line_arguments, main_pgm)
def _check_failing_line(self, configuration: sut.Configuration, phases: Sequence[Phase], invalid_line_cases: Sequence[NameAndValue[SourceAndStatus]]): proc_cases = [ NameAndValue('not allowed to pollute current process', sut.new_processor_that_should_not_pollute_current_process(configuration)), NameAndValue('allowed to pollute current process', sut.new_processor_that_is_allowed_to_pollute_current_process(configuration)), ] for phase in phases: for invalid_line_case in invalid_line_cases: source_and_status = invalid_line_case.value assert isinstance(source_and_status, SourceAndStatus) # Type info for IDE file_with_error = fs.file_with_lines('file-with-error.src', [ source_and_status.failing_source_line, ]) erroneous_line = single_line_sequence(1, source_and_status.failing_source_line) test_case_file = fs.file_with_lines('test.case', [ section_header(phase.section_name), directive_for_inclusion_of_file(file_with_error.name), ]) line_that_includes_erroneous_file = single_line_sequence(2, directive_for_inclusion_of_file( file_with_error.name)) cwd_contents = fs.DirContents([test_case_file, file_with_error]) expected_source_location_path = SourceLocationPath( location=SourceLocation(erroneous_line, pathlib.Path(file_with_error.name)), file_inclusion_chain=[SourceLocation(line_that_includes_erroneous_file, pathlib.Path(test_case_file.name))]) for proc_case in proc_cases: with self.subTest(phase=phase.section_name, proc=proc_case.name, line=erroneous_line.first_line): processor = proc_case.value assert isinstance(processor, Processor) with tmp_dir_as_cwd(cwd_contents): test_case_reference = test_case_reference_of_source_file(pathlib.Path(test_case_file.name)) # ACT # result = processor.apply(test_case_reference) # ASSERT # assert isinstance(result, Result) # Type info for IDE source_and_status.expected_result_statuses.apply_with_message(self, result, 'result statuses') source_location_path_expectation = equals_source_location_path( expected_source_location_path) source_location_path_expectation.apply_with_message(self, result.source_location_path, 'source location path')
def _expect_raise_argument_parsing_error(self, cwd_contents: DirContents, arguments: List[str]): with tmp_dir_as_cwd(cwd_contents): with self.assertRaises(ArgumentParsingError): sut.parse(self.TEST_CASE_HANDLING_SETUP, sandbox_root_name_resolver.for_test(), arguments, {})
def check(put: unittest.TestCase, arrangement: Arrangement, expectation: Expectation): # ARRANGE # with tmp_dir_as_cwd(arrangement.cwd_dir_contents): # ACT # actual = sut.parse(arrangement.sections_configuration, arrangement.root_file) # ASSERT # expectation.document.apply_without_message(put, actual)
def check(put: unittest.TestCase, command_line_arguments: List[str], arrangement: Arrangement, expectation: Assertion[SubProcessResult]): # ARRANGE # main_program = main_program_from_config(arrangement.main_program_config) with tmp_dir_as_cwd(arrangement.cwd_contents): # ACT # result = capture_output_from_main_program(command_line_arguments, main_program) # ASSERT # expectation.apply_without_message(put, result)
def check_with_tmp_dir_contents(setup: SetupWithTmpCwdDirContents, put: unittest.TestCase, runner: Callable[[unittest.TestCase, List[str]], SubProcessResult]): with tmp_dir_as_cwd() as tmp_dir_path: setup.file_structure(tmp_dir_path).write_to(tmp_dir_path) arguments = setup.arguments(tmp_dir_path) sub_process_result = runner(put, arguments) setup.check(put, tmp_dir_path, sub_process_result)
def check_with_tmp_dir_contents(setup: SetupWithTmpCwdDirContents, put: unittest.TestCase, runner: Callable[[unittest.TestCase, List[str]], SubProcessResult]): with tmp_dir_as_cwd() as tmp_dir_path: setup.file_structure(tmp_dir_path).write_to(tmp_dir_path) arguments = setup.arguments(tmp_dir_path) sub_process_result = runner(put, arguments) setup.check(put, tmp_dir_path, sub_process_result)
def _run(self, test_case_runner: TestCaseRunner, suite_file_name: str, suite_file_overriding: Optional[Path]): # ARRANGE # expected_instruction_recording = [ # First test case SETUP_INSTRUCTION_IN_CONTAINING_SUITE, SETUP_INSTRUCTION_IN_CASE, ] suite_file = File( suite_file_name, SUITE_WITH_SETUP_INSTRUCTION.format( marker=SETUP_INSTRUCTION_IN_CONTAINING_SUITE)) case_file = File( 'test.case', CASE_THAT_REGISTERS_MARKER.format( marker=SETUP_INSTRUCTION_IN_CASE)) sub_dir_path = Path('dir-containing-test-case') suite_and_case_files = DirContents([ suite_file, case_file, ]) explicit_suite_file_path = None if suite_file_overriding: explicit_suite_file_path = sub_dir_path / suite_file_overriding recording_media = [] test_case_parsing_setup = TestCaseParsingSetup( space_separator_instruction_name_extractor, instruction_setup_with_setup_instructions( REGISTER_INSTRUCTION_NAME, recording_media), ActPhaseParser()) test_case_handling_setup = test_case_handling_setup_with_identity_preprocessor( ) test_suite_definition = test_suite_definition_without_instructions() # ACT # with tmp_dir_as_cwd(suite_and_case_files.in_dir_path(sub_dir_path)): actual_result = test_case_runner.run( test_case_parsing_setup, test_case_handling_setup, test_suite_definition, sub_dir_path / case_file.name_as_path, explicit_suite_file_path) # ASSERT # self.assertEqual(exit_values.EXECUTION__PASS.exit_code, actual_result.exitcode, 'Sanity check of result indicator') recordings = list(map(Recording.string.fget, recording_media)) self.assertEqual(expected_instruction_recording, recordings)
def check(setup: Setup, put: unittest.TestCase): # ARRANGE # with tmp_dir_as_cwd() as tmp_dir_path: setup.file_structure_to_read(tmp_dir_path).write_to(tmp_dir_path) # ACT # actual = Reader(default_environment()).apply( setup.root_suite_based_at(tmp_dir_path)) # ASSERT # expected = setup.expected_structure_based_at(tmp_dir_path) expected.apply_without_message(put, actual)
def check(setup: Setup, put: unittest.TestCase): # ARRANGE # with tmp_dir_as_cwd() as tmp_dir_path: setup.file_structure_to_read(tmp_dir_path).write_to(tmp_dir_path) # ACT # actual = Reader(default_environment()).apply(setup.root_suite_based_at(tmp_dir_path)) # ASSERT # expected = setup.expected_structure_based_at(tmp_dir_path) expected.apply_without_message(put, actual)
def check(put: unittest.TestCase, command_line_arguments: List[str], arrangement: Arrangement, expectation: ValueAssertion[SubProcessResult]): # ARRANGE # main_program = main_program_from_config(arrangement.main_program_config) with tmp_dir_as_cwd(arrangement.cwd_contents): # ACT # result = capture_output_from_main_program(command_line_arguments, main_program) # ASSERT # expectation.apply_without_message(put, result)
def _run(self, suite_file_name: str, run_as_part_of_explicit_suite: Optional[Path]): # ARRANGE # default_test_case_handling = setup_with_null_act_phase_and_null_preprocessing( ) conf_parser_with_no_instructions = configuration_section_parser({}) test_case_definition = test_case_definition_with_only_assert_phase_instructions( []) case_file = File.empty('test.case') suite_file = File( suite_file_name, lines_content([ phase_names.ASSERT.syntax, ' '.join([ INCLUDING_DIRECTIVE_INFO.singular_name, 'non-existing-file.txt' ]), ])) suite_and_case_files = DirContents([ suite_file, case_file, ]) processor = sut.Processor( test_case_definition, os_services_access.new_for_cmd_exe( CommandExecutorThatJustReturnsConstant()), conf_parser_with_no_instructions, 2**10) with tmp_dir_as_cwd(suite_and_case_files) as tmp_dir: execution_settings = TestCaseExecutionSettings( case_file.name_as_path, tmp_dir, ReportingOption.STATUS_CODE, default_test_case_handling, run_as_part_of_explicit_suite=run_as_part_of_explicit_suite) # ACT # actual_result = capture_output_from_processor( processor, execution_settings) # ASSERT # expectation = is_result_for_exit_value( exit_values.NO_EXECUTION__FILE_ACCESS_ERROR) expectation.apply_without_message(self, actual_result)
def test_inclusion_of_non_exiting_file_SHOULD_cause_file_access_error( self): # ARRANGE # name_of_non_existing_file = 'non-existing.src' configuration = configuration_with_no_instructions_and_no_preprocessor( ) proc_cases = [ NameAndValue( 'not allowed to pollute current process', sut.new_processor_that_should_not_pollute_current_process( configuration)), NameAndValue( 'allowed to pollute current process', sut.new_processor_that_is_allowed_to_pollute_current_process( configuration)), ] for phase in phase_identifier.ALL_WITH_INSTRUCTIONS: for proc_case in proc_cases: with self.subTest(phase.section_name, proc=proc_case.name): test_case_file = fs.file_with_lines( 'test.case', [ section_header(phase.section_name), directive_for_inclusion_of_file( name_of_non_existing_file), ]) cwd_contents = fs.DirContents([test_case_file]) processor = proc_case.value assert isinstance(processor, Processor) with tmp_dir_as_cwd(cwd_contents): test_case_reference = test_case_reference_of_source_file( pathlib.Path(test_case_file.name)) # ACT # result = processor.apply(test_case_reference) # ASSERT # assert isinstance(result, Result) # Type info for IDE self.assertEqual(Status.ACCESS_ERROR, result.status) self.assertEqual(AccessErrorType.FILE_ACCESS_ERROR, result.access_error_type) source_location_path_expectation = equals_source_location_path( source_location_path_of( pathlib.Path(test_case_file.name), Line( 2, directive_for_inclusion_of_file( name_of_non_existing_file)))) source_location_path_expectation.apply_with_message( self, result.error_info.source_location_path, 'source location path')
def _run(self, suite_file_name: str, run_as_part_of_explicit_suite: Optional[Path]): # ARRANGE # default_test_case_handling = setup_with_null_act_phase_and_null_preprocessing() conf_parser_with_no_instructions = configuration_section_parser({}) test_case_definition = test_case_definition_with_only_assert_phase_instructions([]) case_file = empty_file('test.case') suite_file = File(suite_file_name, lines_content([ phase_names.ASSERT.syntax, ' '.join([ INCLUDING_DIRECTIVE_INFO.singular_name, 'non-existing-file.txt' ]), ])) suite_and_case_files = DirContents([suite_file, case_file, ]) processor = sut.Processor(test_case_definition, AtcOsProcessExecutorThatJustReturnsConstant(), conf_parser_with_no_instructions) with tmp_dir_as_cwd(suite_and_case_files) as tmp_dir: execution_settings = TestCaseExecutionSettings(case_file.name_as_path, tmp_dir, ReportingOption.STATUS_CODE, default_test_case_handling, run_as_part_of_explicit_suite=run_as_part_of_explicit_suite) # ACT # actual_result = capture_output_from_processor(processor, execution_settings) # ASSERT # expectation = is_result_for_exit_value(exit_values.NO_EXECUTION__FILE_ACCESS_ERROR) expectation.apply_without_message(self, actual_result)
def test_inclusion_of_file_SHOULD_be_possible_in_all_phases_except_act( self): # ARRANGE # name_of_recording_instruction = 'recording-instruction' file_to_include = fs.file_with_lines('included-file.src', [ name_of_recording_instruction, ]) proc_cases = [ NameAndValue( 'not allowed to pollute current process', sut.new_processor_that_should_not_pollute_current_process), NameAndValue( 'allowed to pollute current process', sut.new_processor_that_is_allowed_to_pollute_current_process), ] for phase in phase_identifier.ALL_WITH_INSTRUCTIONS: for proc_case in proc_cases: with self.subTest(phase.section_name, proc=proc_case.name): test_case_file = fs.file_with_lines( 'test.case', [ section_header(phase.section_name), directive_for_inclusion_of_file( file_to_include.name), ]) cwd_contents = fs.DirContents( [test_case_file, file_to_include]) recording_output = [] configuration = configuration_with_instruction_in_each_phase_that_records_phase_name( name_of_recording_instruction, recording_output) processor = proc_case.value(configuration) with tmp_dir_as_cwd(cwd_contents): test_case_reference = test_case_reference_of_source_file( pathlib.Path(test_case_file.name)) # ACT # result = processor.apply(test_case_reference) # ASSERT # assert isinstance(result, Result) # Type info for IDE self.assertEqual(Status.EXECUTED, result.status) self.assertFalse(result.execution_result.is_failure) self.assertEqual(FullExeResultStatus.PASS, result.execution_result.status) self.assertEqual([phase.section_name], recording_output)
def test_fail(self): # ARRANGE # regular_file = File.empty('regular-file') cwd_contents = DirContents([regular_file]) cases = [ NameAndValue( 'existing regular file', regular_file.name_as_path, ), NameAndValue( 'middle component that is existing regular file', regular_file.name_as_path / 'non-existing', ), ] with tmp_dir.tmp_dir_as_cwd(cwd_contents): for case in cases: with self.subTest(case.name): with self.assertRaises(OSError): # ACT & ASSERT # sut.ensure_directory_exists(case.value)
def test_inclusion_of_file_SHOULD_be_possible_in_all_phases_except_act(self): # ARRANGE # name_of_recording_instruction = 'recording-instruction' file_to_include = fs.file_with_lines('included-file.src', [ name_of_recording_instruction, ]) proc_cases = [ NameAndValue('not allowed to pollute current process', sut.new_processor_that_should_not_pollute_current_process), NameAndValue('allowed to pollute current process', sut.new_processor_that_is_allowed_to_pollute_current_process), ] for phase in phase_identifier.ALL_WITH_INSTRUCTIONS: for proc_case in proc_cases: with self.subTest(phase.section_name, proc=proc_case.name): test_case_file = fs.file_with_lines('test.case', [ section_header(phase.section_name), directive_for_inclusion_of_file(file_to_include.name), ]) cwd_contents = fs.DirContents([test_case_file, file_to_include]) recording_output = [] configuration = configuration_with_instruction_in_each_phase_that_records_phase_name( name_of_recording_instruction, recording_output) processor = proc_case.value(configuration) with tmp_dir_as_cwd(cwd_contents): test_case_reference = test_case_reference_of_source_file(pathlib.Path(test_case_file.name)) # ACT # result = processor.apply(test_case_reference) # ASSERT # assert isinstance(result, Result) # Type info for IDE self.assertEqual(Status.EXECUTED, result.status) self.assertFalse(result.execution_result.is_failure) self.assertEqual(FullExeResultStatus.PASS, result.execution_result.status) self.assertEqual([phase.section_name], recording_output)
def _when_syntax_error_in_case_phase_contents_then_suite_parsing_should_raise_exception( self): # ARRANGE # suite_file = File( 'the.suite', SUITE_WITH_SYNTAX_ERROR_IN_CASE_PHASE.format( case_phase_header=self._phase_config().phase_name().syntax)) cwd_contents = DirContents([suite_file]) tc_parsing_setup = TestCaseParsingSetup( space_separator_instruction_name_extractor, InstructionsSetup(), SectionElementParserThatRaisesUnrecognizedSectionElementSourceError( )) tc_handling_setup = setup_with_null_act_phase_and_null_preprocessing() reader = suite_hierarchy_reading.Reader( suite_hierarchy_reading.Environment( SectionElementParserThatRaisesUnrecognizedSectionElementSourceError( ), tc_parsing_setup, tc_handling_setup)) with self.assertRaises(SuiteParseError): with tmp_dir_as_cwd(cwd_contents): # ACT & ASSERT # reader.apply(suite_file.name_as_path)
def _check( self, root_suite_file: File, suite_and_case_files: DirContents, expectation: ExpectedRecordingsAssertionConstructor, ): case_processors = [ NameAndValue( 'processor_that_should_not_pollute_current_process', processors. new_processor_that_should_not_pollute_current_process), NameAndValue( 'processor_that_is_allowed_to_pollute_current_process', processors. new_processor_that_is_allowed_to_pollute_current_process), ] with tmp_dir_as_cwd(suite_and_case_files) as abs_cwd_dir_path: suite_file_path = Path(root_suite_file.name) for case_processor_case in case_processors: with self.subTest(case_processor_case.name): recording_media = [] processor = self._new_processor(recording_media, case_processor_case.value) # ACT # return_value = processor.process( suite_file_path, null_output_reporting_environment()) # ASSERT # self.assertEqual( ProcessingReporterThatDoesNothing. VALID_SUITE_EXIT_CODE, return_value, 'Sanity check of result indicator') expected_instruction_recording = expectation.assertion( abs_cwd_dir_path) expected_instruction_recording.apply_with_message( self, recording_media, 'recordings'),
def test_relative_path_to_root_file_in_cwd(self): # ARRANGE # root_file_base_name = 'root-file-base-name.src' root_file_in_cwd = file_with_lines(root_file_base_name, [ phase_names.SETUP.syntax, INSTR_THAT_ASSERTS_ENV_VARS, ]) cwd_dir_contents = DirContents([root_file_in_cwd]) with tmp_dir_as_cwd(cwd_dir_contents): expected_default = None expected_from_defaults_getter = dict(os.environ) # ACT & ASSERT # fail_if_test_case_does_not_pass( self, Path(root_file_base_name), test_case_definition_with_setup_phase_assertion_instruction( self, expected_default, expected_from_defaults_getter))
def test_inclusion_of_non_exiting_file_SHOULD_cause_file_access_error(self): # ARRANGE # name_of_non_existing_file = 'non-existing.src' configuration = configuration_with_no_instructions_and_no_preprocessor() proc_cases = [ NameAndValue('not allowed to pollute current process', sut.new_processor_that_should_not_pollute_current_process(configuration)), NameAndValue('allowed to pollute current process', sut.new_processor_that_is_allowed_to_pollute_current_process(configuration)), ] for phase in phase_identifier.ALL_WITH_INSTRUCTIONS: for proc_case in proc_cases: with self.subTest(phase.section_name, proc=proc_case.name): test_case_file = fs.file_with_lines('test.case', [ section_header(phase.section_name), directive_for_inclusion_of_file(name_of_non_existing_file), ]) cwd_contents = fs.DirContents([test_case_file]) processor = proc_case.value assert isinstance(processor, Processor) with tmp_dir_as_cwd(cwd_contents): test_case_reference = test_case_reference_of_source_file(pathlib.Path(test_case_file.name)) # ACT # result = processor.apply(test_case_reference) # ASSERT # assert isinstance(result, Result) # Type info for IDE self.assertEqual(Status.ACCESS_ERROR, result.status) self.assertEqual(AccessErrorType.FILE_ACCESS_ERROR, result.access_error_type) source_location_path_expectation = equals_source_location_path( source_location_path_of(pathlib.Path(test_case_file.name), Line(2, directive_for_inclusion_of_file(name_of_non_existing_file)))) source_location_path_expectation.apply_with_message(self, result.error_info.source_location_path, 'source location path')
def test_abs_path_to_root_file_in_cwd(self): # ARRANGE # root_file_base_name = 'root-file-base-name.src' root_file_in_cwd = file_with_lines(root_file_base_name, [ phase_names.CONFIGURATION.syntax, INSTR_THAT_ASSERTS_HDS_DIR_MATCHES_PATH, ]) cwd_dir_contents = DirContents([root_file_in_cwd]) with tmp_dir_as_cwd(cwd_dir_contents) as abs_cwd_dir_path: abs_file_arg_to_parser = abs_cwd_dir_path / root_file_base_name hds_dir_assertion = asrt.equals(abs_cwd_dir_path) # ACT & ASSERT # fail_if_test_case_does_not_pass( self, abs_file_arg_to_parser, test_case_definition_with_config_phase_assertion_instruction( self, hds_dir_assertion))
def _when_syntax_error_in_case_phase_contents_then_suite_parsing_should_raise_exception(self): # ARRANGE # suite_file = File( 'the.suite', SUITE_WITH_SYNTAX_ERROR_IN_CASE_PHASE.format(case_phase_header=self._phase_config().phase_name().syntax) ) cwd_contents = DirContents([ suite_file ]) tc_parsing_setup = TestCaseParsingSetup(space_separator_instruction_name_extractor, InstructionsSetup(), SectionElementParserThatRaisesUnrecognizedSectionElementSourceError()) tc_handling_setup = setup_with_null_act_phase_and_null_preprocessing() reader = suite_hierarchy_reading.Reader( suite_hierarchy_reading.Environment( SectionElementParserThatRaisesUnrecognizedSectionElementSourceError(), tc_parsing_setup, tc_handling_setup) ) with self.assertRaises(SuiteParseError): with tmp_dir_as_cwd(cwd_contents): # ACT & ASSERT # reader.apply(suite_file.name_as_path)
def test_with_error_of_path_below_relativity_root__file_names_from_applied_hierarchy_reader( self): # ARRANGE # elapsed_time = datetime.timedelta(seconds=1) num_test_cases = 6 case_file = File.empty('test.case') suite_file = File('test.suite', lines_content([case_file.name])) dir_with_suite = Dir('dir-with-suite', [suite_file, case_file]) with tmp_dir_as_cwd(DirContents([dir_with_suite])) as cwd_abs_path: read_suite_hierarchy = Reader(default_environment()).apply( dir_with_suite.name_as_path / suite_file.name) self.assertEqual(1, len(read_suite_hierarchy.test_cases), 'Sanity check: number of read cases') test_case_file_reference = read_suite_hierarchy.test_cases[0] the_exit_identifier = 'exit_identifier_4' errors = { the_exit_identifier: [ test_case_file_reference, ], } # ACT # actual_lines = sut.format_final_result_for_valid_suite( num_test_cases, elapsed_time, cwd_abs_path, errors) # ASSERT # self._assert_at_least_one_line_was_generated(actual_lines) self._assert_line_is_number_of_executed_tests_line( actual_lines[0], num_test_cases) self.assertEqual( ['', _NUMBER_OF_ERRORS.of(1), ''], actual_lines[1:4], 'Reporting of number of unsuccessful tests (including separating lines)' ) self.assertListEqual([ the_exit_identifier, ' ' + str(dir_with_suite.name_as_path / case_file.name_as_path), ], actual_lines[4:], 'Lines after "Num unsuccessful ..."')
def test_relative_path_to_root_file_in_cwd(self): # ARRANGE # root_file_base_name = 'root-file-base-name.src' root_file_in_cwd = file_with_lines(root_file_base_name, [ phase_names.SETUP.syntax, INSTR_THAT_ASSERTS_ENV_VARS, ]) cwd_dir_contents = DirContents([ root_file_in_cwd ]) with tmp_dir_as_cwd(cwd_dir_contents): expected_env_vars_to_exist_at_least = os.environ # ACT & ASSERT # fail_if_test_case_does_not_pass( self, Path(root_file_base_name), test_case_definition_with_setup_phase_assertion_instruction(self, expected_env_vars_to_exist_at_least))
def test_stdin_SHOULD_be_passed_to_process(self): # ARRANGE # program_file = File( 'stdin-2-stdout.py', py_programs.py_pgm_that_copies_stdin_to_stdout(), ) stdin_file = File( 'stdin.txt', 'contents of stdin', ) dir_contents = DirContents([ program_file, stdin_file, ]) with tmp_dir.tmp_dir_as_cwd(dir_contents): output_dir = pathlib.Path('output') executor = sut.ProcessorThatStoresResultInFilesInDir( COMMAND_EXECUTOR, output_dir, file_ctx_managers.open_file(stdin_file.name_as_path, 'r'), ) # ACT # result = executor.process(ProcessExecutionSettings.null(), py_exe.command_for_interpreting(program_file.name)) # ASSERT # assert_is_success_and_output_dir_contains_at_exactly_result_files( self, output_dir, SubProcessResult( exitcode=0, stdout=stdin_file.contents, stderr='', ), result, )
def _check_failing_line( self, configuration: sut.Configuration, phases: Sequence[Phase], invalid_line_cases: Sequence[NameAndValue[SourceAndStatus]]): proc_cases = [ NameAndValue( 'not allowed to pollute current process', sut.new_processor_that_should_not_pollute_current_process( configuration)), NameAndValue( 'allowed to pollute current process', sut.new_processor_that_is_allowed_to_pollute_current_process( configuration)), ] for phase in phases: for invalid_line_case in invalid_line_cases: source_and_status = invalid_line_case.value assert isinstance(source_and_status, SourceAndStatus) # Type info for IDE file_with_error = fs.file_with_lines('file-with-error.src', [ source_and_status.failing_source_line, ]) erroneous_line = single_line_sequence( 1, source_and_status.failing_source_line) test_case_file = fs.file_with_lines('test.case', [ section_header(phase.section_name), directive_for_inclusion_of_file(file_with_error.name), ]) line_that_includes_erroneous_file = single_line_sequence( 2, directive_for_inclusion_of_file(file_with_error.name)) cwd_contents = fs.DirContents( [test_case_file, file_with_error]) expected_source_location_path = SourceLocationPath( location=SourceLocation(erroneous_line, pathlib.Path( file_with_error.name)), file_inclusion_chain=[ SourceLocation(line_that_includes_erroneous_file, pathlib.Path(test_case_file.name)) ]) for proc_case in proc_cases: with self.subTest(phase=phase.section_name, proc=proc_case.name, line=erroneous_line.first_line): processor = proc_case.value assert isinstance(processor, Processor) with tmp_dir_as_cwd(cwd_contents): test_case_reference = test_case_reference_of_source_file( pathlib.Path(test_case_file.name)) # ACT # result = processor.apply(test_case_reference) # ASSERT # assert isinstance(result, Result) # Type info for IDE source_and_status.expected_result_statuses.apply_with_message( self, result, 'result statuses') source_location_path_expectation = equals_source_location_path( expected_source_location_path) source_location_path_expectation.apply_with_message( self, result.source_location_path, 'source location path')
def _expect_raise_argument_parsing_error(self, cwd_contents: DirContents, arguments: List[str]): with tmp_dir_as_cwd(cwd_contents): with self.assertRaises(ArgumentParsingError): sut.parse(self.handling_setup, arguments)
def _expect_raise_argument_parsing_error(self, cwd_contents: DirContents, arguments: List[str]): with tmp_dir_as_cwd(cwd_contents): with self.assertRaises(ArgumentParsingError): return sut.parse(self.handling_setup, arguments)
def _run(self, suite_file_name: str, suite_file_overriding: Optional[Path]): default_test_case_handling = setup_with_null_act_phase_and_null_preprocessing() suite_conf_instruction = SuiteConfInstructionThatSets( preprocessor=preprocessor_that_gives_const_source_with_single_assert_instruction( ASSERT_PHASE_INSTRUCTION_THAT_PASS_IFF_STDOUT_IS_SUCCESS_INDICATOR_STRING__NAME), act_phase_setup=act_setup_that_prints_single_string_on_stdout(SUCCESS_INDICATOR_STRING)) suite_conf_instructions = { SUITE_CONF_INSTRUCTION_THAT_SETS_PREPROCESSOR_AND_ACTOR__NAME: single_instruction_setup(SUITE_CONF_INSTRUCTION_THAT_SETS_PREPROCESSOR_AND_ACTOR__NAME, suite_conf_instruction) } suite_conf_parser = configuration_section_parser(suite_conf_instructions) test_case_definition = test_case_definition_with_only_assert_phase_instructions([ ( ASSERT_PHASE_INSTRUCTION_THAT_PASS_IFF_STDOUT_IS_SUCCESS_INDICATOR_STRING__NAME, assert_phase_instruction_that_pass_iff_stdout_is_success_indicator_string(SUCCESS_INDICATOR_STRING) ), ( ASSERT_PHASE_INSTRUCTION_THAT_FAILS_UNCONDITIONALLY__NAME, ASSERT_PHASE_INSTRUCTION_THAT_FAILS_UNCONDITIONALLY, ), ]) processor = sut.Processor(test_case_definition, AtcOsProcessExecutorThatJustReturnsConstant(), suite_conf_parser) suite_file = File( suite_file_name, test_suite_source_with_single_conf_instruction( SUITE_CONF_INSTRUCTION_THAT_SETS_PREPROCESSOR_AND_ACTOR__NAME) ) case_file = File( 'test.case', test_case_source_with_single_assert_phase_instruction( ASSERT_PHASE_INSTRUCTION_THAT_FAILS_UNCONDITIONALLY__NAME) ) sub_dir_path = Path('sub-dir') suite_and_case_files = DirContents([ suite_file, case_file, ]).in_dir(str(sub_dir_path)) explicit_suite_file_path = None if suite_file_overriding: explicit_suite_file_path = sub_dir_path / suite_file_overriding with tmp_dir_as_cwd(suite_and_case_files) as tmp_dir: execution_settings = TestCaseExecutionSettings(sub_dir_path / case_file.name_as_path, tmp_dir / sub_dir_path, ReportingOption.STATUS_CODE, default_test_case_handling, run_as_part_of_explicit_suite=explicit_suite_file_path) # ACT # actual_result = capture_output_from_processor(processor, execution_settings) # ASSERT # if actual_result.exitcode != exit_values.EXECUTION__PASS.exit_code: self.fail(_error_message(actual_result))
def capture_output_from_main_program__in_tmp_dir(command_line_arguments: List[str], cwd_contents: DirContents, main_pgm: main_program.MainProgram, ) -> SubProcessResult: with tmp_dir_as_cwd(cwd_contents): return capture_output_from_main_program(command_line_arguments, main_pgm)
def _run(self, suite_file_name: str, suite_file_overriding: Optional[Path]): default_test_case_handling = setup_with_null_act_phase_and_null_preprocessing() suite_conf_instruction = SuiteConfInstructionThatSets( preprocessor=preprocessor_that_gives_const_source_with_single_assert_instruction( ASSERT_PHASE_INSTRUCTION_THAT_PASS_IFF_STDOUT_IS_SUCCESS_INDICATOR_STRING__NAME), act_phase_setup=act_setup_that_prints_single_string_on_stdout(SUCCESS_INDICATOR_STRING)) suite_conf_instructions = { SUITE_CONF_INSTRUCTION_THAT_SETS_PREPROCESSOR_AND_ACTOR__NAME: single_instruction_setup(SUITE_CONF_INSTRUCTION_THAT_SETS_PREPROCESSOR_AND_ACTOR__NAME, suite_conf_instruction) } suite_conf_parser = configuration_section_parser(suite_conf_instructions) test_case_definition = test_case_definition_with_only_assert_phase_instructions([ ( ASSERT_PHASE_INSTRUCTION_THAT_PASS_IFF_STDOUT_IS_SUCCESS_INDICATOR_STRING__NAME, assert_phase_instruction_that_pass_iff_stdout_is_success_indicator_string(SUCCESS_INDICATOR_STRING) ), ( ASSERT_PHASE_INSTRUCTION_THAT_FAILS_UNCONDITIONALLY__NAME, ASSERT_PHASE_INSTRUCTION_THAT_FAILS_UNCONDITIONALLY, ), ]) processor = sut.Processor(test_case_definition, os_services_access.new_for_cmd_exe(CommandExecutorThatJustReturnsConstant()), suite_conf_parser, 2 ** 10) suite_file = File( suite_file_name, test_suite_source_with_single_conf_instruction( SUITE_CONF_INSTRUCTION_THAT_SETS_PREPROCESSOR_AND_ACTOR__NAME) ) case_file = File( 'test.case', test_case_source_with_single_assert_phase_instruction( ASSERT_PHASE_INSTRUCTION_THAT_FAILS_UNCONDITIONALLY__NAME) ) sub_dir_path = Path('sub-dir') suite_and_case_files = DirContents([ suite_file, case_file, ]).in_dir(str(sub_dir_path)) explicit_suite_file_path = None if suite_file_overriding: explicit_suite_file_path = sub_dir_path / suite_file_overriding with tmp_dir_as_cwd(suite_and_case_files) as tmp_dir: execution_settings = TestCaseExecutionSettings(sub_dir_path / case_file.name_as_path, tmp_dir / sub_dir_path, ReportingOption.STATUS_CODE, default_test_case_handling, run_as_part_of_explicit_suite=explicit_suite_file_path) # ACT # actual_result = capture_output_from_processor(processor, execution_settings) # ASSERT # if actual_result.exitcode != exit_values.EXECUTION__PASS.exit_code: self.fail(_error_message(actual_result))