def test_positive(self): cases = [ SourceCase('MATCHER on first line, followed by non-instr line', source=remaining_source_lines([ EMPTINESS_CHECK_ARGUMENT, 'following line', ]), source_assertion=asrt_source.is_at_end_of_line(1) ), SourceCase('Followed by empty line', source=remaining_source_lines([ EMPTINESS_CHECK_ARGUMENT, '', ]), source_assertion=asrt_source.is_at_end_of_line(1) ), SourceCase('Selection and matcher on separate lines', source=remaining_source_lines([ selection_arguments(name_pattern='*'), EMPTINESS_CHECK_ARGUMENT, '', 'following line', ]), source_assertion=asrt_source.is_at_end_of_line(2) ), ] for case in cases: self._check_sub_test(case, is_matching_success())
def test_file_matcher_reference_is_reported(self): name_of_file_matcher = 'a_file_matcher_symbol' arguments_constructor = args.complete_arguments_constructor( self.assertion_variant.arguments, file_matcher=name_of_file_matcher) arguments = arguments_constructor.apply( pfh_expectation_type_config(ExpectationType.NEGATIVE)) source = remaining_source(arguments) # ACT # matcher = parsers().full.parse(source) assert isinstance(matcher, MatcherSdv) actual = matcher.references # ASSERT # expected_references = asrt.matches_sequence( list(self.assertion_variant.expected_references) + [is_reference_to_file_matcher(name_of_file_matcher)]) expected_references.apply_without_message(self, actual) asrt_source.is_at_end_of_line(1)
def test_document_is_not_mandatory_and_not_present(self): some_white_space = ' ' source_cases = [ ([ '', ], asrt_source.is_at_end_of_line(1)), ([ some_white_space, ], asrt_source.assert_source( current_line_number=asrt.equals(1), remaining_part_of_current_line=asrt.equals(some_white_space)) ), ([ '', 'line after', ], asrt_source.is_at_end_of_line(1)), ] parser = sut.HereDocParser(False) for source_lines, source_assertion in source_cases: with self.subTest(msg=repr((source_lines, source_assertion))): source = remaining_source_lines(source_lines) actual = parser.parse(source) self.assertIsNone(actual, 'return value from parsing') source_assertion.apply_with_message(self, source, 'source')
def test_here_document_with_symbol_references(self): symbol1 = StringConstantSymbolContext('symbol_1_name', 'symbol 1 value') symbol2 = StringConstantSymbolContext('symbol_2_name', 'symbol 2 value') symbol3 = StringConstantSymbolContext('symbol_3_name', 'symbol 3 value') line_with_sym_ref_template = 'before symbol {symbol} after symbol' line_with_two_sym_refs_template = '{first_symbol} between symbols {second_symbol}' cases = [ SuccessfulCase( source_lines=[ '<<eof', line_with_sym_ref_template.format( symbol=symbol1.name__sym_ref_syntax), 'eof', 'following line', ], expected_document_contents=hd.matches_resolved_value( [ line_with_sym_ref_template.format( symbol=symbol1.str_value), ], symbol_references=[ symbol1.reference__w_str_rendering, ], symbols=symbol1.symbol_table), source_after_parse=asrt_source.is_at_end_of_line(3), ), SuccessfulCase( source_lines=[ '<<eof', line_with_sym_ref_template.format( symbol=symbol1.name__sym_ref_syntax), line_with_two_sym_refs_template.format( first_symbol=symbol2.name__sym_ref_syntax, second_symbol=symbol3.name__sym_ref_syntax), 'eof', 'following line', ], expected_document_contents=hd.matches_resolved_value( [ line_with_sym_ref_template.format( symbol=symbol1.str_value), line_with_two_sym_refs_template.format( first_symbol=symbol2.str_value, second_symbol=symbol3.str_value), ], symbol_references=[ symbol1.reference__w_str_rendering, symbol2.reference__w_str_rendering, symbol3.reference__w_str_rendering, ], symbols=SymbolContext.symbol_table_of_contexts( [symbol1, symbol2, symbol3], )), source_after_parse=asrt_source.is_at_end_of_line(4), ), ] for case in cases: self._check_case(case)
def test(self): cases = [ Case('empty line with no following lines', source= remaining_source(''), expectation= Expectation(elements=[], source=asrt_source.is_at_end_of_line(1)), ), Case('only white space on current line, with no following lines', source= remaining_source(' '), expectation= Expectation(elements=[], source=asrt_source.source_is_not_at_end( current_line_number=asrt.equals(1), remaining_part_of_current_line=asrt.equals(' '))), ), Case('empty line, with following lines', source= remaining_source('', ['contents of following line']), expectation= Expectation(elements=[], source=asrt_source.is_at_end_of_line(1), ) ), ] # ACT & ASSERT # _test_cases(self, cases)
def test_file_matcher_reference_is_reported(self): name_of_file_matcher = 'a_file_matcher_symbol' arguments_constructor = args.complete_arguments_constructor( self.assertion_variant.arguments, file_matcher=name_of_file_matcher ) arguments = arguments_constructor.apply(pfh_expectation_type_config(ExpectationType.NEGATIVE)) source = remaining_source(arguments) # ACT # matcher = sut.files_matcher_parser().parse(source) assert isinstance(matcher, FilesMatcherResolver) actual = matcher.references # ASSERT # expected_references = asrt.matches_sequence( [is_file_matcher_reference_to(name_of_file_matcher)] + list(self.assertion_variant.expected_references) ) expected_references.apply_without_message(self, actual) asrt_source.is_at_end_of_line(1)
def _source_variants_with_accepted_following_content_on_same_line( num_source_lines: int ) -> List[Tuple[Arguments, ValueAssertion[ParseSource]]]: return [ (Arguments('', []), asrt_source.is_at_end_of_line(num_source_lines)), (Arguments('', ['following line']), asrt_source.is_at_end_of_line(num_source_lines)), (Arguments('', [' ']), asrt_source.is_at_end_of_line(num_source_lines)), ]
def _source_variants_with_accepted_following_content_on_same_line( num_source_lines: int ) -> List[Tuple[Arguments, Assertion[ParseSource]]]: return [ (Arguments('', []), asrt_source.is_at_end_of_line(num_source_lines)), (Arguments('', ['following line']), asrt_source.is_at_end_of_line(num_source_lines)), (Arguments('', [' ']), asrt_source.is_at_end_of_line(num_source_lines)), ]
def test_success_of_expression_within_parentheses(self): s = ast.SimpleSansArg() cases = [ ( 'parentheses around first expr to make nested expr instead of "linear" args to op', Arrangement( grammar=ast.GRAMMAR_WITH_ALL_COMPONENTS, source=remaining_source('( {s} {op} {s} ) {op} {s}'.format( s=ast.SIMPLE_SANS_ARG, op=ast.COMPLEX_A, )), ), Expectation( expression=ComplexA([ComplexA([s, s]), s]), source=asrt_source.is_at_end_of_line(1), ), ), ( 'parentheses around final (second) expr to make first op have precedence', Arrangement( grammar=ast.GRAMMAR_WITH_ALL_COMPONENTS, source=remaining_source('{s} {op} ( {s} {op} {s} )'.format( s=ast.SIMPLE_SANS_ARG, op=ast.COMPLEX_A, )), ), Expectation( expression=ComplexA([s, ComplexA([s, s])]), source=asrt_source.is_at_end_of_line(1), ), ), ( '"linear" (sequence) of OPA, by embedding OPB inside parentheses', Arrangement( grammar=ast.GRAMMAR_WITH_ALL_COMPONENTS, source=remaining_source('{s} {op_a} ( {s} {op_b} {s} ) {op_a} {s}'.format( s=ast.SIMPLE_SANS_ARG, op_a=ast.COMPLEX_A, op_b=ast.COMPLEX_B_THAT_IS_NOT_A_VALID_SYMBOL_NAME, )), ), Expectation( expression=ComplexA([s, ComplexB([s, s]), s]), source=asrt_source.is_at_end_of_line(1), ), ), ] for case_name, arrangement, expectation in cases: with self.subTest(name=case_name): _check(self, arrangement, expectation )
def runTest(self): sb = SB.new_with(constant_transformation_arguments=argument_syntax.syntax_for_transformer_option( argument_syntax.syntax_for_replace_transformer('a', 'A') )) cases = [ Case('CONTENTS-MATCHER on separate line', source= self.configuration.source_for_lines( sb.format_lines(['', '{empty}'])), source_assertion= asrt_source.is_at_end_of_line(2), main_result_assertion= is_matching_success(), ), Case('transformation and CONTENTS-MATCHER on separate line', source= self.configuration.source_for_lines( sb.format_lines(['', '{constant_transformation_arguments}', '{empty}'])), source_assertion= asrt_source.is_at_end_of_line(3), main_result_assertion= is_matching_success(), ), Case('negation and CONTENTS-MATCHER on separate line', source= self.configuration.source_for_lines( sb.format_lines(['', '{not}', '{empty}'])), source_assertion= asrt_source.is_at_end_of_line(3), main_result_assertion= is_arbitrary_matching_failure(), ), ] for case in cases: with self.subTest(case.name): self._check( case.source, model_construction.empty_model(), self.configuration.arrangement_for_contents( post_sds_population_action=MK_SUB_DIR_OF_ACT_AND_MAKE_IT_CURRENT_DIRECTORY), Expectation(main_result=case.main_result_assertion, source=case.source_assertion), )
def runTest(self): # ARRANGE # program_symbol_name = 'PROGRAM_SYMBOL' # ACT && ASSERT # integration_check.CHECKER__PARSE_FULL.check_multi( self, args.RunProgram( program_args.symbol_ref_command_elements( program_symbol_name)).as_arguments, ParseExpectation( source=asrt_source.is_at_end_of_line(1), symbol_references=asrt.matches_sequence([ is_reference_to_program(program_symbol_name), ]), ), model_constructor.arbitrary(self), [ validation_cases.validation_exe_case(validation_case) for validation_case in validation_cases.failing_validation_cases( program_symbol_name, 'TRANSFORMER_SYMBOL') ], )
def _doTest(self, maybe_not: ExpectationTypeConfigForNoneIsSuccess): regex_lines = ['1.3', '4.*6'] here_doc_of_reg_ex = here_document_as_elements(regex_lines) actual_contents = lines_content(['123', '456', '789']) for transformer_option_arguments in TRANSFORMER_OPTION_ALTERNATIVES_ELEMENTS: with self.subTest(maybe_with_transformer_option=transformer_option_arguments): argument_elements = ArgumentElements(transformer_option_arguments + maybe_not.empty__if_positive__not_option__if_negative + [matcher_options.MATCHES_ARGUMENT, FULL_MATCH_ARGUMENT] ).followed_by(here_doc_of_reg_ex) self._check( argument_elements.as_remaining_source, model_constructor.of_str(self, actual_contents), arrangement_w_tcds(), Expectation( ParseExpectation( source=asrt_source.is_at_end_of_line(1 + len(here_doc_of_reg_ex.following_lines)) ), ExecutionExpectation( main_result=maybe_not.fail__if_positive__pass_if_negative ), ), )
def _doTest(self, maybe_not: ExpectationTypeConfigForNoneIsSuccess): expected_content_line_template = 'expected content line, with {symbol} ref' def expected_content(symbol_content: str) -> str: return expected_content_line_template.format(symbol=symbol_content) symbol = NameAndValue('symbol_name', 'the symbol value') self._check( self.configuration.source_for( args('{maybe_not} {equals} <<EOF', maybe_not=maybe_not.nothing__if_positive__not_option__if_negative), [expected_content(symbol_reference_syntax_for_name(symbol.name)), 'EOF', 'following line']), model_construction.model_of(lines_content([expected_content(symbol.value)])), self.configuration.arrangement_for_contents( post_sds_population_action=MK_SUB_DIR_OF_ACT_AND_MAKE_IT_CURRENT_DIRECTORY, symbols=SymbolTable({ symbol.name: data_symbol_utils.string_constant_container(symbol.value), })), Expectation(main_result=maybe_not.pass__if_positive__fail__if_negative, symbol_usages=equals_symbol_references([ SymbolReference(symbol.name, is_any_data_type()) ]), source=asrt_source.is_at_end_of_line(3)), )
def check__full_and_simple_within_parentheses__multi( put: unittest.TestCase, source_and_expectation_cases: Sequence[NIE[str, Expr]]): # ARRANGE # expected_source = asrt_source.is_at_end_of_line(1) for case in source_and_expectation_cases: with put.subTest(case.name, parser_case='full', source=case.input_value): source = remaining_source(case.input_value) # ACT # actual = _PARSER__FULL.parse(source) # ASSERT # expected_source.apply_with_message(put, source, 'source') put.assertEqual(case.expected_value, actual, 'parsed expression') with put.subTest(case.name, parser_case='simple, within parentheses', source=case.input_value): source = remaining_source(' '.join(['(', case.input_value, ')'])) # ACT # actual = _PARSER__SIMPLE.parse(source) # ASSERT # expected_source.apply_with_message(put, source, 'source') put.assertEqual(case.expected_value, actual, 'parsed expression')
def assertion(self) -> Assertion[ParseSource]: return (asrt_source.is_at_end_of_line(self.current_line_number) if self.remaining_part_of_current_line is None else asrt_source.source_is_not_at_end( current_line_number=asrt.equals(self.current_line_number), remaining_part_of_current_line=asrt.equals( self.remaining_part_of_current_line)))
def test_combined_expression_with_single_simple_expr(self): # [ [ [ s A s ] B s B s ] A s ] s = ast.SimpleSansArg() op_sequence_1 = ast.ComplexA([s, s]) op_sequence_2 = ast.ComplexB([op_sequence_1, s, s]) expected = ast.ComplexA([op_sequence_2, s]) arguments = '{s} {op_a} {s} {op_b} {s} {op_b} {s} {op_a} {s}'.format( op_a=ast.COMPLEX_A, op_b=ast.COMPLEX_B_THAT_IS_NOT_A_VALID_SYMBOL_NAME, s=ast.SIMPLE_SANS_ARG, ) self._check( Arrangement( grammar= ast.GRAMMAR_WITH_ALL_COMPONENTS, source= remaining_source(arguments)), Expectation( expression= expected, source= asrt_source.is_at_end_of_line(1), ) )
def test_result_SHOULD_be_true_iff_exit_code_is_0(self): # ARRANGE # program_symbol_name = 'PROGRAM_THAT_EXECUTES_PY_FILE' exit_code_symbol_name = 'EXIT_CODE_SYMBOL' # ACT && ASSERT # integration_check.CHECKER__PARSE_FULL.check_multi( self, args.RunProgram( program_args.symbol_ref_command_elements( program_symbol_name, arguments=[ symbol_reference_syntax_for_name(exit_code_symbol_name) ], )).as_arguments, ParseExpectation( source=asrt_source.is_at_end_of_line(1), symbol_references=asrt.matches_sequence([ is_reference_to_program(program_symbol_name), is_reference_to__w_str_rendering(exit_code_symbol_name), ]), ), integration_check.ARBITRARY_MODEL, test_cases.exit_code_exe_cases( program_symbol_name, exit_code_symbol_name, ), )
def test__primitive_recursive_followed_by_binary_op_on_same_line(self): s = ast.PrimitiveSansArg() expected = ast.InfixOpA([ast.PrimitiveRecursive(s), s]) arguments = '{r} {s} {op_a} {s}'.format( r=ast.PRIMITIVE_RECURSIVE, s=ast.PRIMITIVE_SANS_ARG, op_a=ast.INFIX_OP_A, ) check( self, PARSER_MAKER_OF_FULL_EXPR_PARSER, Arrangement( grammar= ast.GRAMMAR_WITH_ALL_COMPONENTS, source= remaining_source(arguments)), Expectation( expression= expected, source= asrt_source.is_at_end_of_line(1), ) )
def test_combined_expression_with_single_primitive_expr(self): # [ [ [ s A s ] B s B s ] A s ] s = ast.PrimitiveSansArg() op_sequence_1 = ast.InfixOpA([s, s]) op_sequence_2 = ast.InfixOpB([op_sequence_1, s, s]) expected = ast.InfixOpA([op_sequence_2, s]) arguments = '{s} {op_a} {s} {op_b} {s} {op_b} {s} {op_a} {s}'.format( op_a=ast.INFIX_OP_A, op_b=ast.INFIX_OP_B_THAT_IS_NOT_A_VALID_SYMBOL_NAME, s=ast.PRIMITIVE_SANS_ARG, ) check( self, PARSER_MAKER_OF_FULL_EXPR_PARSER, Arrangement( grammar= ast.GRAMMAR_WITH_ALL_COMPONENTS, source= remaining_source(arguments)), Expectation( expression= expected, source= asrt_source.is_at_end_of_line(1), ) )
def runTest(self): lines = ['1', '2', '3'] actual_number_of_lines = len(lines) integer_matcher = IntegerMatcherSymbolContext.of_primitive( 'INTEGER_MATCHER', matchers.matcher( comparators.EQ, actual_number_of_lines, )) integration_check.CHECKER__PARSE_SIMPLE.check( self, args.NumLines( integer_matcher.name__sym_ref_syntax).as_remaining_source, model_constructor.of_str(self, lines_content(lines)), arrangement_w_tcds(symbols=integer_matcher.symbol_table, ), Expectation( ParseExpectation( source=asrt_source.is_at_end_of_line(1), symbol_references=integer_matcher.references_assertion, ), ExecutionExpectation( main_result=asrt_matching_result.matches_value(True)), ), )
def _doTest(self, maybe_not: ExpectationTypeConfigForNoneIsSuccess): expected_content_line_template = 'expected content line, with {symbol} ref' def expected_content(symbol_content: str) -> str: return expected_content_line_template.format(symbol=symbol_content) symbol = StringConstantSymbolContext('symbol_name', 'the symbol value') self._check( test_configuration.source_for( args('{maybe_not} {equals} <<EOF', maybe_not=maybe_not.nothing__if_positive__not_option__if_negative), [expected_content(symbol.name__sym_ref_syntax), 'EOF', 'following line']), model_constructor.of_str(self, lines_content([expected_content(symbol.str_value)])), arrangement_w_tcds( post_population_action=MK_SUB_DIR_OF_ACT_AND_MAKE_IT_CURRENT_DIRECTORY, symbols=symbol.symbol_table), Expectation( ParseExpectation( source=asrt_source.is_at_end_of_line(3), symbol_references=asrt.matches_sequence([ symbol.reference_assertion__w_str_rendering ]), ), ExecutionExpectation( main_result=maybe_not.pass__if_positive__fail__if_negative, ), ), )
def test(self): cases = [ Case( 'empty line with no following lines', source=remaining_source(''), expectation=Expectation( elements=[], source=asrt_source.is_at_end_of_line(1)), ), Case( 'only white space on current line, with no following lines', source=remaining_source(' '), expectation=Expectation( elements=[], source=asrt_source.is_at_end_of_line(1)), ), Case('empty line, with following lines', source=remaining_source('', ['contents of following line']), expectation=Expectation( elements=[], source=asrt_source.is_at_end_of_line(1), )), Case('line with r-paren', source=remaining_source(reserved_words.PAREN_END, ['contents of following line']), expectation=Expectation( elements=[], source=asrt_source.source_is_not_at_end( current_line_number=asrt.equals(1), remaining_part_of_current_line=asrt.equals( reserved_words.PAREN_END)), )), Case('line with continuation-token, followed by empty line', source=remaining_source(defs.CONTINUATION_TOKEN, ['']), expectation=Expectation( elements=[], source=asrt_source.is_at_end_of_line(2), )), Case( 'line with continuation-token (followed by space), followed by empty line', source=remaining_source(defs.CONTINUATION_TOKEN + ' ', ['']), expectation=Expectation( elements=[], source=asrt_source.is_at_end_of_line(2), )), ] # ACT & ASSERT # _test_cases(self, cases)
def runTest(self): sb = SB.new_with( constant_transformation_arguments=argument_syntax. syntax_for_transformer_option( argument_syntax.syntax_for_replace_transformer('a', 'A'))) cases = [ Case( 'CONTENTS-MATCHER on separate line', source=test_configuration.source_for_lines( sb.format_lines(['', '{empty}'])), source_assertion=asrt_source.is_at_end_of_line(2), main_result_assertion=is_matching_success(), ), Case( 'transformation and CONTENTS-MATCHER on separate line', source=test_configuration.source_for_lines( sb.format_lines( ['', '{constant_transformation_arguments}', '{empty}'])), source_assertion=asrt_source.is_at_end_of_line(3), main_result_assertion=is_matching_success(), ), Case( 'negation and CONTENTS-MATCHER on separate line', source=test_configuration.source_for_lines( sb.format_lines(['', '{not}', '{empty}'])), source_assertion=asrt_source.is_at_end_of_line(3), main_result_assertion=is_arbitrary_matching_failure(), ), ] for case in cases: with self.subTest(case.name): self._check( case.source, model_constructor.empty(self), arrangement_w_tcds( post_population_action= MK_SUB_DIR_OF_ACT_AND_MAKE_IT_CURRENT_DIRECTORY), Expectation( ParseExpectation(source=case.source_assertion, ), ExecutionExpectation( main_result=case.main_result_assertion, ), ), )
def _source_variants_with__for_full_line_expression_parser( num_expression_lines: int = 1 ) -> List[Tuple[List[str], Assertion[ParseSource]]]: source_expectation = asrt_source.is_at_end_of_line(num_expression_lines) return [ ([], source_expectation), ([' '], source_expectation), (['following line'], source_expectation), ]
def _equivalent_source_variants_for_consume_until_end_of_last_line( num_expression_lines: int = 1 ) -> List[Tuple[List[str], Assertion[ParseSource]]]: source_expectation = asrt_source.is_at_end_of_line(num_expression_lines) return [ ([], source_expectation), (['non-empty following line'], source_expectation), ([' '], source_expectation), ([' ', 'non-empty-line'], source_expectation), ]
def _check( self, output: StdOutputFilesContents, exit_code_cases: List[int], ignore_exit_code: bool, execution_expectation: ExecutionExpectation, ): # ARRANGE # py_file_rel_opt_conf = rel_opt.conf_rel_any(RelOptionType.REL_TMP) for exit_code in exit_code_cases: with self.subTest(non_zero_exit_code=exit_code): py_file = File( 'exit-with-hard-coded-exit-code.py', py_programs.py_pgm_with_stdout_stderr_exit_code( stdout_output=output.out, stderr_output=output.err, exit_code=exit_code, ), ) py_file_conf = py_file_rel_opt_conf.named_file_conf( py_file.name) program_symbol = ProgramSymbolContext.of_sdv( 'PROGRAM_SYMBOL_NAME', program_sdvs.interpret_py_source_file_that_must_exist( py_file_conf.path_sdv)) # ACT && ASSERT # integration_check.CHECKER__PARSE_FULL.check( self, args.syntax_for_run( program_args.symbol_ref_command_elements( program_symbol.name), ignore_exit_code=ignore_exit_code, ).as_remaining_source, model_constructor.arbitrary(self), arrangement_w_tcds( symbols=program_symbol.symbol_table, tcds_contents=py_file_rel_opt_conf. populator_for_relativity_option_root( DirContents([py_file])), ), Expectation( ParseExpectation( source=asrt_source.is_at_end_of_line(1), symbol_references=program_symbol. references_assertion), execution_expectation, ), )
def runTest(self): instruction_argument = self._arg('{executable}') utils.check(self, instruction_argument, utils.Arrangement(home_or_sds_pop.empty()), utils.Expectation(file_resolver_value=self.configuration.file_resolver_value, expected_symbol_references_of_file=self.configuration.expected_symbol_references_of_file, expected_symbol_references_of_argument=self.configuration.expected_symbol_references_of_argument, source=asrt_source.is_at_end_of_line(1), validation_result=self.configuration.validation_result, argument_resolver_value=empty_list_value()))
def test_negative(self): cases = [ SourceCase('Dir on 1st line, Negation and DIR-CONTENTS-MATCHER on 2nd line', source=remaining_source_lines([ instruction_arguments.NEGATION_ARGUMENT_STR + ' ' + EMPTINESS_CHECK_ARGUMENT, ]), source_assertion=asrt_source.is_at_end_of_line(1) ), SourceCase('Dir on 1st line, Negation and DIR-CONTENTS-MATCHER on 2nd line, followed by non-instr lines', source=remaining_source_lines([ instruction_arguments.NEGATION_ARGUMENT_STR, EMPTINESS_CHECK_ARGUMENT, 'following line', ]), source_assertion=asrt_source.is_at_end_of_line(2) ), ] for case in cases: self._check_sub_test(case, is_arbitrary_matching_failure())
def runTest(self): # ARRANGE # clashing_file_name = 'clashing-file' non_clashing_file_name = 'non-clashing-file' clash_cases: Sequence[NameAndValue[FileSystemElements]] = [ NameAndValue( 'exists as regular', [fs.File.empty(clashing_file_name)], ), NameAndValue( 'exists as dir', [fs.Dir.empty(clashing_file_name)], ), NameAndValue( 'exists as sym-link to regular', [fs.File.empty(non_clashing_file_name), fs.sym_link(clashing_file_name, non_clashing_file_name)], ), NameAndValue( 'exists as broken sym-link', [fs.sym_link(clashing_file_name, non_clashing_file_name)], ), ] src_dir_relativity = relativity_options.conf_rel_any(RelOptionType.REL_HDS_CASE) src_dir_symbol = PathDdvSymbolContext.of_no_suffix( 'SRC_PATH_SYMBOL', src_dir_relativity.relativity, accepted_relativities=RELATIVITY_VARIANTS__READ__BEFORE_ACT, ) arguments_syntax = abs_stx.CopyOfDirContentsAbsStx(src_dir_symbol.abstract_syntax) for clash_case in clash_cases: with self.subTest(clash_case.name): # ACT & ASSERT # integration_check.CHECKER.check__abs_stx( self, arguments_syntax, clash_case.value, Arrangement( symbols=src_dir_symbol.symbol_table, tcds=TcdsArrangement( tcds_contents=src_dir_relativity.populator_for_relativity_option_root__s( [fs.File.empty(clashing_file_name)] ) ) ), Expectation( ParseExpectation( source=asrt_source.is_at_end_of_line(1), symbol_references=src_dir_symbol.references_assertion, ), execution=ExecutionExpectation.is_any_hard_error() ), )
def test_successful_parse_with_complex_expressions(self): s = ast.SimpleSansArg() cases = [ ( 'prefix operator binds to following simple expression (single complex ops)', Arrangement( grammar=ast.GRAMMAR_WITH_ALL_COMPONENTS, source=remaining_source('{p_op} {s} {bin_op} {s} {bin_op} {p_op} {s}'.format( s=ast.SIMPLE_SANS_ARG, p_op=ast.PREFIX_P, bin_op=ast.COMPLEX_A, )), ), Expectation( expression=ComplexA([PrefixExprP(s), s, PrefixExprP(s)]), source=asrt_source.is_at_end_of_line(1), ), ), ( 'prefix operator binds to following simple expression (different complex ops)', Arrangement( grammar=ast.GRAMMAR_WITH_ALL_COMPONENTS, source=remaining_source('{p_op} {s} {bin_op_a} {s} {bin_op_b} {p_op} {s}'.format( s=ast.SIMPLE_SANS_ARG, p_op=ast.PREFIX_P, bin_op_a=ast.COMPLEX_A, bin_op_b=ast.COMPLEX_B_THAT_IS_NOT_A_VALID_SYMBOL_NAME, )), ), Expectation( expression=ComplexB([ComplexA([PrefixExprP(s), s]), PrefixExprP(s)]), source=asrt_source.is_at_end_of_line(1), ), ), ] for case_name, arrangement, expectation in cases: with self.subTest(name=case_name): self._check( arrangement, expectation )
def test_combined_expression_sans_parentheses(self): # [ [ [ ref1 OPA s ] OPB s OPB ref2 ] OPA s_x OPA ref3 ] ref_1 = ast.RefExpr('symbol_1') ref_2 = ast.RefExpr('symbol_2') ref_3 = ast.RefExpr('symbol_3') s = ast.PrimitiveSansArg() s_x = ast.PrimitiveWithArg('X') e1 = ast.InfixOpA([ ref_1, s, ]) e2 = ast.InfixOpB([ e1, s, ref_2, ]) expected = ast.InfixOpA([ e2, s_x, ref_3, ]) argument_string = '{ref_1} {op_a} {s} {op_b} {s} {op_b} {ref_2} {op_a} {s_w_arg} {x} {op_a} {ref_3}'.format( s=ast.PRIMITIVE_SANS_ARG, ref_1=ref_1.symbol_name, ref_2=ref_2.symbol_name, ref_3=ref_3.symbol_name, op_a=ast.INFIX_OP_A, op_b=ast.INFIX_OP_B_THAT_IS_NOT_A_VALID_SYMBOL_NAME, s_w_arg=ast.PRIMITIVE_WITH_ARG, x=s_x.argument, ) check( self, PARSER_MAKER_OF_FULL_EXPR_PARSER, Arrangement( grammar= ast.GRAMMAR_WITH_ALL_COMPONENTS, source= remaining_source(argument_string)), Expectation( expression= expected, source= asrt_source.is_at_end_of_line(1), ) )
def runTest(self): utils.check__abs_stx( self, self.configuration.executable, utils.Arrangement(tcds_pop.empty()), utils.Expectation( path_ddv=self.configuration.path_ddv, expected_symbol_references=self.configuration. expected_symbol_references, source=asrt_source.is_at_end_of_line(1), validation_result=self.configuration.validation_result, ), )
def _doTest(self, maybe_not: ExpectationTypeConfigForNoneIsSuccess): self._check( self.configuration.source_for( args('{maybe_not} {equals} <<EOF', maybe_not=maybe_not.nothing__if_positive__not_option__if_negative), ['expected content line', 'EOF']), model_construction.model_of(lines_content(['expected content line'])), self.configuration.arrangement_for_contents( post_sds_population_action=MK_SUB_DIR_OF_ACT_AND_MAKE_IT_CURRENT_DIRECTORY), Expectation(main_result=maybe_not.pass__if_positive__fail__if_negative, source=asrt_source.is_at_end_of_line(3)), )
def test_successful_parse_with_infix_op_expressions(self): s = ast.PrimitiveSansArg() cases = [ NArrEx( 'prefix operator binds to following primitive expression (single infix ops)', Arrangement( grammar=ast.GRAMMAR_WITH_ALL_COMPONENTS, source=remaining_source('{p_op} {s} {bin_op} {s} {bin_op} {p_op} {s}'.format( s=ast.PRIMITIVE_SANS_ARG, p_op=ast.PREFIX_P, bin_op=ast.INFIX_OP_A, )), ), Expectation( expression=InfixOpA([PrefixOpExprP(s), s, PrefixOpExprP(s)]), source=asrt_source.is_at_end_of_line(1), ), ), NArrEx( 'prefix operator binds to following primitive expression (different infix ops)', Arrangement( grammar=ast.GRAMMAR_WITH_ALL_COMPONENTS, source=remaining_source('{p_op} {s} {bin_op_a} {s} {bin_op_b} {p_op} {s}'.format( s=ast.PRIMITIVE_SANS_ARG, p_op=ast.PREFIX_P, bin_op_a=ast.INFIX_OP_A, bin_op_b=ast.INFIX_OP_B_THAT_IS_NOT_A_VALID_SYMBOL_NAME, )), ), Expectation( expression=InfixOpB([InfixOpA([PrefixOpExprP(s), s]), PrefixOpExprP(s)]), source=asrt_source.is_at_end_of_line(1), ), ), ] # ACT & ASSERT # parse_check.check__multi(self, PARSER_MAKER_OF_FULL_EXPR_PARSER, cases)
def test_combined_expression_sans_parentheses(self): # [ [ [ ref1 OPA s ] OPB s OPB ref2 ] OPA s_x OPA ref3 ] ref_1 = ast.RefExpr('symbol_1') ref_2 = ast.RefExpr('symbol_2') ref_3 = ast.RefExpr('symbol_3') s = ast.SimpleSansArg() s_x = ast.SimpleWithArg('X') e1 = ast.ComplexA([ ref_1, s, ]) e2 = ast.ComplexB([ e1, s, ref_2, ]) expected = ast.ComplexA([ e2, s_x, ref_3, ]) argument_string = '{ref_1} {op_a} {s} {op_b} {s} {op_b} {ref_2} {op_a} {s_w_arg} {x} {op_a} {ref_3}'.format( s=ast.SIMPLE_SANS_ARG, ref_1=ref_1.symbol_name, ref_2=ref_2.symbol_name, ref_3=ref_3.symbol_name, op_a=ast.COMPLEX_A, op_b=ast.COMPLEX_B_THAT_IS_NOT_A_VALID_SYMBOL_NAME, s_w_arg=ast.SIMPLE_WITH_ARG, x=s_x.argument, ) self._check( Arrangement( grammar= ast.GRAMMAR_WITH_ALL_COMPONENTS, source= remaining_source(argument_string)), Expectation( expression= expected, source= asrt_source.is_at_end_of_line(1), ) )
def test_successful_parse(self): symbol_name = 'the_symbol_name' space_after = ' ' token_after = str(surrounded_by_hard_quotes('not an expression')) for grammar_description, grammar in self.grammars: cases = [ SourceCase( 'first line is only simple expr', source= remaining_source('{symbol_name}'.format( symbol_name=symbol_name, )), source_assertion= asrt_source.is_at_end_of_line(1) ), SourceCase( 'first line is simple expr with space around', source= remaining_source(' {symbol_name}{space_after}'.format( symbol_name=symbol_name, space_after=space_after)), source_assertion= asrt_source.source_is_not_at_end(current_line_number=asrt.equals(1), remaining_part_of_current_line=asrt.equals(space_after[1:])) ), SourceCase( 'expression is followed by non-expression', source= remaining_source('{symbol_name} {token_after}'.format( symbol_name=symbol_name, token_after=token_after)), source_assertion= asrt_source.source_is_not_at_end(current_line_number=asrt.equals(1), remaining_part_of_current_line=asrt.equals(token_after)) ), ] for case in cases: with self.subTest(grammar=grammar_description, name=case.name): self._check( Arrangement( grammar=grammar, source=case.source), Expectation( expression=ast.RefExpr(symbol_name), source=case.source_assertion, ) )
def test_constant_here_document_is_given(self): cases = [ SuccessfulCase( source_lines=[ '<<MARKER', 'MARKER', ], expected_document_contents=hd.matches_resolved_value([]), source_after_parse=asrt_source.is_at_end_of_line(2)), SuccessfulCase( source_lines=[ '<<eof', 'eof', ], expected_document_contents=hd.matches_resolved_value([]), source_after_parse=asrt_source.is_at_end_of_line(2)), SuccessfulCase( source_lines=[ '<<-', '-', ], expected_document_contents=hd.matches_resolved_value([]), source_after_parse=asrt_source.is_at_end_of_line(2)), SuccessfulCase( source_lines=[ '<<MARKER', 'MARKER', ' after', ], expected_document_contents=hd.matches_resolved_value([]), source_after_parse=asrt_source.is_at_end_of_line(2)), SuccessfulCase( source_lines=[ '<<eof', 'single line contents', 'eof', ], expected_document_contents=hd.matches_resolved_value( ['single line contents']), source_after_parse=asrt_source.is_at_end_of_line(3)), SuccessfulCase( source_lines=[ '<<EOF', 'first line', 'second line', 'EOF', 'line after', ], expected_document_contents=hd.matches_resolved_value([ 'first line', 'second line', ]), source_after_parse=asrt_source.is_at_end_of_line(4)), ] for case in cases: self._check_case(case)
def check__simple_and_full__multi( put: unittest.TestCase, source_and_expectation_cases: Sequence[NIE[str, Expr]]): # ARRANGE # expected_source = asrt_source.is_at_end_of_line(1) for case in source_and_expectation_cases: for parser_case in _PARSER_CASES: with put.subTest(case.name, parser_case=parser_case.name): source = remaining_source(case.input_value) # ACT # actual = parser_case.value.parse(source) # ASSERT # expected_source.apply_with_message(put, source, 'source') put.assertEqual(case.expected_value, actual, 'parsed expression')
def runTest(self): # ARRANGE & ACT && ASSERT # integration_check.CHECKER__PARSE_FULL.check( self, args.RunProgram( program_args.system_program_argument_elements( NON_EXISTING_SYSTEM_PROGRAM)).as_remaining_source, integration_check.ARBITRARY_MODEL, arrangement_w_tcds(), Expectation( ParseExpectation(source=asrt_source.is_at_end_of_line(1), ), ExecutionExpectation( is_hard_error=asrt_text_doc.is_any_text()), ), )
def cases_wo_parentheses(expected_int: int) -> List[NSourceCase]: return [ NSourceCase( 'plain int', ParseSource(str(expected_int)), asrt_source.is_at_end_of_line(1), ), NSourceCase( 'plain int followed by other plain int', ParseSource(str(expected_int) + ' 77'), asrt_source.is_at_line(1, '77'), ), NSourceCase( 'plain int followed by end parenthesis', ParseSource(str(expected_int) + ' )'), asrt_source.is_at_line(1, ')'), ), ]
def test_token_SHOULD_be_interpreted_as_sym_ref_WHEN_sym_ref_syntax_is_used_for_existing_primitive( self): for grammar_description, grammar in GRAMMARS: with self.subTest(grammar=grammar_description): parse_check.check( self, self.parser_maker, Arrangement( grammar=grammar, source=remaining_source( symbol_reference_syntax_for_name( ast.PRIMITIVE_SANS_ARG)), ), Expectation( expression=ast.RefExpr(ast.PRIMITIVE_SANS_ARG), source=asrt_source.is_at_end_of_line(1), ), )
def _source_variants_with__for_expression_parser( num_expression_lines: int = 1 ) -> List[Tuple[Arguments, Assertion[ParseSource]]]: space = ' ' following_argument = 'argumentOfOthers' return [ (Arguments('', []), asrt_source.is_at_end_of_line(num_expression_lines)), (Arguments(space, ['following line']), asrt_source.assert_source( current_line_number=asrt.equals(num_expression_lines), remaining_part_of_current_line=asrt.equals(space[1:]))), (Arguments(space + following_argument, [' ']), asrt_source.assert_source( current_line_number=asrt.equals(num_expression_lines), remaining_part_of_current_line=asrt.equals(space[1:] + following_argument))), ]
def _doTest(self, maybe_not: ExpectationTypeConfigForNoneIsSuccess): self._check( test_configuration.source_for( args('{maybe_not} {equals} <<EOF', maybe_not=maybe_not.nothing__if_positive__not_option__if_negative), ['expected content line', 'EOF']), model_constructor.of_str(self, lines_content(['expected content line'])), arrangement_w_tcds( post_population_action=MK_SUB_DIR_OF_ACT_AND_MAKE_IT_CURRENT_DIRECTORY), Expectation( ParseExpectation( source=asrt_source.is_at_end_of_line(3), ), ExecutionExpectation( main_result=maybe_not.pass__if_positive__fail__if_negative, ), ), )
def test(self): path_suffix_of_symbol = 'first_path_component' file_symbol = NameAndValue('file_symbol', file_ref_of(RelOptionType.REL_TMP, path_suffix_of_symbol)) string_symbol = NameAndValue('string_symbol', 'string symbol value') reference_of_relativity_symbol = SymbolReference( file_symbol.name, path_relativity_restriction( syntax_elements.REL_OPTION_ARG_CONF.options.accepted_relativity_variants )) reference_of_path_string_symbol_as_path_component = SymbolReference(string_symbol.name, ReferenceRestrictionsOnDirectAndIndirect( direct=StringRestriction(), indirect=StringRestriction()), ) symbols = SymbolTable({ file_symbol.name: su.container(file_ref_resolvers.constant(file_symbol.value)), string_symbol.name: su.container(string_resolvers.str_constant(string_symbol.value)), }) cases = [ Case('symbol references in file', source='{rel_symbol_option} {file_symbol} {string_symbol}'.format( file_symbol=file_symbol.name, string_symbol=symbol_reference_syntax_for_name(string_symbol.name), rel_symbol_option=REL_symbol_OPTION, ), expectation= ExpectationOnExeFile( file_resolver_value=StackedFileRef(file_symbol.value, file_refs.constant_path_part(string_symbol.value)), expected_symbol_references_of_file=[reference_of_relativity_symbol, reference_of_path_string_symbol_as_path_component], argument_resolver_value=empty_list_value(), expected_symbol_references_of_argument=[], symbol_for_value_checks=symbols, ), source_after_parse=asrt_source.is_at_end_of_line(1), ), ] for case in cases: with self.subTest(name=case.name): _parse_and_check(self, case)
def test(self): file_symbol = ConstantSuffixPathDdvSymbolContext( 'file_symbol', RelOptionType.REL_TMP, 'first_path_component') string_symbol = StringConstantSymbolContext('string_symbol', 'string symbol value') reference_of_relativity_symbol = SymbolReference( file_symbol.name, path_relativity_restriction( syntax_elements.EXE_FILE_REL_OPTION_ARG_CONF.options. accepted_relativity_variants)) reference_of_path_string_symbol_as_path_component = SymbolReference( string_symbol.name, ReferenceRestrictionsOnDirectAndIndirect( direct=value_restrictions.is_string(), indirect=value_restrictions.is_string()), ) symbols = SymbolContext.symbol_table_of_contexts([ file_symbol, string_symbol, ]) cases = [ Case.of( 'symbol references in file', RelSymbolPathAbsStx(file_symbol.name, string_symbol.name__sym_ref_syntax), arguments=(), expectation=ExpectationOnExeFile( path_ddv=path_ddvs.stacked( file_symbol.ddv, path_ddvs.constant_path_part(string_symbol.str_value)), expected_symbol_references=[ reference_of_relativity_symbol, reference_of_path_string_symbol_as_path_component ], symbol_for_value_checks=symbols, ), source_after_parse=asrt_source.is_at_end_of_line(1), ), ] for case in cases: with self.subTest(name=case.name): _parse_and_check(self, case)
def test_valid_syntax_without_symbol_references(self): single_string_token_value = 'singleStringTokenValue' multiple_tokens_string_value = 'multiple tokens string value' following_arg_token = 'singleToken' cases = [ NameAndValue('non-quoted string-token on single line', ( [ single_string_token_value, ], ExpectedString(single_string_token_value, CommonExpectation( symbol_references=[], source=asrt_source.is_at_end_of_line(1))) ) ), NameAndValue('non-quoted string-token on following line', ( [ '', single_string_token_value, ], ExpectedString(single_string_token_value, CommonExpectation( symbol_references=[], source=asrt_source.is_at_end_of_line(2))) ) ), NameAndValue('non-quoted string-token on single line, followed by arguments on same line', ( [ '{string_token} {following_argument}'.format( string_token=single_string_token_value, following_argument=following_arg_token, ) ], ExpectedString(single_string_token_value, CommonExpectation( symbol_references=[], source=asrt_source.assert_source( current_line_number=asrt.equals(1), remaining_part_of_current_line=asrt.equals( following_arg_token)))) ) ), NameAndValue('quoted string-token on single line', ( [ surrounded_by_soft_quotes_str(multiple_tokens_string_value), ], ExpectedString(multiple_tokens_string_value, CommonExpectation( symbol_references=[], source=asrt_source.is_at_end_of_line(1))) ) ), ] for case in cases: source_lines, expected_string = case.value source = remaining_source_lines(source_lines) with self.subTest(case_name=case.name): _expect_string(self, source, expected_string)
def test(self): cases = [ Case('absolute_path', source=string_formatting.file_name(sys.executable), expectation= ExpectationOnExeFile( argument_resolver_value=empty_list_value(), file_resolver_value=file_refs.absolute_file_name(sys.executable), expected_symbol_references_of_file=[], expected_symbol_references_of_argument=[], ), source_after_parse=asrt_source.is_at_end_of_line(1), ), Case('without_option', source='file arg2', expectation= ExpectationOnExeFile( argument_resolver_value=empty_list_value(), file_resolver_value=file_ref_of_default_relativity('file'), expected_symbol_references_of_file=[], expected_symbol_references_of_argument=[], ), source_after_parse=has_remaining_part_of_first_line('arg2'), ), Case('relative_file_name_with_space', source='"the file"', expectation= ExpectationOnExeFile( argument_resolver_value=empty_list_value(), file_resolver_value=file_ref_of_default_relativity('the file'), expected_symbol_references_of_file=[], expected_symbol_references_of_argument=[], ), source_after_parse=asrt_source.is_at_end_of_line(1), ), Case('relative_file_name_with_space_and_arguments', source='"the file" "an argument"', expectation= ExpectationOnExeFile( argument_resolver_value=empty_list_value(), file_resolver_value=file_ref_of_default_relativity('the file'), expected_symbol_references_of_file=[], expected_symbol_references_of_argument=[], ), source_after_parse=has_remaining_part_of_first_line('"an argument"'), ), Case('option_without_tail', source='%s THE_FILE' % file_ref_texts.REL_HOME_CASE_OPTION, expectation= ExpectationOnExeFile( argument_resolver_value=empty_list_value(), file_resolver_value=file_ref_of(RelOptionType.REL_HOME_CASE, 'THE_FILE'), expected_symbol_references_of_file=[], expected_symbol_references_of_argument=[], ), source_after_parse=asrt_source.is_at_end_of_line(1), ), Case('option_with_tail', source='%s FILE tail' % file_ref_texts.REL_CWD_OPTION, expectation= ExpectationOnExeFile( argument_resolver_value=empty_list_value(), file_resolver_value=file_ref_of(RelOptionType.REL_CWD, 'FILE'), expected_symbol_references_of_file=[], expected_symbol_references_of_argument=[], ), source_after_parse=has_remaining_part_of_first_line('tail'), ), ] for case in cases: with self.subTest(name=case.name): _parse_and_check(self, case)
def test(self): single_token_value = 'single_token_value' string_symbol = NameAndValue('string_symbol_name', 'string symbol value') cases = [ Case('single string constant, at end of line, on the last line', source= remaining_source(single_token_value), expectation= Expectation(elements= [list_resolvers.str_element(single_token_value)], source= assert_source(is_at_eof=asrt.is_true)), ), Case('single symbol reference, at end of line, on the last line', source= remaining_source(symbol_reference_syntax_for_name(string_symbol.name)), expectation= Expectation(elements= [list_resolvers.symbol_element(symbol_reference(string_symbol.name))], source= assert_source(is_at_eof=asrt.is_true), references= asrt.matches_sequence([asrt_sym_ref.matches_reference_2( string_symbol.name, is_any_data_type_reference_restrictions()) ])), ), Case('complex element (str const and sym-refs), at end of line, on the last line', source= remaining_source(single_token_value + symbol_reference_syntax_for_name(string_symbol.name)), expectation= Expectation( elements= [ list_resolvers.string_element(string_resolvers.from_fragments([ string_resolvers.str_fragment(single_token_value), string_resolvers.symbol_fragment( SymbolReference(string_symbol.name, reference_restrictions.is_any_data_type()) ), ]))], references= asrt.matches_sequence([asrt_sym_ref.matches_reference_2( string_symbol.name, is_any_data_type_reference_restrictions()) ]), source= asrt_source.is_at_end_of_line(1)), ), Case('single element, followed by more than one space, on the last line', source= remaining_source(single_token_value + ' ', []), expectation= Expectation(elements= [list_resolvers.str_element(single_token_value)], source= asrt_source.is_at_line(1, ' ')), ), Case('single element, followed by single space, on the last line', source= remaining_source(single_token_value + ' ', []), expectation= Expectation(elements= [list_resolvers.str_element(single_token_value)], source= asrt_source.is_at_end_of_line(1)), ), Case('single element, followed by space, followed by empty line', source= remaining_source(single_token_value + ' ', ['']), expectation= Expectation(elements= [list_resolvers.str_element(single_token_value)], source= asrt_source.is_at_line(1, ' ')), ), Case('single element, at end of line, followed by line with only space', source= remaining_source(single_token_value, [' ']), expectation= Expectation(elements= [list_resolvers.str_element(single_token_value)], source= asrt_source.is_at_end_of_line(1)), ), Case('single element, followed by space, followed by line with only space', source= remaining_source(single_token_value + ' ', [' ']), expectation= Expectation(elements= [list_resolvers.str_element(single_token_value)], source= asrt_source.is_at_line(1, ' ')), ), Case('single element, at end of line, followed by line with invalid quoting', source= remaining_source(single_token_value, ['" ']), expectation= Expectation(elements= [list_resolvers.str_element(single_token_value)], source= asrt_source.is_at_end_of_line(1)), ), ] # ACT & ASSERT # _test_cases(self, cases)
def test_successful_parse_with_simple_expr(self): space_after = ' ' token_after = str(surrounded_by_hard_quotes('not an expression')) simple_expr = ast.SimpleSansArg() simple_expr_src = ast.SIMPLE_SANS_ARG for grammar_description, grammar in self.grammars: for prefix_operator, mk_prefix_expr in self.prefix_operators: cases = [ SourceCase( 'first line is only simple expr', source= remaining_source('{op} {simple_expr}'.format( op=prefix_operator, simple_expr=simple_expr_src, )), source_assertion= asrt_source.is_at_end_of_line(1) ), SourceCase( 'first line is simple expr with space around', source= remaining_source(' {op} {simple_expr}{space_after}'.format( op=prefix_operator, simple_expr=simple_expr_src, space_after=space_after)), source_assertion= asrt_source.source_is_not_at_end(current_line_number=asrt.equals(1), remaining_part_of_current_line=asrt.equals(space_after[1:])) ), SourceCase( 'expression is followed by non-expression', source= remaining_source('{op} {simple_expr} {token_after}'.format( op=prefix_operator, simple_expr=simple_expr_src, token_after=token_after)), source_assertion= asrt_source.source_is_not_at_end(current_line_number=asrt.equals(1), remaining_part_of_current_line=asrt.equals(token_after)) ), SourceCase( '( op simple )', source= remaining_source('( {op} {simple_expr} )'.format( op=prefix_operator, simple_expr=simple_expr_src, token_after=token_after)), source_assertion= asrt_source.is_at_end_of_line(1), ), SourceCase( 'op ( simple )', source= remaining_source('{op} ( {simple_expr} )'.format( op=prefix_operator, simple_expr=simple_expr_src, token_after=token_after)), source_assertion= asrt_source.is_at_end_of_line(1), ), ] for case in cases: with self.subTest(grammar=grammar_description, prefix_operator=prefix_operator, name=case.name): self._check( Arrangement( grammar=grammar, source=case.source), Expectation( expression=mk_prefix_expr(simple_expr), source=case.source_assertion, ) )
def test_valid_syntax_with_symbol_references(self): symbol = NameAndValue('symbol_name', 'symbol value') before_symbol = 'text before symbol' after_symbol = 'text after symbol' following_arg_token = 'singleToken' cases = [ NameAndValue('single unquoted symbol reference', ( [ symbol_reference_syntax_for_name(symbol.name), ], ExpectedString(symbol.value, CommonExpectation( symbol_references=[ references.reference_to_any_data_type_value(symbol.name), ], source=asrt_source.is_at_end_of_line(1), symbol_table=singleton_symbol_table_2(symbol.name, string_constant_container( symbol.value)), ) ) ) ), NameAndValue('single unquoted symbol reference followed by args on same line', ( [ '{sym_ref} {following_argument}'.format( sym_ref=symbol_reference_syntax_for_name(symbol.name), following_argument=following_arg_token, ), ], ExpectedString(symbol.value, CommonExpectation( symbol_references=[ references.reference_to_any_data_type_value(symbol.name), ], source=asrt_source.assert_source( current_line_number=asrt.equals(1), remaining_part_of_current_line=asrt.equals( following_arg_token)), symbol_table=singleton_symbol_table_2(symbol.name, string_constant_container( symbol.value)), ), ) ) ), NameAndValue('reference embedded in quoted string', ( [ '{soft_quote}{before_sym_ref}{sym_ref}{after_sym_ref}{soft_quote}'.format( soft_quote=SOFT_QUOTE_CHAR, sym_ref=symbol_reference_syntax_for_name(symbol.name), before_sym_ref=before_symbol, after_sym_ref=after_symbol, ) ], ExpectedString(before_symbol + symbol.value + after_symbol, CommonExpectation( symbol_references=[ references.reference_to_any_data_type_value(symbol.name), ], source=asrt_source.is_at_end_of_line(1), symbol_table=singleton_symbol_table_2(symbol.name, string_constant_container( symbol.value)), ) ) ) ), ] for case in cases: source_lines, expected_string = case.value source = remaining_source_lines(source_lines) with self.subTest(case_name=case.name): _expect_string(self, source, expected_string)
def test_success_of_expression_within_parentheses_spanning_several_lines(self): s = ast.SimpleSansArg() cases = [ ( 'simple expr and ) on following line', Arrangement( grammar=ast.GRAMMAR_WITH_ALL_COMPONENTS, source=remaining_source('(', ['{s} )'.format(s=ast.SIMPLE_SANS_ARG)]), ), Expectation( expression=s, source=asrt_source.is_at_end_of_line(2), ), ), ( 'simple expr and ) on following line, followed by non-expr', Arrangement( grammar=ast.GRAMMAR_WITH_ALL_COMPONENTS, source=remaining_source('(', ['{s} ) non-expr'.format(s=ast.SIMPLE_SANS_ARG)]), ), Expectation( expression=s, source=asrt_source.source_is_not_at_end(current_line_number=asrt.equals(2), remaining_part_of_current_line=asrt.equals('non-expr')), ), ), ( 'simple expr with ) on following line', Arrangement( grammar=ast.GRAMMAR_WITH_ALL_COMPONENTS, source=remaining_source('( {s}'.format(s=ast.SIMPLE_SANS_ARG), [' )']), ), Expectation( expression=s, source=asrt_source.is_at_end_of_line(2), ), ), ( 'simple expr with ) on following line, and non-expr on line after that', Arrangement( grammar=ast.GRAMMAR_WITH_ALL_COMPONENTS, source=remaining_source('( {s}'.format(s=ast.SIMPLE_SANS_ARG), [' )', 'non-expr']), ), Expectation( expression=s, source=asrt_source.is_at_end_of_line(2), ), ), ( 'binary op with only ( on first line', Arrangement( grammar=ast.GRAMMAR_WITH_ALL_COMPONENTS, source=remaining_source('(', [' {s} {op} {s} )'.format(s=ast.SIMPLE_SANS_ARG, op=ast.COMPLEX_A) ]), ), Expectation( expression=ComplexA([s, s]), source=asrt_source.is_at_end_of_line(2), ), ), ( 'binary op with ) on following line', Arrangement( grammar=ast.GRAMMAR_WITH_ALL_COMPONENTS, source=remaining_source('( {s} {op} {s}'.format(s=ast.SIMPLE_SANS_ARG, op=ast.COMPLEX_A), [' ) ']), ), Expectation( expression=ComplexA([s, s]), source=asrt_source.is_at_end_of_line(2), ), ), ] for case_name, arrangement, expectation in cases: with self.subTest(name=case_name): _check(self, arrangement, expectation )
def test_success_of_single_operator(self): space_after = ' ' quoted_string = str(surrounded_by_hard_quotes('quoted string')) valid_simple_expressions = [ ( '{simple_expression}'.format(simple_expression=ast.SIMPLE_SANS_ARG), ast.SimpleSansArg() ), ( '{simple_expression_name} {argument}'.format( simple_expression_name=ast.SIMPLE_WITH_ARG, argument='simple-expr-argument'), ast.SimpleWithArg('simple-expr-argument') ), ] operators = [ ( ast.COMPLEX_A, ast.ComplexA, ), ( ast.COMPLEX_B_THAT_IS_NOT_A_VALID_SYMBOL_NAME, ast.ComplexB, ), ] for valid_simple_expr_source, expected_simple_expr in valid_simple_expressions: for operator_source, operator_constructor in operators: expected_expression = operator_constructor([expected_simple_expr, expected_simple_expr]) cases = [ SourceCase( 'first line is just complex expr', source= remaining_source('{simple_expr} {operator} {simple_expr}'.format( simple_expr=valid_simple_expr_source, operator=operator_source, )), source_assertion= asrt_source.is_at_end_of_line(1) ), SourceCase( 'first line is complex expr, followed by space', source= remaining_source('{simple_expr} {operator} {simple_expr}{space_after}'.format( simple_expr=valid_simple_expr_source, operator=operator_source, space_after=space_after, )), source_assertion= asrt_source.source_is_not_at_end( current_line_number=asrt.equals(1), remaining_part_of_current_line=asrt.equals(space_after[1:])) ), SourceCase( 'complex expr followed by non-operator', source= remaining_source('{simple_expr} {operator} {simple_expr} {quoted_string}'.format( simple_expr=valid_simple_expr_source, operator=operator_source, quoted_string=quoted_string, )), source_assertion= asrt_source.source_is_not_at_end( current_line_number=asrt.equals(1), remaining_part_of_current_line=asrt.equals(quoted_string)) ), SourceCase( 'complex expr followed by simple expression', source= remaining_source('{simple_expr} {operator} {simple_expr} {simple_expr}'.format( simple_expr=valid_simple_expr_source, operator=operator_source, )), source_assertion= asrt_source.source_is_not_at_end( current_line_number=asrt.equals(1), remaining_part_of_current_line=asrt.equals(valid_simple_expr_source)) ), SourceCase( 'complex expr followed by quoted operator', source= remaining_source('{simple_expr} {operator} {simple_expr} {quoted_operator}'.format( simple_expr=valid_simple_expr_source, operator=operator_source, quoted_operator=surrounded_by_soft_quotes(operator_source), )), source_assertion= asrt_source.source_is_not_at_end( current_line_number=asrt.equals(1), remaining_part_of_current_line=asrt.equals(str(surrounded_by_soft_quotes(operator_source)))) ), SourceCase( 'first line is just complex expr: inside ()', source= remaining_source('( {simple_expr} {operator} {simple_expr} )'.format( simple_expr=valid_simple_expr_source, operator=operator_source, )), source_assertion= asrt_source.is_at_end_of_line(1) ), SourceCase( 'first simple expr inside ()', source= remaining_source('( {simple_expr} ) {operator} {simple_expr}'.format( simple_expr=valid_simple_expr_source, operator=operator_source, )), source_assertion= asrt_source.is_at_end_of_line(1) ), SourceCase( 'second simple expr inside ()', source= remaining_source('{simple_expr} {operator} ( {simple_expr} )'.format( simple_expr=valid_simple_expr_source, operator=operator_source, )), source_assertion= asrt_source.is_at_end_of_line(1) ), SourceCase( 'second expr on following line', source= remaining_source(valid_simple_expr_source + ' ' + operator_source, [valid_simple_expr_source]), source_assertion= asrt_source.is_at_end_of_line(2) ), ] for case in cases: with self.subTest(name=case.name, operator_source=operator_source, valid_simple_expr_source=valid_simple_expr_source): _check(self, Arrangement( grammar= ast.GRAMMAR_WITH_ALL_COMPONENTS, source= case.source), Expectation( expression= expected_expression, source= case.source_assertion, ) )
def test_successful_parse_of_expr_with_argument(self): the_argument = 'the-argument' space_after = ' ' token_after = str(surrounded_by_hard_quotes('not an expression')) for grammar_description, grammar in self.grammars: cases = [ SourceCase( 'first line is only simple expr', source= remaining_source('{simple_with_arg} {argument}'.format( simple_with_arg=ast.SIMPLE_WITH_ARG, argument=the_argument)), source_assertion= asrt_source.is_at_end_of_line(1) ), SourceCase( 'first line is simple expr with space around', source= remaining_source(' {simple_with_arg} {argument}{space_after}'.format( simple_with_arg=ast.SIMPLE_WITH_ARG, argument=the_argument, space_after=space_after)), source_assertion= asrt_source.source_is_not_at_end(current_line_number=asrt.equals(1), remaining_part_of_current_line=asrt.equals(space_after[1:])) ), SourceCase( 'expression is followed by non-expression', source= remaining_source(' {simple_with_arg} {argument} {token_after}'.format( simple_with_arg=ast.SIMPLE_WITH_ARG, argument=the_argument, token_after=token_after)), source_assertion= asrt_source.source_is_not_at_end(current_line_number=asrt.equals(1), remaining_part_of_current_line=asrt.equals(token_after)) ), SourceCase( '( simple )', source= remaining_source('( {simple_with_arg} {argument} )'.format( simple_with_arg=ast.SIMPLE_WITH_ARG, argument=the_argument, )), source_assertion= asrt_source.is_at_end_of_line(1), ), SourceCase( '( ( simple ) )', source= remaining_source('( ( {simple_with_arg} {argument} ) )'.format( simple_with_arg=ast.SIMPLE_WITH_ARG, argument=the_argument, )), source_assertion= asrt_source.is_at_end_of_line(1), ), ] for case in cases: with self.subTest(grammar=grammar_description, name=case.name): self._check( Arrangement( grammar=grammar, source=case.source), Expectation( expression=ast.SimpleWithArg(the_argument), source=case.source_assertion, ) )
def test(self): single_token_value = 'single_token_value' single_token_value_1 = 'single_token_value_1' single_token_value_2 = 'single_token_value_2' symbol_name = 'a_symbol_name' cases = [ Case('multiple string constants on line that is the last line', source= remaining_source(single_token_value_1 + ' ' + single_token_value_2), expectation= Expectation(elements= [list_resolvers.str_element(single_token_value_1), list_resolvers.str_element(single_token_value_2) ], source=asrt_source.is_at_end_of_line(1)), ), Case('multiple string constants on line that is followed by an empty line', source= remaining_source(single_token_value_1 + ' ' + single_token_value_2, ['']), expectation= Expectation(elements= [list_resolvers.str_element(single_token_value_1), list_resolvers.str_element(single_token_value_2) ], source= asrt_source.is_at_end_of_line(1)), ), Case('multiple string constants on line that is followed by a non-empty line', source= remaining_source(single_token_value_1 + ' ' + single_token_value_2, [' ']), expectation= Expectation(elements= [list_resolvers.str_element(single_token_value_1), list_resolvers.str_element(single_token_value_2) ], source= asrt_source.is_at_end_of_line(1)), ), Case('symbol-reference and string constant on first line', source= remaining_source('{sym_ref} {string_constant}'.format( sym_ref=symbol_reference_syntax_for_name(symbol_name), string_constant=single_token_value)), expectation= Expectation(elements= [list_resolvers.symbol_element(symbol_reference(symbol_name)), list_resolvers.str_element(single_token_value) ], references= asrt.matches_sequence([asrt_sym_ref.matches_reference_2( symbol_name, is_any_data_type_reference_restrictions()) ]), source= asrt_source.is_at_end_of_line(1)), ), Case('complex element (sym-ref and str const) and string constant, ' 'followed by space, ' 'followed by non-empty line', source= remaining_source(symbol_reference_syntax_for_name(symbol_name) + single_token_value + ' ' + single_token_value_1, [' ']), expectation= Expectation( elements= [ list_resolvers.string_element(string_resolvers.from_fragments([ string_resolvers.symbol_fragment(SymbolReference(symbol_name, reference_restrictions.is_any_data_type())), string_resolvers.str_fragment(single_token_value), ])), list_resolvers.str_element(single_token_value_1), ], references= asrt.matches_sequence([asrt_sym_ref.matches_reference_2( symbol_name, is_any_data_type_reference_restrictions()) ]), source= asrt_source.is_at_end_of_line(1)), ), ] # ACT & ASSERT # _test_cases(self, cases)