Skip to content

Commit ebdcfb1

Browse files
thk123Matthias Güdemann
authored andcommitted
Adding utiltiy functions required for unit tests
1 parent f79e895 commit ebdcfb1

File tree

2 files changed

+177
-0
lines changed

2 files changed

+177
-0
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/*******************************************************************\
2+
3+
Module: Unit test utilities
4+
5+
Author: DiffBlue Limited. All rights reserved.
6+
7+
\*******************************************************************/
8+
9+
#include "require_parse_tree.h"
10+
11+
/// Find in the parsed class a specific entry within the
12+
/// lambda_method_handle_map with a matching descriptor. Will fail if no
13+
/// matching lambda entry found.
14+
/// \param parsed_class: the class to inspect
15+
/// \param descriptor: the descriptor the lambda method should have
16+
/// \param entry_index: the number to skip (i.e. if multiple entries with the
17+
/// same descriptor
18+
/// \return
19+
require_parse_tree::lambda_method_handlet
20+
require_parse_tree::require_lambda_entry_for_descriptor(
21+
const java_bytecode_parse_treet::classt &parsed_class,
22+
const std::string &descriptor,
23+
const size_t entry_index)
24+
{
25+
REQUIRE(entry_index < parsed_class.lambda_method_handle_map.size());
26+
typedef java_bytecode_parse_treet::classt::lambda_method_handle_mapt::
27+
value_type lambda_method_entryt;
28+
29+
size_t matches_found = 0;
30+
31+
const auto matching_lambda_entry = std::find_if(
32+
parsed_class.lambda_method_handle_map.begin(),
33+
parsed_class.lambda_method_handle_map.end(),
34+
[&descriptor, &matches_found, &entry_index](
35+
const lambda_method_entryt &entry) {
36+
if(entry.second.method_type == descriptor)
37+
{
38+
++matches_found;
39+
return matches_found == entry_index + 1;
40+
}
41+
return false;
42+
});
43+
44+
INFO("Looking for descriptor: " << descriptor);
45+
std::ostringstream found_entries;
46+
for(const auto entry : parsed_class.lambda_method_handle_map)
47+
{
48+
found_entries << id2string(entry.first.first) << ": "
49+
<< id2string(entry.second.method_type) << std::endl;
50+
}
51+
INFO("Found descriptors:\n" << found_entries.str());
52+
53+
REQUIRE(matching_lambda_entry != parsed_class.lambda_method_handle_map.end());
54+
55+
return matching_lambda_entry->second;
56+
}
57+
58+
/// Finds a specific method in the parsed class with a matching name.
59+
/// \param parsed_class: The class
60+
/// \param method_name: The name of the method to look for
61+
/// \return The methodt structure with the corresponding name
62+
const require_parse_tree::methodt require_parse_tree::require_method(
63+
const java_bytecode_parse_treet::classt &parsed_class,
64+
const irep_idt &method_name)
65+
{
66+
const auto method = std::find_if(
67+
parsed_class.methods.begin(),
68+
parsed_class.methods.end(),
69+
[&method_name](const java_bytecode_parse_treet::methodt &method) {
70+
return method.name == method_name;
71+
});
72+
73+
INFO("Looking for method: " << method_name);
74+
std::ostringstream found_methods;
75+
for(const auto entry : parsed_class.methods)
76+
{
77+
found_methods << id2string(entry.name) << std::endl;
78+
}
79+
INFO("Found methods:\n" << found_methods.str());
80+
81+
REQUIRE(method != parsed_class.methods.end());
82+
83+
return *method;
84+
}
85+
86+
/// Verify whether a given methods instructions match an expectation
87+
/// \param expected_instructions: The expected instructions for a given method
88+
/// \param instructions: The instructions of a method
89+
void require_parse_tree::require_instructions_match_expectation(
90+
const expected_instructionst &expected_instructions,
91+
const java_bytecode_parse_treet::methodt::instructionst instructions)
92+
{
93+
REQUIRE(instructions.size() == expected_instructions.size());
94+
auto actual_instruction_it = instructions.begin();
95+
for(const auto expected_instruction : expected_instructions)
96+
{
97+
expected_instruction.require_instructions_equal(*actual_instruction_it);
98+
++actual_instruction_it;
99+
}
100+
}
101+
102+
/// Check whether a given instruction matches an expectation of the instruction
103+
/// \param actual_instruction: The instruction to check
104+
void require_parse_tree::expected_instructiont::require_instructions_equal(
105+
java_bytecode_parse_treet::instructiont actual_instruction) const
106+
{
107+
REQUIRE(actual_instruction.statement == instruction_mnemoic);
108+
REQUIRE(actual_instruction.args.size() == instruction_arguments.size());
109+
auto actual_arg_it = actual_instruction.args.begin();
110+
for(const exprt &expected_arg : actual_instruction.args)
111+
{
112+
INFO("Expected argument" << expected_arg.pretty());
113+
INFO("Actual argument" << actual_arg_it->pretty());
114+
REQUIRE(*actual_arg_it == expected_arg);
115+
++actual_arg_it;
116+
}
117+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*******************************************************************\
2+
3+
Module: Unit test utilities
4+
5+
Author: DiffBlue Limited. All rights reserved.
6+
7+
\*******************************************************************/
8+
9+
/// \file
10+
/// Utilties for inspecting java_parse_treet
11+
12+
#ifndef CPROVER_TESTING_UTILS_REQUIRE_PARSE_TREE_H
13+
#define CPROVER_TESTING_UTILS_REQUIRE_PARSE_TREE_H
14+
15+
#include <java_bytecode/java_bytecode_parse_tree.h>
16+
#include "catch.hpp"
17+
18+
// NOLINTNEXTLINE(readability/namespace)
19+
namespace require_parse_tree
20+
{
21+
typedef java_bytecode_parse_treet::classt::lambda_method_handlet
22+
lambda_method_handlet;
23+
24+
lambda_method_handlet require_lambda_entry_for_descriptor(
25+
const java_bytecode_parse_treet::classt &parsed_class,
26+
const std::string &descriptor,
27+
const size_t entry_index = 0);
28+
29+
typedef java_bytecode_parse_treet::methodt methodt;
30+
31+
const methodt require_method(
32+
const java_bytecode_parse_treet::classt &parsed_class,
33+
const irep_idt &method_name);
34+
35+
struct expected_instructiont
36+
{
37+
expected_instructiont(
38+
const irep_idt &instruction_mnemoic,
39+
const std::vector<exprt> &instruction_arguments)
40+
: instruction_mnemoic(instruction_mnemoic),
41+
instruction_arguments(instruction_arguments)
42+
{
43+
}
44+
45+
void require_instructions_equal(
46+
java_bytecode_parse_treet::instructiont actual_instruction) const;
47+
48+
private:
49+
const irep_idt instruction_mnemoic;
50+
const std::vector<exprt> instruction_arguments;
51+
};
52+
53+
typedef std::vector<expected_instructiont> expected_instructionst;
54+
55+
void require_instructions_match_expectation(
56+
const expected_instructionst &expected_instructions,
57+
const java_bytecode_parse_treet::methodt::instructionst instructions);
58+
}
59+
60+
#endif //CPROVER_TESTING_UTILS_REQUIRE_PARSE_TREE_H

0 commit comments

Comments
 (0)