Skip to content

Add some unit test helper functions, useful for Java generics unit tests #1550

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions unit/testing-utils/require_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,21 @@ code_typet require_type::require_code(const typet &type)
return to_code_type(type);
}

/// Verify a given type is an code_typet, and that the code it represents
/// accepts a given number of parameters
/// \param type The type to check
/// \param num_params check the the given code_typet expects this
/// number of parameters
/// \return The type cast to a code_typet
code_typet require_type::require_code(
const typet &type,
const size_t num_params)
{
code_typet code_type=require_code(type);
REQUIRE(code_type.parameters().size()==num_params);
return code_type;
}

/// Verify that a function has a parameter of a specific name.
/// \param function_type: The type of the function
/// \param param_name: The name of the parameter
Expand All @@ -78,3 +93,105 @@ code_typet::parametert require_type::require_parameter(
REQUIRE(param != function_type.parameters().end());
return *param;
}

/// Verify a given type is a java_generic_type, optionally checking
/// that it's associated type variables match a given set of identifiers
/// \param type The type to check
/// \param type_variables An optional set of type variable identifiers which
/// should be expected as the type parameters of the generic type.
/// \return The given type, cast to a java_generic_typet
const java_generic_typet &require_type::require_java_generic_type_variables(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make it a bit more clear what this does, could you please rename it to require_java_generic_type_with_variables?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh and as a reminder - removing const & form the return type (if you're returning a local variable) might fix the CI issues.

const typet &type,
const optionalt<std::initializer_list<irep_idt>> &type_variables)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we will have generic types with both instantiated and uninstantiated parameters, this may not need to be a complete list of parameters.

{
REQUIRE(is_java_generic_type(type));
const java_generic_typet &generic_type=to_java_generic_type(type);
if(type_variables)
{
const java_generic_typet::generic_type_variablest &generic_type_vars=
generic_type.generic_type_variables();
REQUIRE(generic_type_vars.size()==type_variables.value().size());
REQUIRE(
std::equal(
type_variables->begin(),
type_variables->end(),
generic_type_vars.begin(),
[](const irep_idt &type_var_name, const java_generic_parametert &param)
{
REQUIRE(!is_java_generic_inst_parameter((param)));
return param.type_variable().get_identifier()==type_var_name;
}));
}

return generic_type;
}

/// Verify a given type is a java_generic_type, optionally checking
/// that it's associated type variables match a given set of identifiers
/// \param type The type to check
/// \param type_variables An optional set of type variable identifiers which
/// should be expected as the type parameters of the generic type.
/// \return The given type, cast to a java_generic_typet
const java_generic_typet
&require_type::require_java_generic_type_instantiations(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly to above, could you please rename it to require_java_generic_type_with_instantiations`?

const typet &type,
const optionalt<std::initializer_list<irep_idt>> &type_instantiations)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, may not be a complete list.

{
REQUIRE(is_java_generic_type(type));
const java_generic_typet &generic_type=to_java_generic_type(type);
if(type_instantiations)
{
const java_generic_typet::generic_type_variablest &generic_type_vars=
generic_type.generic_type_variables();
REQUIRE(generic_type_vars.size()==type_instantiations.value().size());
REQUIRE(
std::equal(
type_instantiations->begin(),
type_instantiations->end(),
generic_type_vars.begin(),
[](const irep_idt &type_id, const java_generic_parametert &param)
{
REQUIRE(is_java_generic_inst_parameter((param)));
return param.subtype()==symbol_typet(type_id);
}));
}


return generic_type;
}

/// Verify a given type is a java_generic_parameter, optionally checking
/// that it's associated type variables match a given set of identifiers
/// \param type The type to check
/// \param type_variables An optional set of type variable identifiers which
/// should be expected as the type parameters of the generic type.
/// \return The given type, cast to a java_generic_typet
const java_generic_parametert
&require_type::require_java_generic_parameter_variables(
Copy link

@majakusber majakusber Nov 1, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great to have a similar function for instantiated parameters, something like require_java_generic_parameter_instantiated (and this one then require_java_generic_parameter_variable, singular). Then these two functions can be called within the two functions above, for checking generic type and the parameters.

const typet &type,
const optionalt<irep_idt> &type_variable)
{
REQUIRE(is_java_generic_parameter(type));
const java_generic_parametert &generic_param=to_java_generic_parameter(type);
if(type_variable)
{
const java_generic_parametert::type_variablet &generic_type_var=
generic_param.type_variable();
REQUIRE(!is_java_generic_inst_parameter((generic_param)));
REQUIRE(generic_type_var.get_identifier()==type_variable.value());
}

return generic_param;
}

const typet &require_type::require_java_non_generic_type(
const typet &type,
const optionalt<irep_idt> &expect_type)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This parameter seems a bit strange - I'd prefer if it took a symbol_typet or maybe just leave checking the actual type to a separate helper function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that is I think a hangover from an earlier usage of this helper. Fixed now, including adding the missing doxygen.

{
REQUIRE(!is_java_generic_parameter(type));
REQUIRE(!is_java_generic_type(type));
REQUIRE(!is_java_generic_inst_parameter(type));
if(expect_type)
REQUIRE(type.subtype()==symbol_typet(expect_type.value()));
return type;
}
25 changes: 24 additions & 1 deletion unit/testing-utils/require_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

#include <util/optional.h>
#include <util/std_types.h>
#include <java_bytecode/java_types.h>


// NOLINTNEXTLINE(readability/namespace)
namespace require_type
Expand All @@ -29,8 +31,29 @@ struct_typet::componentt require_component(
const irep_idt &component_name);

code_typet require_code(const typet &type);

code_typet::parametert
require_parameter(const code_typet &function_type, const irep_idt &param_name);

code_typet require_code(
const typet &type,
const size_t num_params);

const java_generic_typet &require_java_generic_type_variables(
const typet &type,
const optionalt<std::initializer_list<irep_idt>> &type_variables);

const java_generic_typet &require_java_generic_type_instantiations(
const typet &type,
const optionalt<std::initializer_list<irep_idt>> &type_instantiations);

const java_generic_parametert &require_java_generic_parameter_variables(
const typet &type,
const optionalt<irep_idt> &type_variables);

const typet &require_java_non_generic_type(
const typet &type,
const optionalt<irep_idt> &expect_type);
}

#endif
#endif // CPROVER_TESTING_UTILS_REQUIRE_TYPE_H