예제 #1
0
    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))
예제 #2
0
 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))
예제 #3
0
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))
예제 #4
0
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))
예제 #5
0
 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)
예제 #6
0
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),
        ))
예제 #7
0
 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')
예제 #8
0
    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')
예제 #9
0
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, )))
예제 #10
0
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
예제 #11
0
    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)
예제 #12
0
 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)