def test_source_string_reader(self) -> None:
     """
     Checks that the text can be retrieved from a string reader.
     """
     text = 'Peek-a-boo!\nI see you.\n'
     expected = text
     unit_under_test = SourceStringReader(text)
     assert unit_under_test.get_text() == expected
Exemplo n.º 2
0
 def testSourceStringReader(self):
     # pylint: disable=no-self-use
     '''
     Checks that the text can be retrieved from a string reader.
     '''
     text = 'Peek-a-boo!\nI see you.\n'
     expected = text
     unit_under_test = SourceStringReader(text)
     assert unit_under_test.get_text() == expected
    def test_preprocessed_fortran_source(self) -> None:
        source = """! Some things happen, others don't
module test_mod
#ifdef EXTRA
  use extra_mod, only: special
#endif
  implicit none
contains
  function normal()
  end function normal
  #ifdef EXTRA
  function more()
  end function more
  #endif EXTRA
end module test_mod
"""
        expected = """! Some things happen, others don't
module test_mod
! #ifdef EXTRA
  use extra_mod, only: special
! #endif
  implicit none
contains
  function normal()
  end function normal
  ! #ifdef EXTRA
  function more()
  end function more
  ! #endif EXTRA
end module test_mod
"""
        reader = SourceStringReader(source)
        unit_under_test = FortranPreProcessor(reader)
        assert unit_under_test.get_text() == expected
Exemplo n.º 4
0
    def test_preprocessed_pfunit_source(self):
        # pylint: disable=no-self-use
        source = '''! Test all the things
module test_mod
  use pFUnit
  implicit none
contains
  @test
  subroutine test_normal()
  end subroutine test_normal
end module test_mod
'''
        expected = '''! Test all the things
module test_mod
  use pFUnit
  implicit none
contains
  ! @test
  subroutine test_normal()
  end subroutine test_normal
end module test_mod
'''
        reader = SourceStringReader(source)
        unit_under_test = PFUnitProcessor(reader)
        assert unit_under_test.get_text() == expected
Exemplo n.º 5
0
    def test_implicit_double(
            self,
            containing_program_unit: Tuple[str, List[str]],
            subprogram_implicit: Tuple[str, List[str]],
            second_subprogram_implicit: Tuple[str, List[str]]) -> None:
        """
        Checks all the permutations of two contained procedures.
        """
        procedure = '\n'.join([subprogram_implicit[0],
                               second_subprogram_implicit[0]]).strip()
        text = containing_program_unit[0].format(procedure=procedure)
        reader = SourceStringReader(text)
        source = FortranSource(reader)

        insert_point = containing_program_unit[0].find('{procedure}')
        insert_line = containing_program_unit[0].count('\n',
                                                       0,
                                                       insert_point) + 1
        first_len = subprogram_implicit[0].count('\n')
        if first_len > 0:
            first_len += 1

        expectation = []
        for thing in containing_program_unit[1]:
            expectation.append(f"1: {thing}")
        for thing in subprogram_implicit[1]:
            expectation.append(f"{insert_line}: {thing}")
        for thing in second_subprogram_implicit[1]:
            expectation.append(f"{insert_line + first_len}: {thing}")

        unit_under_test = stylist.fortran.MissingImplicit('none')
        issues = unit_under_test.examine(source)
        issue_descriptions = [str(issue) for issue in issues]
        assert issue_descriptions == expectation
    def test_preprocessed_c_source(self) -> None:
        source = """/* Some things happen, others don't */
#ifndef TEST_HEADER
#define TEST_HEADER

  #include <stdbool.h>

int normal(void);
#ifdef EXTRA
char *more(void);
#endif
#endif
"""
        expected = """/* Some things happen, others don't */
// #ifndef TEST_HEADER
// #define TEST_HEADER

  // #include <stdbool.h>

int normal(void);
// #ifdef EXTRA
char *more(void);
// #endif
// #endif
"""
        reader = SourceStringReader(source)
        unit_under_test = CPreProcessor(reader)
        assert unit_under_test.get_text() == expected
