Skip to content

Commit

Permalink
Promote DRAKE_EXPECT_THROWS_MESSAGE from geometry to common, remove b…
Browse files Browse the repository at this point in the history
…espoke definitions, fix invocation sites.

Re-engineered the macros to avoid duplication, and improve behavior & documentation.
  • Loading branch information
sherm1 committed Mar 19, 2018
1 parent c55d4fd commit 5441a5d
Show file tree
Hide file tree
Showing 20 changed files with 345 additions and 371 deletions.
1 change: 1 addition & 0 deletions common/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,7 @@ drake_cc_googletest(
deps = [
":type_safe_index",
":unused",
"//common/test_utilities:expect_throws_message",
],
)

Expand Down
12 changes: 0 additions & 12 deletions common/test/copyable_unique_ptr_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,6 @@ using std::unique_ptr;
template <typename T>
using cup = copyable_unique_ptr<T>;

// Helper macro for "expecting" an exception but *also* testing the error
// message against the provided regular expression.
#define EXPECT_ERROR_MESSAGE(expression, exception, reg_exp) \
try { \
expression; \
GTEST_FAIL(); \
} catch (const exception& err) { \
auto matcher = [](const char* s, const char* re) { \
return regex_match(s, regex(re)); }; \
EXPECT_PRED2(matcher, err.what(), reg_exp); \
}

// -------------------- copy functionality tests ------------------------
// These tests cover the actual copyable semantics. Confirming that the
// protocol selecting between Clone and copy constructor is consistent with the
Expand Down
185 changes: 89 additions & 96 deletions common/test/type_safe_index_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include <gtest/gtest.h>

#include "drake/common/test_utilities/expect_throws_message.h"
#include "drake/common/unused.h"

