def _consume_and_return_current_line( source: ParseSource, line_predicate_for_line_to_consume: Callable[[str], bool], ) -> line_source.LineSequence: current_line = source.current_line lines = [current_line.text] source.consume_current_line() while source.has_current_line and line_predicate_for_line_to_consume( source.current_line_text): lines.append(source.current_line_text) source.consume_current_line() return line_source.LineSequence(current_line.line_number, tuple(lines))
def parse(self, fs_location_info: FileSystemLocationInfo, source: ParseSource) -> sut.ParsedInstruction: first_line_number = source.current_line_number dummy_source = line_source.LineSequence(first_line_number, (source.current_line_text, )) is_instruction = False while not source.is_at_eof and source.current_line_text.startswith( self.instruction_line_identifier): source.consume_current_line() is_instruction = True if not is_instruction: raise ValueError('Not an instruction') return sut.ParsedInstruction(dummy_source, InstructionInfo(Instruction(), None))
def new_instruction( line_number: int, line_text: str, section_name: str, file_path: pathlib.Path = None, file_inclusion_chain: List[SourceLocation] = () ) -> model.SectionContentElement: builder = SectionContentElementBuilder( FileLocationInfo( pathlib.Path('/'), file_path, file_inclusion_chain, )) return builder.new_instruction( line_source.LineSequence(line_number, (line_text, )), InstructionInSection(section_name))
def parse_and_compute_source(parser: InstructionParser, fs_location_info: FileSystemLocationInfo, source: ParseSource, description: str = None) -> ParsedInstruction: source_before = source.remaining_source first_line_number = source.current_line_number len_before_parse = len(source_before) instruction = parser.parse(fs_location_info, source) len_after_parse = len(source.remaining_source) len_instruction_source = len_before_parse - len_after_parse instruction_source = source_before[:len_instruction_source] lines = instruction_source.split('\n') if len(lines) > 1 and lines[-1] == '': del lines[-1] source = line_source.LineSequence(first_line_number, tuple(lines)) return ParsedInstruction(source, InstructionInfo(instruction, description))
def _consume_instruction_source( source: ParseSource) -> line_source.LineSequence: current_line = source.current_line_text if is_multi_line_instruction_line(current_line): first_line_number = source.current_line_number lines = [current_line] source.consume_current_line() # Eat additional lines while source.has_current_line: current_line = source.current_line_text if is_multi_line_instruction_line(current_line): lines.append(current_line) source.consume_current_line() else: break return line_source.LineSequence(first_line_number, tuple(lines)) else: return consume_current_line_and_return_it_as_line_sequence(source)
def equals_multi_line_instruction_without_description( line_number: int, lines: list, section_name: str, file_path: pathlib.Path, file_inclusion_chain: List[SourceLocation], ) -> Assertion[model.SectionContentElement]: return matches_section_contents_element( ElementType.INSTRUCTION, instruction_info=matches_instruction_info_without_description( equals_instruction_in_section(InstructionInSection(section_name))), source_location_info=matches_source_location_info2( source=equals_line_sequence( line_source.LineSequence(line_number, tuple(lines))), file_path_rel_referrer=asrt.equals(file_path), file_inclusion_chain=equals_file_inclusion_chain( file_inclusion_chain), ))
def test_element_from_instruction_parser_SHOULD_be_assigned_to_section_contents_element( self): expected_instruction_info = InstructionInfo(Instruction(), 'description') expected = sut.ParsedInstruction( line_source.LineSequence(1, ('first line text', )), expected_instruction_info) parser = sut.standard_syntax_element_parser( _InstructionParserThatGivesConstant(expected)) source = _source_for_lines(['ignored', 'source', 'lines']) # ACT # element = parser.parse(ARBITRARY_FS_LOCATION_INFO, source) # ASSERT # element_assertion = matches_instruction( source=asrt.is_(expected.source), instruction_info=matches_instruction_info( assertion_on_description=asrt.is_( expected_instruction_info.description), assertion_on_instruction=asrt.is_( expected_instruction_info.instruction))) element_assertion.apply_with_message(self, element, 'element')
def test_file_inclusion_directive(self): self._check(sut.ParsedFileInclusionDirective(LINE_SEQUENCE, []), sut.ParsedFileInclusionDirective) def test_visit_SHOULD_raise_TypeError_WHEN_argument_is_not_a_sub_class_of_argument( self): visitor = ArgumentRecordingArgumentVisitor() with self.assertRaises(TypeError): visitor.visit(UnknownParsedSectionElementSubClass(LINE_SEQUENCE)) def _check(self, x: sut.ParsedSectionElement, expected_class): # ARRANGE # visitor = ArgumentRecordingArgumentVisitor() # ACT # returned = visitor.visit(x) # ASSERT # self.assertListEqual([expected_class], visitor.visited_classes) self.assertIs( x, returned, 'Visitor should return the return-value of the visited method') class UnknownParsedSectionElementSubClass(sut.ParsedSectionElement): def __init__(self, source: line_source.LineSequence): super().__init__(source) LINE_SEQUENCE = line_source.LineSequence(1, ('line text', )) INSTRUCTION_INFO = InstructionInfo(Instruction(), 'description')
def new_empty(line_number: int, line_text: str) -> model.SectionContentElement: return _ELEMENT_BUILDER_WITHOUT_FILE_PATH.new_empty( line_source.LineSequence(line_number, (line_text, )))
def consume_current_line_and_return_it_as_line_sequence(source: ParseSource) -> line_source.LineSequence: ret_val = line_source.LineSequence(source.current_line_number, (source.current_line_text,)) source.consume_current_line() return ret_val
def parse(self, fs_location_info: FileSystemLocationInfo, source: ParseSource): lines = line_source.LineSequence(source.current_line_number, (source.current_line_text, )) raise UnrecognizedSectionElementSourceError(lines, self.err_msg)
def instruction_element(self, instruction) -> doc.SectionContentElement: line_no = self._current_line self._current_line += 1 source = line_source.LineSequence(line_no, ('Line ' + str(line_no),)) return self._element_builder.new_instruction(source, instruction)