def test_basegen_start_parent_loop_omp_end_dbg(capsys): '''Check the debug option to the start_parent_loop method when we have an OpenMP end directive''' module = ModuleGen(name="testmodule") sub = SubroutineGen(module, name="testsubroutine") module.add(sub) dgen = DirectiveGen(sub, "omp", "end", "do", "") sub.add(dgen) loop = DoGen(sub, "it", "1", "10") sub.add(loop) call = CallGen(loop, "testcall") loop.add(call) call.start_parent_loop(debug=True) out, _ = capsys.readouterr() print out expected = ("Parent is a do loop so moving to the parent\n" "The type of the current node is now <class " "'fparser.block_statements.Do'>\n" "The type of parent is <class " "'fparser.block_statements.Subroutine'>\n" "Finding the loops position in its parent ...\n" "The loop's index is 1\n" "The type of the object at the index is <class " "'fparser.block_statements.Do'>\n" "If preceding node is a directive then move back one\n" "preceding node is a directive so find out what type ...\n") assert expected in out
def test_imp_none_in_subroutine(): ''' test that implicit none can be added to a subroutine ''' module = ModuleGen(name="testmodule") subroutine = SubroutineGen(module, name="testsubroutine") module.add(subroutine) subroutine.add(ImplicitNoneGen(subroutine)) assert 'IMPLICIT NONE' in str(subroutine.root)
def test_subgen_implicit_none_true(): ''' test that implicit none is added to the subroutine if requested ''' module = ModuleGen(name="testmodule") sub = SubroutineGen(module, name="testsubroutine", implicitnone=True) module.add(sub) count = count_lines(sub.root, "IMPLICIT NONE") assert count == 1, "IMPLICIT NONE SHOULD EXIST"
def test_subgen_implicit_none_false(): ''' test that implicit none is not added to the subroutine if not requested ''' module = ModuleGen(name="testmodule") sub = SubroutineGen(module, name="testsubroutine", implicitnone=False) module.add(sub) count = count_lines(sub.root, "IMPLICIT NONE") assert count == 0, "IMPLICIT NONE SHOULD NOT EXIST"
def test_comment(): ''' check that a comment gets created succesfully. ''' module = ModuleGen(name="testmodule") content = "HELLO" comment = CommentGen(module, content) module.add(comment) lines = str(module.root).splitlines() assert "!" + content in lines[3]
def test_subgen_implicit_none_default(): ''' test that implicit none is not added to the subroutine by default ''' module = ModuleGen(name="testmodule") sub = SubroutineGen(module, name="testsubroutine") module.add(sub) count = count_lines(sub.root, "IMPLICIT NONE") assert count == 0, "IMPLICIT NONE SHOULD NOT EXIST BY DEFAULT"
def test_imp_none_in_module_already_exists(): ''' test that implicit none is not added to a module when one already exists''' module = ModuleGen(name="testmodule", implicitnone=True) module.add(ImplicitNoneGen(module)) count = count_lines(module.root, "IMPLICIT NONE") print str(module.root) assert count == 1, \ "There should only be one instance of IMPLICIT NONE"
def test_deallocate_arg_str(): '''check that a deallocate gets created succesfully with content being a str.''' module = ModuleGen(name="testmodule") content = "goodbye" deallocate = DeallocateGen(module, content) module.add(deallocate) lines = str(module.root).splitlines() assert "DEALLOCATE (" + content + ")" in lines[3]
def test_allocate_arg_str(): '''check that an allocate gets created succesfully with content being a string.''' module = ModuleGen(name="testmodule") content = "hello" allocate = AllocateGen(module, content) module.add(allocate) lines = str(module.root).splitlines() assert "ALLOCATE (" + content + ")" in lines[3]
def test_progunitgen_multiple_generic_use(): '''Check that we correctly handle the case where duplicate use statements are added''' module = ModuleGen(name="testmodule") sub = SubroutineGen(module, name="testsubroutine") module.add(sub) sub.add(UseGen(sub, name="fred")) sub.add(UseGen(sub, name="fred")) assert count_lines(sub.root, "USE fred") == 1
def test_if(): ''' Check that an if gets created succesfully. ''' module = ModuleGen(name="testmodule") clause = "a < b" fortran_if = IfThenGen(module, clause) module.add(fortran_if) lines = str(module.root).splitlines() assert "IF (" + clause + ") THEN" in lines[3] assert "END IF" in lines[4]
def test_progunitgen_multiple_use1(): '''Check that we correctly handle the case where duplicate use statements are added but one is specific''' module = ModuleGen(name="testmodule") sub = SubroutineGen(module, name="testsubroutine") module.add(sub) sub.add(UseGen(sub, name="fred")) sub.add(UseGen(sub, name="fred", only=True, funcnames=["astaire"])) assert count_lines(sub.root, "USE fred") == 1
def test_do_loop_with_increment(): ''' Test that we correctly generate code for a do loop with non-unit increment ''' module = ModuleGen(name="testmodule") sub = SubroutineGen(module, name="testsub") module.add(sub) dogen = DoGen(sub, "it", "1", "10", step="2") sub.add(dogen) count = count_lines(sub.root, "DO it=1,10,2") assert count == 1
def test_imp_none_exception_if_wrong_parent(): ''' test that an exception is thrown if implicit none is added and the parent is not a module or a subroutine ''' module = ModuleGen(name="testmodule") sub = SubroutineGen(module, name="testsubroutine") module.add(sub) dogen = DoGen(sub, "i", "1", "10") sub.add(dogen) with pytest.raises(Exception): dogen.add(ImplicitNoneGen(dogen))
def test_imp_none_in_subroutine_already_exists(): ''' test that implicit none is not added to a subroutine when one already exists''' module = ModuleGen(name="testmodule") sub = SubroutineGen(module, name="testsubroutine", implicitnone=True) module.add(sub) sub.add(ImplicitNoneGen(sub)) count = count_lines(sub.root, "IMPLICIT NONE") assert count == 1, \ "There should only be one instance of IMPLICIT NONE"
def test_basegen_append(): '''Check that we can append an object to the tree''' module = ModuleGen(name="testmodule") sub = SubroutineGen(module, name="testsubroutine") module.add(sub) sub.add(DeclGen(sub, datatype="integer", entity_decls=["var1"])) sub.add(CommentGen(sub, " hello"), position=["append"]) cindex = line_number(sub.root, "hello") assert cindex == 3
def test_typedeclgen_missing_names(): ''' Check that we raise an error if we attempt to create TypeDeclGen without naming the variables ''' module = ModuleGen(name="testmodule") sub = SubroutineGen(module, name="testsubroutine") module.add(sub) with pytest.raises(RuntimeError) as err: _ = TypeDeclGen(sub, datatype="my_type") assert ("Cannot create a declaration of a derived-type variable " "without specifying" in str(err))
def test_declgen_wrong_type(): ''' Check that we raise an appropriate error if we attempt to create a DeclGen for an unsupported type ''' module = ModuleGen(name="testmodule") sub = SubroutineGen(module, name="testsubroutine") module.add(sub) with pytest.raises(RuntimeError) as err: _ = DeclGen(sub, datatype="complex", entity_decls=["rvar1"]) assert "Only integer and real are currently supported" in str(err)
def test_modulegen_add_wrong_parent(): ''' Check that attempting to add an object to a ModuleGen fails if the object's parent is not that ModuleGen ''' module = ModuleGen(name="testmodule") module_wrong = ModuleGen(name="another_module") sub = SubroutineGen(module_wrong, name="testsubroutine") with pytest.raises(RuntimeError) as err: module.add(sub) print str(err) assert "because it is not a descendant of it or of any of" in str(err)
def test_declgen_missing_names(): ''' Check that we raise an error if we attempt to create a DeclGen without naming the variable(s) ''' module = ModuleGen(name="testmodule") sub = SubroutineGen(module, name="testsubroutine") module.add(sub) with pytest.raises(RuntimeError) as err: _ = DeclGen(sub, datatype="integer") assert ("Cannot create a variable declaration without specifying " "the name" in str(err))
def test_basegen_first(): '''Check that we can insert an object as the first child''' module = ModuleGen(name="testmodule") sub = SubroutineGen(module, name="testsubroutine") module.add(sub) sub.add(DeclGen(sub, datatype="integer", entity_decls=["var1"])) sub.add(CommentGen(sub, " hello"), position=["first"]) cindex = line_number(sub.root, "hello") assert cindex == 1
def test_typedeclgen_names(): ''' Check that the names method of TypeDeclGen works as expected ''' module = ModuleGen(name="testmodule") sub = SubroutineGen(module, name="testsubroutine") module.add(sub) dgen = TypeDeclGen(sub, datatype="my_type", entity_decls=["type1"]) sub.add(dgen) names = dgen.names assert len(names) == 1 assert names[0] == "type1"
def test_adduse_empty_only(): ''' Test that the adduse module method works correctly when we specify that we want it to be specific but then don't provide a list of entities for the only qualifier ''' module = ModuleGen(name="testmodule") sub = SubroutineGen(module, name="testsubroutine") module.add(sub) # Add a use statement with only=True but an empty list of entities adduse("fred", sub.root, only=True, funcnames=[]) assert count_lines(sub.root, "USE fred") == 1 assert count_lines(sub.root, "USE fred, only") == 0
def test_basegen_previous_loop_no_loop(): '''Check that we raise an error when requesting the position of the previous loop if we don't have a loop ''' module = ModuleGen(name="testmodule") sub = SubroutineGen(module, name="testsubroutine") module.add(sub) # Request the position of the last loop # even though we haven't got one with pytest.raises(RuntimeError) as err: sub.previous_loop() assert "no loop found - there is no previous loop" in str(err)
def test_if_content(): ''' Check that the content of an if gets created successfully. ''' module = ModuleGen(name="testmodule") clause = "a < b" if_statement = IfThenGen(module, clause) if_statement.add(CommentGen(if_statement, "HELLO")) module.add(if_statement) lines = str(module.root).splitlines() assert "IF (" + clause + ") THEN" in lines[3] assert "!HELLO" in lines[4] assert "END IF" in lines[5]
def test_imp_none_in_module(): ''' test that implicit none can be added to a module in the correct location''' module = ModuleGen(name="testmodule", implicitnone=False) module.add(ImplicitNoneGen(module)) in_idx = line_number(module.root, "IMPLICIT NONE") cont_idx = line_number(module.root, "CONTAINS") assert in_idx > -1, "IMPLICIT NONE not found" assert cont_idx > -1, "CONTAINS not found" assert cont_idx - in_idx == 1, "CONTAINS is not on the line after" +\ " IMPLICIT NONE"
def test_basegen_last_declaration_no_vars(): '''Check that we raise an error when requesting the position of the last variable declaration if we don't have any variables''' module = ModuleGen(name="testmodule") sub = SubroutineGen(module, name="testsubroutine") module.add(sub) # Request the position of the last variable declaration # even though we haven't got any with pytest.raises(RuntimeError) as err: sub.last_declaration() assert "no variable declarations found" in str(err)
def test_progunitgen_multiple_use2(): '''Check that we correctly handle the case where the same module appears in two use statements but, because the first use is specific, the second, generic use is included. ''' module = ModuleGen(name="testmodule") sub = SubroutineGen(module, name="testsubroutine") module.add(sub) sub.add(UseGen(sub, name="fred", only=True, funcnames=["astaire"])) sub.add(UseGen(sub, name="fred")) assert count_lines(sub.root, "USE fred") == 2
def test_basegen_append_default(): ''' Check if no position argument is supplied to BaseGen.add() then it defaults to appending ''' from fgenerator.gen import BaseGen module = ModuleGen(name="testmodule") sub = SubroutineGen(module, name="testsubroutine") module.add(sub) BaseGen.add(sub, DeclGen(sub, datatype="integer", entity_decls=["var1"])) BaseGen.add(sub, CommentGen(sub, " hello")) cindex = line_number(sub.root, "hello") assert cindex == 3
def test_adduse_default_funcnames(): ''' Test that the adduse module method works correctly when we do not specify a list of funcnames ''' module = ModuleGen(name="testmodule") sub = SubroutineGen(module, name="testsubroutine") module.add(sub) call = CallGen(sub, name="testcall", args=["a", "b"]) sub.add(call) adduse("fred", call.root) gen = str(sub.root) expected = (" SUBROUTINE testsubroutine()\n" " USE fred\n") assert expected in gen