Drake
rules_test_utilities.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <algorithm>
4 #include <string>
5 #include <vector>
6 
7 #include <gtest/gtest.h>
8 
10 #include "drake/common/unused.h"
11 
12 namespace drake {
13 namespace maliput {
14 namespace api {
15 namespace rules {
16 namespace test {
17 
18 // TODO(maddog@tri.global) Make the general-purpose assertion collection
19 // machinery available (and used) by maliput in general,
20 // or even drake.
21 
22 /// AssertionResultCollector helps with the creation of concise and well-traced
23 /// testing subroutines when using googletest.
24 ///
25 /// Instead of invocations of `EXPECT_*()` or `ASSERT_*()` within a test
26 /// subroutine, predicate-assertion functions are invoked and the resulting
27 /// ::testing::AssertionResult instances should be collected by an instance
28 /// of AssertionResultCollector. At the end of the subroutine, an
29 /// AssertionResult, representing the `and` of all the collected results,
30 /// can be extracted from the collector.
32  public:
33  /// Constructs an empty AssertionResultCollector.
34  AssertionResultCollector() = default;
35 
36  /// Adds an AssertionResult to the collector. Typically this is not called
37  /// directly, but is invoked via the `ADD_RESULT()` macro.
38  ///
39  /// `result` is the AssertionResult to be collected. `expression` is a
40  /// printable representation of the expression which yielded the result.
41  /// `filename` and `line`, as would be produced by __FILE__ and __LINE__
42  /// preprocessor macros, identify the location of the expression which
43  /// yielded `result`.
44  void AddResult(const char* filename, int line, const char* expression,
45  ::testing::AssertionResult result) {
46  ++count_;
47  if (!result) {
48  ++failed_;
49  failure_message_ = failure_message_ +
50  filename + ":" + std::to_string(line) +
51  ": Failure #" + std::to_string(failed_) + ":\n" +
52  "Expression '" + expression + "' failed:\n" +
53  result.message() + "\n";
54  }
55  }
56 
57  /// Returns an AssertionResult reflecting the current state of the
58  /// collector, which is basically an `and` of the collected results.
59  ::testing::AssertionResult result() {
60  if (failed_) {
61  return ::testing::AssertionFailure()
62  << failed_ << " of " << count_ << " expressions failed:\n"
63  << failure_message_;
64  } else {
65  return ::testing::AssertionSuccess()
66  << count_ << " expressions all succeeded.";
67  }
68  }
69 
70  /// Returns the number of results collected.
71  int count() const { return count_; }
72 
73  /// Returns the number of failure results collected.
74  int failed() const { return failed_; }
75 
76  private:
77  int count_{0};
78  int failed_{0};
79  std::string failure_message_;
80 };
81 
82 
83 /// Adds AssertionResult `result` to AssertionResultCollector `collector`.
84 /// The location of the invocation and the literal expression of `result`
85 /// will be recorded by the collector.
86 #define MALIPUT_ADD_RESULT(collector, result) \
87  collector.AddResult(__FILE__, __LINE__, #result, result)
88 
89 /// Returns an AssertionResult which is successful if `e1` equals `e2`
90 /// according to the `IsEqual()` predicate-formatter function. The
91 /// literal expressions for `e1` and `e2` will be provided to `IsEqual()`.
92 #define MALIPUT_IS_EQUAL(e1, e2) \
93  ::drake::maliput::api::rules::test::IsEqual(#e1, #e2, e1, e2)
94 
95 
96 // TODO(maddog@tri.global) Create macros (like below) as an alternative
97 // to EXPECT_PRED_FORMAT*()/etc, which simply returns
98 // the AssertionResult instead of expecting/asserting.
99 // #define EVAL_PRED_FORMAT(pred_format, v1, v2) pred_format(#v1, #v2, v1, v2)
100 
101 // TODO(maddog@tri.global) All the CmpHelperEQ based IsEqual() methods below
102 // should be folded into a single template that knows
103 // what to do for types with operator==.
104 
105 /// Predicate-formatter which tests equality of double.
106 inline ::testing::AssertionResult IsEqual(const char* a_expression,
107  const char* b_expression,
108  const double& a, const double& b) {
109  return ::testing::internal::CmpHelperEQ(a_expression, b_expression, a, b);
110 }
111 
112 
113 /// Predicate-formatter which tests equality of TypeSpecificIdentifier<T>.
114 template <class T>
115 inline ::testing::AssertionResult IsEqual(
116  const char* a_expression, const char* b_expression,
117  const TypeSpecificIdentifier<T>& a,
118  const TypeSpecificIdentifier<T>& b) {
119  return ::testing::internal::CmpHelperEQ(a_expression, b_expression, a, b);
120 }
121 
122 
123 /// Predicate-formatter which tests equality of SRange.
124 inline ::testing::AssertionResult IsEqual(
125  const char* a_expression, const char* b_expression,
126  const SRange& a, const SRange& b) {
127  unused(a_expression, b_expression);
131  return c.result();
132 }
133 
134 
135 /// Predicate-formatter which tests equality of LaneSRange.
136 inline ::testing::AssertionResult IsEqual(
137  const char* a_expression, const char* b_expression,
138  const LaneSRange& a, const LaneSRange& b) {
139  unused(a_expression, b_expression);
143  return c.result();
144 }
145 
146 
147 /// Predicate-formatter which tests equality of std::vector<LaneSRange>.
148 inline ::testing::AssertionResult IsEqual(
149  const char* a_expression, const char* b_expression,
150  const std::vector<LaneSRange>& a, const std::vector<LaneSRange>& b) {
151  unused(a_expression, b_expression);
153  MALIPUT_ADD_RESULT(c, MALIPUT_IS_EQUAL(a.size(), b.size()));
154  int smallest = std::min(a.size(), b.size());
155  for (int i = 0; i < smallest; ++i) {
156  MALIPUT_ADD_RESULT(c, MALIPUT_IS_EQUAL(a[i], b[i]));
157  }
158  return c.result();
159 }
160 
161 
162 /// Predicate-formatter which tests equality of LaneSRoute.
163 inline ::testing::AssertionResult IsEqual(
164  const char* a_expression, const char* b_expression,
165  const LaneSRoute& a, const LaneSRoute& b) {
166  unused(a_expression, b_expression);
169  return c.result();
170 }
171 
172 
173 } // namespace test
174 } // namespace rules
175 } // namespace api
176 } // namespace maliput
177 } // namespace drake
::testing::AssertionResult IsEqual(const char *a_expression, const char *b_expression, const T *a, const T *b)
Definition: check_id_indexing.cc:12
int i
Definition: reset_after_move_test.cc:51
const std::vector< LaneSRange > & ranges() const
Returns the sequence of LaneSRanges.
Definition: regions.h:84
const char const char int line
Definition: drake_throw.h:16
Definition: automotive_demo.cc:90
::testing::AssertionResult result()
Returns an AssertionResult reflecting the current state of the collector, which is basically an and o...
Definition: rules_test_utilities.h:59
#define MALIPUT_IS_EQUAL(e1, e2)
Returns an AssertionResult which is successful if e1 equals e2 according to the IsEqual() predicate-f...
Definition: rules_test_utilities.h:92
std::string to_string(const drake::geometry::Identifier< Tag > &id)
Enables use of identifiers with to_string.
Definition: identifier.h:211
TypeSpecificIdentifier<T> represents an identifier specifically identifying an entity of type T...
Definition: type_specific_identifier.h:39
int failed() const
Returns the number of failure results collected.
Definition: rules_test_utilities.h:74
Directed, inclusive longitudinal (s value) range from s0 to s1.
Definition: regions.h:16
int count() const
Returns the number of results collected.
Definition: rules_test_utilities.h:71
Expression min(const Expression &e1, const Expression &e2)
Definition: symbolic_expression.cc:699
AssertionResultCollector()=default
Constructs an empty AssertionResultCollector.
double s0() const
Gets s0 value.
Definition: regions.h:27
A longitudinal route, possibly spanning multiple (end-to-end) lanes.
Definition: regions.h:72
const LaneId & lane_id() const
Gets the LaneId.
Definition: regions.h:54
double s1() const
Gets s1 value.
Definition: regions.h:30
Directed longitudinal range of a specific Lane, identified by a LaneId.
Definition: regions.h:45
SRange s_range() const
Gets the SRange.
Definition: regions.h:57
#define MALIPUT_ADD_RESULT(collector, result)
Adds AssertionResult result to AssertionResultCollector collector.
Definition: rules_test_utilities.h:86
AssertionResultCollector helps with the creation of concise and well-traced testing subroutines when ...
Definition: rules_test_utilities.h:31
void AddResult(const char *filename, int line, const char *expression,::testing::AssertionResult result)
Adds an AssertionResult to the collector.
Definition: rules_test_utilities.h:44
void unused(const Args &...)
Documents the argument(s) as unused, placating GCC&#39;s -Wunused-parameter warning.
Definition: unused.h:51