def test_add_prerequisite(self): test_unit \ = CInfo(CSymbolID('argle', Path('bargle/wargle.gargle'))) assert test_unit.depends_on == [] test_unit.add_prerequisite('cheese') assert test_unit.depends_on == ['cheese']
def test_equality(self): test_unit \ = CInfo(CSymbolID('argle', Path('bargle/wargle.gargle')), ['beef', 'cheese']) with pytest.raises(TypeError): _ = test_unit == 'not a CInfo' other = CInfo(CSymbolID('argle', Path('bargle/wargle.gargle')), ['beef', 'cheese']) assert test_unit == other assert other == test_unit other = CInfo(CSymbolID('argle', Path('bargle/wargle.gargle'))) assert test_unit != other assert other != test_unit
def test_default_constructor(self): test_unit \ = CInfo(CSymbolID('argle', Path('bargle/wargle.gargle'))) assert test_unit.symbol.name == 'argle' assert test_unit.symbol.found_in == Path('bargle/wargle.gargle') assert test_unit.depends_on == []
def test_prereq_constructor(self): test_unit \ = CInfo(CSymbolID('argle', Path('bargle/wargle.gargle')), ['cheese']) assert test_unit.symbol.name == 'argle' assert test_unit.symbol.found_in == Path('bargle/wargle.gargle') assert test_unit.depends_on == ['cheese']
def test_analyser_symbols(self, caplog, tmp_path): """ Tests that symbols are identified, and calls are picked up provided they come from internal headers. """ caplog.set_level(logging.DEBUG) test_file: Path = tmp_path / 'test.c' test_file.write_text( dedent(''' #pragma FAB UsrIncludeStart void foo(); #pragma FAB UsrIncludeEnd #pragma FAB UsrIncludeStart void bar(); #pragma FAB UsrIncludeEnd #pragma FAB SysIncludeStart void baz(); #pragma FAB SysIncludeEnd void foo() { bar(); baz(); } ''')) database: SqliteStateDatabase = SqliteStateDatabase(tmp_path) test_unit = CAnalyser(tmp_path) test_artifact = Artifact(test_file, CSource, Raw) output_artifacts = test_unit.run([test_artifact]) # Confirm database is updated working_state = CWorkingState(database) assert list(working_state) \ == [CInfo(CSymbolID('foo', test_file), ['bar'])] # Confirm returned Artifact is updated assert len(output_artifacts) == 1 assert output_artifacts[0].defines == ['foo'] assert output_artifacts[0].depends_on == ['bar'] assert output_artifacts[0].location == test_file assert output_artifacts[0].filetype is CSource assert output_artifacts[0].state is Analysed
def test_get_symbol(self, tmp_path: Path): database = SqliteStateDatabase(tmp_path) test_unit = CWorkingState(database) # Test on an empty list # with pytest.raises(WorkingStateException): _ = test_unit.get_symbol('tigger') # Test we can retrieve an item from a single element list test_unit.add_c_symbol(CSymbolID('tigger', Path('tigger.c'))) assert test_unit.get_symbol('tigger') \ == [CInfo(CSymbolID('tigger', Path('tigger.c')))] with pytest.raises(WorkingStateException): _ = test_unit.get_symbol('eeor') # Test retrieval from a multi-element list and with prerequisites. # test_unit.add_c_symbol(CSymbolID('eeor', Path('eeor.c'))) test_unit.add_c_dependency(CSymbolID('eeor', Path('eeor.c')), 'pooh') test_unit.add_c_dependency(CSymbolID('eeor', Path('eeor.c')), 'piglet') assert test_unit.get_symbol('tigger') \ == [CInfo(CSymbolID('tigger', Path('tigger.c')))] assert test_unit.get_symbol('eeor') \ == [CInfo(CSymbolID('eeor', Path('eeor.c')), ['piglet', 'pooh'])] with pytest.raises(WorkingStateException): _ = test_unit.get_symbol('pooh') # Test a multiply defined program unit. # test_unit.add_c_symbol(CSymbolID('tigger', Path('hundred.c'))) assert test_unit.get_symbol('tigger') \ == [CInfo(CSymbolID('tigger', Path('hundred.c'))), CInfo(CSymbolID('tigger', Path('tigger.c')))] assert test_unit.get_symbol('eeor') \ == [CInfo(CSymbolID('eeor', Path('eeor.c')), ['piglet', 'pooh'])] with pytest.raises(WorkingStateException): _ = test_unit.get_symbol('pooh')
def test_add_remove_sequence(self, tmp_path: Path): database = SqliteStateDatabase(tmp_path) test_unit = CWorkingState(database) assert list(iter(test_unit)) == [] # Add a file containing a program unit and an unsatisfied dependency. # test_unit.add_c_symbol(CSymbolID('foo', Path('foo.c'))) test_unit.add_c_dependency(CSymbolID('foo', Path('foo.c')), 'bar') assert list(iter(test_unit)) \ == [CInfo(CSymbolID('foo', Path('foo.c')), ['bar'])] assert list(test_unit.depends_on(CSymbolID('foo', Path('foo.c')))) \ == [CSymbolUnresolvedID('bar')] # Add a second file containing a second program unit. # # This satisfies the previously dangling dependency and adds a new # one. # test_unit.add_c_symbol(CSymbolID('bar', Path('bar.c'))) test_unit.add_c_dependency(CSymbolID('bar', Path('bar.c')), 'baz') assert list(iter(test_unit)) \ == [CInfo(CSymbolID('bar', Path('bar.c')), ['baz']), CInfo(CSymbolID('foo', Path('foo.c')), ['bar'])] assert list(test_unit.depends_on(CSymbolID('foo', Path('foo.c')))) \ == [CSymbolID('bar', Path('bar.c'))] assert list(test_unit.depends_on(CSymbolID('bar', Path('bar.c')))) \ == [CSymbolUnresolvedID('baz')] # Add a third file also containing a third program unit and another # copy of the first. # # The new unit depends on two other units. # test_unit.add_c_symbol(CSymbolID('baz', Path('baz.c'))) test_unit.add_c_symbol(CSymbolID('foo', Path('baz.c'))) test_unit.add_c_dependency(CSymbolID('baz', Path('baz.c')), 'qux') test_unit.add_c_dependency(CSymbolID('baz', Path('baz.c')), 'cheese') assert list(iter(test_unit)) \ == [CInfo(CSymbolID('bar', Path('bar.c')), ['baz']), CInfo(CSymbolID('baz', Path('baz.c')), ['cheese', 'qux']), CInfo(CSymbolID('foo', Path('baz.c'))), CInfo(CSymbolID('foo', Path('foo.c')), ['bar'])] assert list(test_unit.depends_on(CSymbolID('foo', Path('foo.c')))) \ == [CSymbolID('bar', Path('bar.c'))] assert list(test_unit.depends_on(CSymbolID('foo', Path('baz.c')))) \ == [] assert list(test_unit.depends_on(CSymbolID('bar', Path('bar.c')))) \ == [CSymbolID('baz', Path('baz.c'))] assert list(test_unit.depends_on(CSymbolID('baz', Path('baz.c')))) \ == [CSymbolUnresolvedID('qux'), CSymbolUnresolvedID('cheese')] # Remove a previously added file # test_unit.remove_c_file(Path('baz.c')) assert list(iter(test_unit)) \ == [CInfo(CSymbolID('bar', Path('bar.c')), ['baz']), CInfo(CSymbolID('foo', Path('foo.c')), ['bar'])] assert list(test_unit.depends_on(CSymbolID('foo', Path('foo.c')))) \ == [CSymbolID('bar', Path('bar.c'))] assert list(test_unit.depends_on(CSymbolID('bar', Path('bar.c')))) \ == [CSymbolUnresolvedID('baz')]
def test_analyser_cbinding(self, caplog, tmp_path): """ Tests that C bind procedures are correctly detected. """ caplog.set_level(logging.DEBUG) test_file: Path = tmp_path / 'test.f90' test_file.write_text( dedent(''' module foo integer, bind(c), target, save :: quuz real, bind(c, name="corge"), target, save :: varname function bar() bind(c, name="bar_c") implicit none end function bar subroutine baz(), bind(c) implicit none end subroutine baz interface function qux() bind(c, name="qux_c") implicit none end function qux subroutine quux() bind(c) implicit none end subroutine quux end interface end module foo ''')) database: SqliteStateDatabase = SqliteStateDatabase(tmp_path) test_unit = FortranAnalyser(tmp_path) test_artifact = Artifact(test_file, FortranSource, Raw) output_artifacts = test_unit.run([test_artifact]) # Confirm database is updated # Fortran part working_state = FortranWorkingState(database) assert list(working_state) \ == [FortranInfo(FortranUnitID('foo', tmp_path/'test.f90'), ['quux', 'qux_c'])] # C part cworking_state = CWorkingState(database) assert list(cworking_state) \ == [CInfo(CSymbolID('bar_c', tmp_path/'test.f90'), []), CInfo(CSymbolID('baz', tmp_path/'test.f90'), []), CInfo(CSymbolID('corge', tmp_path/'test.f90'), []), CInfo(CSymbolID('quuz', tmp_path/'test.f90'), [])] # Confirm returned Artifact is updated assert len(output_artifacts) == 1 assert output_artifacts[0].defines \ == ['foo', 'quuz', 'corge', 'bar_c', 'baz'] assert output_artifacts[0].depends_on == ['qux_c', 'quux'] assert output_artifacts[0].location == test_file assert output_artifacts[0].filetype is FortranSource assert output_artifacts[0].state is Analysed