Exemplo n.º 7
0
    def test_preprocessed_c_source(self):
        # pylint: disable=no-self-use
        source = '''/* Some things happen, others don't */
#ifndef TEST_HEADER
#define TEST_HEADER

  #include <stdbool.h>

int normal(void);
#ifdef EXTRA
char *more(void);
#endif
#endif
'''
        expected = '''/* Some things happen, others don't */
// #ifndef TEST_HEADER
// #define TEST_HEADER

  // #include <stdbool.h>

int normal(void);
// #ifdef EXTRA
char *more(void);
// #endif
// #endif
'''
        reader = SourceStringReader(source)
        unit_under_test = CPreProcessor(reader)
        assert unit_under_test.get_text() == expected
    def test_exit_labels(self, module_name: str) -> None:
        """
        Checks that the rule reports missing "implicit" labels correctly
        """
        template = '''
program test
contains
    function function1()
        use {module_name}
    end function function1

    function function2()
        use, intrinsic :: {module_name}
    end function function2
end program test
'''

        expectation: List[str] = []
        message = '{line}: Usage of intrinsic module "{module_name}" without '\
                  '"intrinsic" clause.'
        if module_name.lower() in [
                "iso_c_binding", "iso_fortran_env", "ieee_exceptions",
                "ieee_arithmetic", "ieee_features"
        ]:
            expectation.extend([
                message.format(line=5, module_name=module_name),
            ])
        text = template.format(module_name=module_name)
        print(text)  # Shows up in failure reports, for debugging
        reader = SourceStringReader(text)
        source = FortranSource(reader)
        unit_under_test = IntrinsicModule()
        issues = unit_under_test.examine(source)
        issue_descriptions = [str(issue) for issue in issues]
        assert issue_descriptions == expectation
Exemplo n.º 9
0
 def test_simple(self, simple_source: Tuple[str, List[str]]) -> None:
     """
     Ensures a given input source generates the correct issue list.
     """
     unit_under_test = stylist.fortran.FortranCharacterset()
     reader = SourceStringReader(simple_source[0])
     source = FortranSource(reader)
     issues = unit_under_test.examine(source)
     assert [str(issue) for issue in issues] == simple_source[1]
Exemplo n.º 10
0
    def test_use(self, unit_type, unit_usage, procedure_usage, ignorance):
        """
        Checks that the rule reports missing "use" clauses correctly.
        """
        def prepare(line_number: int, params):
            usage = []
            expectations = []
            for details in params:
                line = None
                if details[0] is not None:
                    line = 'use {0}'.format(details[0])
                    if details[1]:
                        line += ', only : {0}'.format(', '.join(details[1]))
                        line_number += 1
                    elif details[0] not in ignorance:
                        message = f'{line_number}: Usage of "{details[0]}" ' \
                                  f'without "only" clause.'
                        expectations.append(message)
                        line_number += 1
                if line:
                    usage.append(line)
            return usage, expectations, line_number

        text = '''{type} test
                   {uusage}
                   implicit none
                 contains
                   subroutine foo()
                     {pusage}
                     implicit none
                   end subroutine foo
                 end {type} test
               '''
        unit_lines, unit_expects, last_line = prepare(2, unit_usage)
        if len(unit_lines) == 0:
            last_line += 1
        proc_lines, proc_expects, _ = prepare(last_line + 3, procedure_usage)
        reader = SourceStringReader(
            text.format(type=unit_type,
                        uusage='\n'.join(unit_lines),
                        pusage='\n'.join(proc_lines)))
        source = FortranSource(reader)

        expectation = list(unit_expects)
        expectation.extend(proc_expects)
        print(
            text.format(type=unit_type,
                        uusage='\n'.join(unit_lines),
                        pusage='\n'.join(proc_lines)))
        print(expectation)
        if ignorance:
            unit_under_test = stylist.fortran.MissingOnly(ignore=ignorance)
        else:
            unit_under_test = stylist.fortran.MissingOnly()
        issues = unit_under_test.examine(source)
        issue_descriptions = [str(issue) for issue in issues]
        assert issue_descriptions == expectation
Exemplo n.º 11
0
 def test_path_string(self, path_case):
     '''
     Checks that matching a path to the source works.
     '''
     # pylint: disable=no-self-use
     reader = SourceStringReader(path_case[0])
     unit_under_test = FortranSource(reader)
     result = unit_under_test.path('/'.join(path_case[1]))
     assert [obj.__class__.__name__ for obj in result] == path_case[2]
