Improves error messages for undefined return value (by Sverre Sundsdal); improves gmock_doctor.
This commit is contained in:
@@ -69,6 +69,8 @@ class ActionAdaptor;
|
||||
template <typename T>
|
||||
class BuiltInDefaultValue {
|
||||
public:
|
||||
// This function returns true iff type T has a built-in default value.
|
||||
static bool Exists() { return false; }
|
||||
static T Get() {
|
||||
Assert(false, __FILE__, __LINE__,
|
||||
"Default action undefined for the function return type.");
|
||||
@@ -83,6 +85,7 @@ class BuiltInDefaultValue {
|
||||
template <typename T>
|
||||
class BuiltInDefaultValue<const T> {
|
||||
public:
|
||||
static bool Exists() { return BuiltInDefaultValue<T>::Exists(); }
|
||||
static T Get() { return BuiltInDefaultValue<T>::Get(); }
|
||||
};
|
||||
|
||||
@@ -91,6 +94,7 @@ class BuiltInDefaultValue<const T> {
|
||||
template <typename T>
|
||||
class BuiltInDefaultValue<T*> {
|
||||
public:
|
||||
static bool Exists() { return true; }
|
||||
static T* Get() { return NULL; }
|
||||
};
|
||||
|
||||
@@ -100,6 +104,7 @@ class BuiltInDefaultValue<T*> {
|
||||
template <> \
|
||||
class BuiltInDefaultValue<type> { \
|
||||
public: \
|
||||
static bool Exists() { return true; } \
|
||||
static type Get() { return value; } \
|
||||
}
|
||||
|
||||
@@ -191,6 +196,12 @@ class DefaultValue {
|
||||
// Returns true iff the user has set the default value for type T.
|
||||
static bool IsSet() { return value_ != NULL; }
|
||||
|
||||
// Returns true if T has a default return value set by the user or there
|
||||
// exists a built-in default value.
|
||||
static bool Exists() {
|
||||
return IsSet() || internal::BuiltInDefaultValue<T>::Exists();
|
||||
}
|
||||
|
||||
// Returns the default value for type T if the user has set one;
|
||||
// otherwise returns the built-in default value if there is one;
|
||||
// otherwise aborts the process.
|
||||
@@ -220,6 +231,12 @@ class DefaultValue<T&> {
|
||||
// Returns true iff the user has set the default value for type T&.
|
||||
static bool IsSet() { return address_ != NULL; }
|
||||
|
||||
// Returns true if T has a default return value set by the user or there
|
||||
// exists a built-in default value.
|
||||
static bool Exists() {
|
||||
return IsSet() || internal::BuiltInDefaultValue<T&>::Exists();
|
||||
}
|
||||
|
||||
// Returns the default value for type T& if the user has set one;
|
||||
// otherwise returns the built-in default value if there is one;
|
||||
// otherwise aborts the process.
|
||||
@@ -236,6 +253,7 @@ class DefaultValue<T&> {
|
||||
template <>
|
||||
class DefaultValue<void> {
|
||||
public:
|
||||
static bool Exists() { return true; }
|
||||
static void Get() {}
|
||||
};
|
||||
|
||||
|
||||
@@ -1061,15 +1061,21 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Performs the default action of this mock function on the given
|
||||
// arguments and returns the result. This method doesn't depend on
|
||||
// the mutable state of this object, and thus can be called
|
||||
// concurrently without locking.
|
||||
// Performs the default action of this mock function on the given arguments
|
||||
// and returns the result. Asserts with a helpful call descrption if there is
|
||||
// no valid return value. This method doesn't depend on the mutable state of
|
||||
// this object, and thus can be called concurrently without locking.
|
||||
// L = *
|
||||
Result PerformDefaultAction(const ArgumentTuple& args) const {
|
||||
Result PerformDefaultAction(const ArgumentTuple& args,
|
||||
const string& call_description) const {
|
||||
const DefaultActionSpec<F>* const spec = FindDefaultActionSpec(args);
|
||||
return (spec != NULL) ? spec->GetAction().Perform(args)
|
||||
: DefaultValue<Result>::Get();
|
||||
if (spec != NULL) {
|
||||
return spec->GetAction().Perform(args);
|
||||
}
|
||||
Assert(DefaultValue<Result>::Exists(), "", -1,
|
||||
call_description + "\n The mock function has no default action "
|
||||
"set, and its return type has no default value set.");
|
||||
return DefaultValue<Result>::Get();
|
||||
}
|
||||
|
||||
// Registers this function mocker and the mock object owning it;
|
||||
@@ -1407,7 +1413,7 @@ class InvokeWithHelper {
|
||||
Mock::GetReactionOnUninterestingCalls(mocker->MockObject());
|
||||
|
||||
// Calculates the function result.
|
||||
Result result = mocker->PerformDefaultAction(args);
|
||||
Result result = mocker->PerformDefaultAction(args, ss.str());
|
||||
|
||||
// Prints the function result.
|
||||
ss << "\n Returns: ";
|
||||
@@ -1429,8 +1435,8 @@ class InvokeWithHelper {
|
||||
args, &exp, &action, &is_excessive, &ss, &why);
|
||||
ss << " Function call: " << mocker->Name();
|
||||
UniversalPrinter<ArgumentTuple>::Print(args, &ss);
|
||||
Result result =
|
||||
action.IsDoDefault() ? mocker->PerformDefaultAction(args)
|
||||
Result result = action.IsDoDefault() ?
|
||||
mocker->PerformDefaultAction(args, ss.str())
|
||||
: action.Perform(args);
|
||||
ss << "\n Returns: ";
|
||||
UniversalPrinter<Result>::Print(result, &ss);
|
||||
@@ -1480,7 +1486,7 @@ class InvokeWithHelper<void, F> {
|
||||
const CallReaction reaction =
|
||||
Mock::GetReactionOnUninterestingCalls(mocker->MockObject());
|
||||
|
||||
mocker->PerformDefaultAction(args);
|
||||
mocker->PerformDefaultAction(args, ss.str());
|
||||
ReportUninterestingCall(reaction, ss.str());
|
||||
return;
|
||||
}
|
||||
@@ -1499,7 +1505,7 @@ class InvokeWithHelper<void, F> {
|
||||
UniversalPrinter<ArgumentTuple>::Print(args, &ss);
|
||||
ss << "\n" << why.str();
|
||||
if (action.IsDoDefault()) {
|
||||
mocker->PerformDefaultAction(args);
|
||||
mocker->PerformDefaultAction(args, ss.str());
|
||||
} else {
|
||||
action.Perform(args);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user