def test_basegen_after_index(): '''Check that we can insert an object using "after_index"''' module = ModuleGen(name="testmodule") sub = SubroutineGen(module, name="testsubroutine") module.add(sub) sub.add(DeclGen(sub, datatype="integer", entity_decls=["var1"])) sub.add(DeclGen(sub, datatype="integer", entity_decls=["var2"])) sub.add(CommentGen(sub, " hello"), position=["after_index", 1]) # The code checked by line_number() *includes* the SUBROUTINE # statement (which is obviously not a child of the SubroutineGen # object) and therefore the index it returns is 1 greater than we # might expect. assert line_number(sub.root, "hello") == 3
def test_basegen_before_error(): '''Check that we raise an error when attempting to insert an object before another object that is not present in 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(DeclGen(sub, datatype="integer", entity_decls=["var2"])) # Create an object but do not add it as a child of sub dgen = DeclGen(sub, datatype="real", entity_decls=["rvar1"]) # Try to add an object before the orphan dgen with pytest.raises(RuntimeError) as err: sub.add(CommentGen(sub, " hello"), position=["before", dgen]) assert "Failed to find supplied object" in str(err)
def test_decl_no_replication_scalars(): '''Check that the same scalar variable will only get declared once in a module and a subroutine''' variable_name = "arg_name" datatype = "integer" module = ModuleGen(name="testmodule") module.add(DeclGen(module, datatype=datatype, entity_decls=[variable_name])) module.add(DeclGen(module, datatype=datatype, entity_decls=[variable_name])) subroutine = SubroutineGen(module, name="testsubroutine") module.add(subroutine) subroutine.add(DeclGen(subroutine, datatype=datatype, entity_decls=[variable_name])) subroutine.add(DeclGen(subroutine, datatype=datatype, entity_decls=[variable_name])) generated_code = str(module.root) assert generated_code.count(variable_name) == 2
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_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_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_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_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_imp_none_in_module_with_decs(): ''' test that implicit none is added before any declaration statements in a module when auto (the default) is used for insertion ''' module = ModuleGen(name="testmodule", implicitnone=False) module.add(DeclGen(module, datatype="integer", entity_decls=["var1"])) module.add(TypeDeclGen(module, datatype="my_type", entity_decls=["type1"])) module.add(ImplicitNoneGen(module)) in_idx = line_number(module.root, "IMPLICIT NONE") assert in_idx == 1
def test_subroutine_var_with_implicit_none(): ''' test that a variable is added after an implicit none statement in a subroutine''' module = ModuleGen(name="testmodule") subroutine = SubroutineGen(module, name="testsubroutine", implicitnone=True) module.add(subroutine) subroutine.add(DeclGen(subroutine, datatype="integer", entity_decls=["var1"])) idx_var = line_number(subroutine.root, "INTEGER var1") idx_imp_none = line_number(subroutine.root, "IMPLICIT NONE") print str(module.root) assert idx_var - idx_imp_none == 1, \ "variable declation must be after implicit none"
def test_imp_none_in_subroutine_with_use_and_decs(): ''' test that implicit none is added after any use statements and before any declarations in a subroutine when auto (the default) is used for insertion''' module = ModuleGen(name="testmodule") sub = SubroutineGen(module, name="testsubroutine") module.add(sub) sub.add(DeclGen(sub, datatype="integer", entity_decls=["var1"])) sub.add(TypeDeclGen(sub, datatype="my_type", entity_decls=["type1"])) sub.add(UseGen(sub, "fred")) sub.add(ImplicitNoneGen(sub)) in_idx = line_number(sub.root, "IMPLICIT NONE") assert in_idx == 2
def test_declgen_multiple_use2(): '''Check that we don't correctly handle the case where data of a different type has already been delared. ''' module = ModuleGen(name="testmodule") sub = SubroutineGen(module, name="testsubroutine") module.add(sub) # first declaration datanames = ["data1"] sub.add(DeclGen(sub, datatype="real", entity_decls=datanames)) gen = str(sub.root) # second declaration datanames = ["data1", "data2"] sub.add(DeclGen(sub, datatype="integer", entity_decls=datanames)) gen = str(sub.root) print gen expected = ( " INTEGER data1, data2\n" " REAL data1") assert expected in gen # check input data is not modified assert datanames == ["data1", "data2"]
def test_imp_none_in_module_with_use_and_decs_and_comments(): ''' test that implicit none is added after any use statements and before any declarations in a module in the presence of comments when auto (the default) is used for insertion''' module = ModuleGen(name="testmodule", implicitnone=False) module.add(DeclGen(module, datatype="integer", entity_decls=["var1"])) module.add(TypeDeclGen(module, datatype="my_type", entity_decls=["type1"])) module.add(UseGen(module, "fred")) for idx in [0, 1, 2, 3]: module.add(CommentGen(module, " hello "+str(idx)), position=["before_index", 2*idx]) module.add(ImplicitNoneGen(module)) in_idx = line_number(module.root, "IMPLICIT NONE") assert in_idx == 3
def test_subroutine_var_intent_in_with_directive(): ''' test that a variable declared as intent in is added before a directive in a subroutine''' module = ModuleGen(name="testmodule") subroutine = SubroutineGen(module, name="testsubroutine", implicitnone=False) module.add(subroutine) subroutine.add(DirectiveGen(subroutine, "omp", "begin", "parallel", "")) subroutine.add(DeclGen(subroutine, datatype="integer", intent="in", entity_decls=["var1"])) idx_par = line_number(subroutine.root, "!$omp parallel") idx_var = line_number(subroutine.root, "INTEGER, intent(in) :: var1") print str(module.root) assert idx_par - idx_var == 1, \ "variable declaration must be before directive"