Exemplo n.º 12
0
 def test_path_string(self, path_case: Tuple[str, List[str], List[str]]) \
         -> None:
     """
     Checks that matching a path to the source works.
     """
     reader = SourceStringReader(path_case[0])
     unit_under_test = FortranSource(reader)
     result = unit_under_test.path('/'.join(path_case[1]))
     assert [obj.__class__.__name__ for obj in result] == path_case[2]
Exemplo n.º 13
0
 def test_simple(self, simple_source):
     # pylint: disable=no-self-use
     '''
     Ensures a given input source generates the correct issue list.
     '''
     unit_under_test = stylist.fortran.FortranCharacterset()
     reader = SourceStringReader(simple_source[0])
     source = FortranSource(reader)
     issues = unit_under_test.examine(source)
     assert [str(issue) for issue in issues] == simple_source[1]
Exemplo n.º 14
0
 def test_examples(self, example_source: Tuple[str, List[int]]) -> None:
     """
     Ensures trailing whitespace is detected on the correct lines.
     """
     unit_under_test = stylist.rule.TrailingWhitespace()
     reader = SourceStringReader(example_source[0])
     issues = unit_under_test.examine(reader)
     assert ([str(issue) for issue in issues] == [
         str(eln) + ': Found trailing white space'
         for eln in example_source[1]
     ])
Exemplo n.º 15
0
    def test(self):
        """
        Ensures the test case produces exactly the issues in expectation
        """
        reader = SourceStringReader(TEST_CASE)
        source = FortranSource(reader)
        unit_under_test = stylist.fortran.AutoCharArrayIntent()
        issues = unit_under_test.examine(source)
        strings = [str(issue) for issue in issues]

        assert strings == TEST_EXPECTATION
Exemplo n.º 16
0
 def test_examination(self):
     """
     Checks that all the rules in a style get a look at the program.
     """
     rule_one = TestStyle._RuleHarness()
     rule_two = TestStyle._RuleHarness()
     unit_under_test = TestStyle._StyleHarness([rule_one, rule_two])
     reader = SourceStringReader('module foo\nend module foo\n')
     source = FortranSource(reader)
     unit_under_test.check(source)
     assert rule_one.examined == ['module foo\nend module foo\n']
     assert rule_two.examined == ['module foo\nend module foo\n']
Exemplo n.º 17
0
 def test_find_all(self) -> None:
     """
     Checks that finding all occurrences of a source part works.
     """
     reader = SourceStringReader(self._MULTI_PROC_MODULE)
     unit_under_test = FortranSource(reader)
     wanted = fparser.two.Fortran2003.Module_Subprogram
     result = unit_under_test.find_all(wanted)
     assert str(next(result).content[0].items[1]) == 'one'
     assert str(next(result).content[0].items[1]) == 'two'
     with pytest.raises(StopIteration):
         next(result)
Exemplo n.º 18
0
 def test_examples(self, example_source):
     '''
     Ensures trailing whitespace is detected on the correct lines.
     '''
     unit_under_test = stylist.rule.TrailingWhitespace()
     reader = SourceStringReader(example_source[0])
     source = FortranSource(reader)
     issues = unit_under_test.examine(source)
     assert ([str(issue) for issue in issues] == [
         str(eln) + ': Found trailing white space'
         for eln in example_source[1]
     ])
    def test_implicit(self, empty_program_unit_implicit):
        # pylint: disable=no-self-use
        '''
        Checks all permutations of program units.
        '''
        reader = SourceStringReader(empty_program_unit_implicit[0])
        source = FortranSource(reader)

        expectation = []
        for thing in empty_program_unit_implicit[1]:
            expectation.append(f"1: {thing}")

        unit_under_test = stylist.fortran.MissingImplicit('none')
        issues = unit_under_test.examine(source)
        issue_descriptions = [str(issue) for issue in issues]
        assert issue_descriptions == expectation