namespace drake {
Expand All @@ -22,31 +23,6 @@ using std::regex;
using std::regex_match;
using std::move;

#ifdef DRAKE_ASSERT_IS_DISARMED
// With assertion disarmed, expect no exception.
#define EXPECT_ERROR_MESSAGE_IF_ARMED(expression, reg_exp) \
do {\
EXPECT_NO_THROW(expression); \
} while (0)

#else
// Helper macro for "expecting" an exception but *also* testing the error
// message against the provided regular expression.

#define EXPECT_ERROR_MESSAGE_IF_ARMED(expression, reg_exp) \
do {\
try { \
expression; \
GTEST_NONFATAL_FAILURE_("\t" #expression \
" failed to throw std::runtime_error."); \
} catch (const std::runtime_error& err) { \
auto matcher = [](const char* s, const char* re) { \
return regex_match(s, regex(re)); }; \
EXPECT_PRED2(matcher, err.what(), reg_exp); \
} \
} while (0)
#endif

// Create dummy index types to exercise the functionality
using AIndex = TypeSafeIndex<class A>;
using BIndex = TypeSafeIndex<class B>;
Expand All @@ -63,10 +39,11 @@ GTEST_TEST(TypeSafeIndex, Constructor) {
EXPECT_FALSE(index2.is_valid());

// Construction with invalid index.
AIndex invalid; // Default constructor.
AIndex invalid; // Default constructor.
EXPECT_FALSE(invalid.is_valid());
EXPECT_ERROR_MESSAGE_IF_ARMED(AIndex(-1),
"Explicitly constructing an invalid index.+");
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(
AIndex(-1), std::runtime_error,
"Explicitly constructing an invalid index.+");
EXPECT_NO_THROW(unused(AIndex(invalid))); // Copy construct invalid index.
}

Expand All @@ -92,8 +69,8 @@ GTEST_TEST(TypeSafeIndex, IndexAssignment) {
AIndex index4;
index4 = 17;
EXPECT_EQ(index4, 17);
EXPECT_ERROR_MESSAGE_IF_ARMED(index4 = -3,
"Assigning an invalid int.+");
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(index4 = -3, std::runtime_error,
"Assigning an invalid int.+");

// Assignment involving invalid indices.

Expand Down Expand Up @@ -141,8 +118,9 @@ GTEST_TEST(TypeSafeIndex, ConversionToInt) {
EXPECT_EQ(four, index);

AIndex invalid;
EXPECT_ERROR_MESSAGE_IF_ARMED(unused(static_cast<int>(invalid)),
"Converting to an int.+");
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(unused(static_cast<int>(invalid)),
std::runtime_error,
"Converting to an int.+");
}

// Tests valid comparisons of like-typed index instances.
Expand Down Expand Up @@ -173,30 +151,42 @@ GTEST_TEST(TypeSafeIndex, InvalidIndexComparisonOperators) {
AIndex invalid;

// Comparison operators.
EXPECT_ERROR_MESSAGE_IF_ARMED(unused(invalid == valid),
"Testing == with invalid LHS.+");
EXPECT_ERROR_MESSAGE_IF_ARMED(unused(valid == invalid),
"Testing == with invalid RHS.+");
EXPECT_ERROR_MESSAGE_IF_ARMED(unused(invalid != valid),
"Testing != with invalid LHS.+");
EXPECT_ERROR_MESSAGE_IF_ARMED(unused(valid != invalid),
"Testing != with invalid RHS.+");
EXPECT_ERROR_MESSAGE_IF_ARMED(unused(invalid < valid),
"Testing < with invalid LHS.+");
EXPECT_ERROR_MESSAGE_IF_ARMED(unused(valid < invalid),
"Testing < with invalid RHS.+");
EXPECT_ERROR_MESSAGE_IF_ARMED(unused(invalid <= valid),
"Testing <= with invalid LHS.+");
EXPECT_ERROR_MESSAGE_IF_ARMED(unused(valid <= invalid),
"Testing <= with invalid RHS.+");
EXPECT_ERROR_MESSAGE_IF_ARMED(unused(invalid > valid),
"Testing > with invalid LHS.+");
EXPECT_ERROR_MESSAGE_IF_ARMED(unused(valid > invalid),
"Testing > with invalid RHS.+");
EXPECT_ERROR_MESSAGE_IF_ARMED(unused(invalid >= valid),
"Testing >= with invalid LHS.+");
EXPECT_ERROR_MESSAGE_IF_ARMED(unused(valid >= invalid),
"Testing >= with invalid RHS.+");
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(unused(invalid == valid),
std::runtime_error,
"Testing == with invalid LHS.+");
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(unused(valid == invalid),
std::runtime_error,
"Testing == with invalid RHS.+");
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(unused(invalid != valid),
std::runtime_error,
"Testing != with invalid LHS.+");
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(unused(valid != invalid),
std::runtime_error,
"Testing != with invalid RHS.+");
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(unused(invalid < valid),
std::runtime_error,
"Testing < with invalid LHS.+");
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(unused(valid < invalid),
std::runtime_error,
"Testing < with invalid RHS.+");
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(unused(invalid <= valid),
std::runtime_error,
"Testing <= with invalid LHS.+");
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(unused(valid <= invalid),
std::runtime_error,
"Testing <= with invalid RHS.+");
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(unused(invalid > valid),
std::runtime_error,
"Testing > with invalid LHS.+");
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(unused(valid > invalid),
std::runtime_error,
"Testing > with invalid RHS.+");
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(unused(invalid >= valid),
std::runtime_error,
"Testing >= with invalid LHS.+");
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(unused(valid >= invalid),
std::runtime_error,
"Testing >= with invalid RHS.+");
}

// Tests the prefix increment behavior.
Expand All @@ -210,12 +200,13 @@ GTEST_TEST(TypeSafeIndex, PrefixIncrement) {
// In Debug builds, some increment operations will throw.
// Overflow produces an invalid index.
AIndex max_index(std::numeric_limits<int>::max());
EXPECT_ERROR_MESSAGE_IF_ARMED(++max_index,
"Pre-incrementing produced an invalid index.+");
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(
++max_index, std::runtime_error,
"Pre-incrementing produced an invalid index.+");
// Increment invalid index.
AIndex invalid;
EXPECT_ERROR_MESSAGE_IF_ARMED(++invalid,
"Pre-incrementing an invalid index.+");
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(++invalid, std::runtime_error,
"Pre-incrementing an invalid index.+");
}

// Tests the postfix increment behavior.
Expand All @@ -229,12 +220,13 @@ GTEST_TEST(TypeSafeIndex, PostfixIncrement) {
// In Debug builds, some increment operations will throw.
// Overflow produces an invalid index.
AIndex max_index(std::numeric_limits<int>::max());
EXPECT_ERROR_MESSAGE_IF_ARMED(
max_index++, "Post-incrementing produced an invalid index.+");
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(
max_index++, std::runtime_error,
"Post-incrementing produced an invalid index.+");
// Increment invalid index.
AIndex invalid;
EXPECT_ERROR_MESSAGE_IF_ARMED(
invalid++, "Post-incrementing an invalid index.+");
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(invalid++, std::runtime_error,
"Post-incrementing an invalid index.+");
}

// Tests the prefix decrement behavior.
Expand All @@ -246,10 +238,11 @@ GTEST_TEST(TypeSafeIndex, PrefixDecrement) {
EXPECT_EQ(index_minus, AIndex(7));
// In Debug builds decrements leading to a negative result will throw.
AIndex about_to_be_negative_index(0);
EXPECT_ERROR_MESSAGE_IF_ARMED(--about_to_be_negative_index,
"Pre-decrementing produced an invalid index.+");
EXPECT_ERROR_MESSAGE_IF_ARMED(
--AIndex(), "Pre-decrementing an invalid index.+");
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(
--about_to_be_negative_index, std::runtime_error,
"Pre-decrementing produced an invalid index.+");
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(--AIndex(), std::runtime_error,
"Pre-decrementing an invalid index.+");
}

// Tests the postfix decrement behavior.
Expand All @@ -261,11 +254,11 @@ GTEST_TEST(TypeSafeIndex, PostfixDecrement) {
EXPECT_EQ(index_minus, AIndex(8));
// In Debug builds decrements leading to a negative result will throw.
AIndex about_to_be_negative_index(0);
EXPECT_ERROR_MESSAGE_IF_ARMED(
about_to_be_negative_index--,
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(
about_to_be_negative_index--, std::runtime_error,
"Post-decrementing produced an invalid index.+");
EXPECT_ERROR_MESSAGE_IF_ARMED(AIndex()--,
"Post-decrementing an invalid index.+");
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(AIndex()--, std::runtime_error,
"Post-decrementing an invalid index.+");
}

// Tests integer addition and subtraction.
Expand Down Expand Up @@ -293,24 +286,24 @@ GTEST_TEST(TypeSafeIndex, InPlaceAddition) {

// In-place with an int.
AIndex about_to_be_negative_index(7);
EXPECT_ERROR_MESSAGE_IF_ARMED(
about_to_be_negative_index += (-9),
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(
about_to_be_negative_index += (-9), std::runtime_error,
"In-place addition with an int produced an invalid index.+");
AIndex invalid;
EXPECT_ERROR_MESSAGE_IF_ARMED(
invalid += 1,
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(
invalid += 1, std::runtime_error,
"In-place addition with an int on an invalid index.+");

// In-place with an index.
AIndex max_index(std::numeric_limits<int>::max());
EXPECT_ERROR_MESSAGE_IF_ARMED(
max_index += AIndex(1),
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(
max_index += AIndex(1), std::runtime_error,
"In-place addition with another index produced an invalid index.+");
EXPECT_ERROR_MESSAGE_IF_ARMED(
invalid += AIndex(1),
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(
invalid += AIndex(1), std::runtime_error,
"In-place addition with another index invalid LHS.+");
EXPECT_ERROR_MESSAGE_IF_ARMED(
index += invalid,
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(
index += invalid, std::runtime_error,
"In-place addition with another index invalid RHS.+");
}

Expand All @@ -326,25 +319,25 @@ GTEST_TEST(TypeSafeIndex, InPlaceSubtract) {

// In-place with an int.
AIndex about_to_be_negative_index(0);
EXPECT_ERROR_MESSAGE_IF_ARMED(
about_to_be_negative_index -= 7,
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(
about_to_be_negative_index -= 7, std::runtime_error,
"In-place subtraction with an int produced an invalid index.+");
AIndex invalid;
EXPECT_ERROR_MESSAGE_IF_ARMED(
invalid -= -3,
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(
invalid -= -3, std::runtime_error,
"In-place subtraction with an int on an invalid index.+");

// In-place with an index.
about_to_be_negative_index = 0;
EXPECT_ERROR_MESSAGE_IF_ARMED(
about_to_be_negative_index -= AIndex(1),
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(
about_to_be_negative_index -= AIndex(1), std::runtime_error,
"In-place subtraction with another index produced an invalid index.+");
EXPECT_ERROR_MESSAGE_IF_ARMED(
invalid -= AIndex(1),
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(
invalid -= AIndex(1), std::runtime_error,
"In-place subtraction with another index invalid LHS.+");
about_to_be_negative_index = 0;
EXPECT_ERROR_MESSAGE_IF_ARMED(
about_to_be_negative_index -= invalid,
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(
about_to_be_negative_index -= invalid, std::runtime_error,
"In-place subtraction with another index invalid RHS.+");
}

Expand All @@ -356,8 +349,8 @@ GTEST_TEST(TypeSafeIndex, StreamInsertion) {
EXPECT_EQ(stream.str(), "8");

AIndex invalid;
EXPECT_ERROR_MESSAGE_IF_ARMED(stream << invalid,
"Converting to an int.+");
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(stream << invalid, std::runtime_error,
"Converting to an int.+");
}

// Tests conversion to string via std::to_string function.
Expand All @@ -367,8 +360,8 @@ GTEST_TEST(TypeSafeIndex, ToString) {
EXPECT_EQ(std::to_string(index), std::to_string(value));

AIndex invalid;
EXPECT_ERROR_MESSAGE_IF_ARMED(std::to_string(invalid),
"Converting to an int.+");
DRAKE_EXPECT_THROWS_MESSAGE_IF_ARMED(
std::to_string(invalid), std::runtime_error, "Converting to an int.+");
}

// Verifies that it is not possible to convert between two different
Expand Down
7 changes: 7 additions & 0 deletions common/test_utilities/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ drake_cc_library(
deps = [
":eigen_geometry_compare",
":eigen_matrix_compare",
":expect_throws_message",
":is_dynamic_castable",
":is_memcpy_movable",
":measure_execution",
Expand Down Expand Up @@ -59,6 +60,12 @@ drake_cc_library(
],
)

drake_cc_library(
name = "expect_throws_message",
testonly = 1,
hdrs = ["expect_throws_message.h"],
)

drake_cc_library(
name = "is_dynamic_castable",
testonly = 1,
Expand Down
Loading

0 comments on commit 5441a5d

Please sign in to comment.