Exemplo n.º 20
0
    def test_implicit(self,
                      empty_program_unit_implicit: Tuple[str, List[str]]) \
            -> None:
        """
        Checks all permutations of program units.
        """
        reader = SourceStringReader(empty_program_unit_implicit[0])
        source = FortranSource(reader)

        expectation = []
        for thing in empty_program_unit_implicit[1]:
            expectation.append(f"1: {thing}")

        unit_under_test = stylist.fortran.MissingImplicit('none')
        issues = unit_under_test.examine(source)
        issue_descriptions = [str(issue) for issue in issues]
        assert issue_descriptions == expectation
Exemplo n.º 21
0
    def test_constructor(self) -> None:
        """
        Checks that the source file is correctly parsed on construction.
        """
        inject = r"""! Test program
program test
  implicit none
  write(6, '("Hello ", A)') 'world'
end program test
"""
        reader = SourceStringReader(inject)
        unit_under_test = FortranSource(reader)
        assert unit_under_test.get_text() == inject

        expected_string = """! Test program
PROGRAM test
  IMPLICIT NONE
  WRITE(6, FMT = '("Hello ", A)') 'world'
END PROGRAM test"""
        assert str(unit_under_test.get_tree()) == expected_string
Exemplo n.º 22
0
    def test_constructor(self):
        '''
        Checks that the source file is correctly parsed on construction.
        '''
        # pylint: disable=no-self-use
        inject = r'''! Test program
program test
  implicit none
  write(6, '("Hello ", A)') 'world'
end program test
'''
        reader = SourceStringReader(inject)
        unit_under_test = FortranSource(reader)
        assert unit_under_test.get_text() == inject

        expected_string = '''! Test program
PROGRAM test
  IMPLICIT NONE
  WRITE(6, FMT = '("Hello ", A)') 'world'
END PROGRAM test'''
        assert str(unit_under_test.get_tree()) == expected_string
    def test_intent(self, parent_container, procedure, arguments, intent) \
            -> None:
        """
        Checks all permutations.
        """

        text = parent_container.format(procedure=procedure[0])
        text = text.format(dummy_args=','.join(
            [x.lower() for x in arguments[0]]),
                           type_declaration=arguments[1])

        if intent != '':
            intent_str = ', ' + intent
        else:
            intent_str = intent

        text = text.format(intent=intent_str)

        print(text)

        expectation = []
        issue_base = '{line}: Dummy argument "{arg}" of {unit_type} "{unit}" '\
                     'is missing an "intent" statement'
        for arg in arguments[0]:
            if intent == '' or 'type_declaration' not in procedure[0]:
                expectation.append(
                    issue_base.format(line=3,
                                      arg=arg.lower(),
                                      unit_type=procedure[1],
                                      unit='test_' + procedure[1]))

        reader = SourceStringReader(text)
        source = FortranSource(reader)
        unit_under_test = stylist.fortran.MissingIntent()
        issues = unit_under_test.examine(source)
        issue_descriptions = [str(issue) for issue in issues]

        assert issue_descriptions == expectation
Exemplo n.º 24
0
    def test_preprocessed_pfunit_source(self) -> None:
        source = """! Test all the things
module test_mod
  use pFUnit
  implicit none
contains
  @test
  subroutine test_normal()
  end subroutine test_normal
end module test_mod
"""
        expected = """! Test all the things
module test_mod
  use pFUnit
  implicit none
contains
  ! @test
  subroutine test_normal()
  end subroutine test_normal
end module test_mod
"""
        reader = SourceStringReader(source)
        unit_under_test = PFUnitProcessor(reader)
        assert unit_under_test.get_text() == expected
Exemplo n.º 25
0
    def test_exit_labels(self, do_construct_name: str) -> None:
        """
        Checks that the rule reports missing exit labels correctly.
        """
        template = '''
program test
contains
    function function1()
        foo : do
            exit {do_construct_name}
        end do foo
    end function function1

    function function2()
        foo : do
            if (.true.) exit {do_construct_name}
        end do foo
    end function function2
end program test
'''

        expectation: List[str] = []
        message = '{line}: Usage of "exit" without label indicating which ' \
                  '"do" construct is being exited from.'
        if do_construct_name == '':
            expectation.extend(
                [message.format(line=6),
                 message.format(line=12)])
        text = template.format(do_construct_name=do_construct_name)
        print(text)  # Shows up in failure reports, for debugging
        reader = SourceStringReader(text)
        source = FortranSource(reader)
        unit_under_test = LabelledDoExit()
        issues = unit_under_test.examine(source)
        issue_descriptions = [str(issue) for issue in issues]
        assert issue_descriptions == expectation
Exemplo n.º 26
0
    def test_pointer_init(self,
                          prog_unit,
                          type_pointer,
                          unit_pointer,
                          proc_pointer):
        """
        Checks that the rule reports missing pointer initialisation correctly.
        """
        template = '''
{prog_unit} test
  implicit none
  private
  type foo_type
    private
    integer{type_attr} :: type_{type_decl}, second_type_{type_decl}
    ! Procedure pointers have to be pointers.
    procedure(some_if), nopass, pointer :: type_proc_pointer_{type_decl}, &
                                           other_type_proc_pointer_{type_decl}
  end type foo_type
  type(foo_type){unit_attr} :: unit_{unit_decl}
  procedure(some_if){unit_attr} :: unit_proc_{unit_decl}
contains
  ! A comment for the function
  !
  function qux() result(answer)
    implicit none
    ! It isn't possible to initialise function return variables
    real, pointer :: answer(:)
  end function qux
  !
  ! Comment for the subroutine
  !
  subroutine bar()
    implicit none
    type(foo_type){proc_attr} :: proc_{proc_decl}
    procedure(some_if){proc_attr} :: proc_proc_{proc_decl}
    integer{proc_attr} :: proc_var_{proc_decl}
  end subroutine bar
  logical function whatev()
    ! Functions may also be declared this way.
    implicit none
    whatev = .true.
  end function whatev
  subroutine baz( thing, thang, thong, bong )
    implicit none
    ! Intent in arguments aren't initialised
    type(foo_type), intent(in), pointer :: thing
    procedure(some_if), intent(in), pointer :: thang
    ! Oddly intent out arguments can't be initialised either
    logical, intent(out), pointer :: bong
    !Intent inout arguments aren't initialised
    real, intent(in out), pointer :: thong(:)
  end subroutine baz
end {prog_unit} test
'''

        expectation: List[str] = []
        message = '{line}: Declaration of pointer ' \
                  '"{name}" without initialisation.'
        if type_pointer != 'nullpointer':
            suffix = self._DECL_MAP[type_pointer].partition(' ')[0]
            expectation.extend([
                message.format(line=9,
                               name=f'other_type_proc_pointer_{suffix}'),
                message.format(line=9,
                               name=f'type_proc_pointer_{suffix}')
            ])
        if type_pointer == 'pointer':
            expectation.extend([message.format(line=7,
                                               name='second_type_bare'),
                                message.format(line=7,
                                               name='type_bare')])
        if proc_pointer == 'pointer':
            expectation.extend([message.format(line=27,
                                               name='proc_bare'),
                                message.format(line=28,
                                               name='proc_proc_bare'),
                                message.format(line=29,
                                               name='proc_var_bare')])
        if unit_pointer == 'pointer':
            expectation.extend([message.format(line=12,
                                               name='unit_bare'),
                                message.format(line=13,
                                               name='unit_proc_bare')])
        expectation.sort(key=lambda x: (int(x.split(':', 1)[0]),
                                        x.split(':', 1)))

        text = template.format(
            prog_unit=prog_unit,
            type_attr=self._ATTR_MAP[type_pointer],
            type_decl=self._DECL_MAP[type_pointer],
            unit_attr=self._ATTR_MAP[unit_pointer],
            unit_decl=self._DECL_MAP[unit_pointer],
            proc_attr=self._ATTR_MAP[proc_pointer],
            proc_decl=self._DECL_MAP[proc_pointer])
        print(text)  # Shows up in failure reports, for debugging
        reader = SourceStringReader(text)
        source = FortranSource(reader)
        unit_under_test = stylist.fortran.MissingPointerInit()
        issues = unit_under_test.examine(source)
        issue_descriptions = [str(issue) for issue in issues]
        issue_descriptions.sort(key=lambda x: (int(x.split(':', 1)[0]),
                                               x.split(':', 1)))
        print(issue_descriptions)
        print(expectation)
        assert issue_descriptions == expectation