Add the 'googlemock' component of Google Test to LLVM's unittest libraries.
I have two immediate motivations for adding this:
1) It makes writing expectations in tests *dramatically* easier. A
quick example that is a taste of what is possible:
std::vector<int> v = ...;
EXPECT_THAT(v, UnorderedElementsAre(1, 2, 3));
This checks that v contains '1', '2', and '3' in some order. There
are a wealth of other helpful matchers like this. They tend to be
highly generic and STL-friendly so they will in almost all cases work
out of the box even on custom LLVM data structures.
I actually find the matcher syntax substantially easier to read even
for simple assertions:
EXPECT_THAT(a, Eq(b));
EXPECT_THAT(b, Ne(c));
Both of these make it clear what is being *tested* and what is being
*expected*. With `EXPECT_EQ` this is implicit (the LHS is expected,
the RHS is tested) and often confusing. With `EXPECT_NE` it is just
not clear. Even the failure error messages are superior with the
matcher based expectations.
2) When testing any kind of generic code, you are continually defining
dummy types with interfaces and then trying to check that the
interfaces are manipulated in a particular way. This is actually what
mocks are *good* for -- testing *interface interactions*. With
generic code, there is often no "fake" or other object that can be
used.
For a concrete example of where this is currently causing significant
pain, look at the pass manager unittests which are riddled with
counters incremented when methods are called. All of these could be
replaced with mocks. The result would be more effective at testing
the code by having tighter constraints. It would be substantially
more readable and maintainable when updating the code. And the error
messages on failure would have substantially more information as
mocks automatically record stack traces and other information *when
the API is misused* instead of trying to diagnose it after the fact.
I expect that #1 will be the overwhelming majority of the uses of gmock,
but I think that is sufficient to justify having it. I would actually
like to update the coding standards to encourage the use of matchers
rather than any other form of `EXPECT_...` macros as they are IMO
a strict superset in terms of functionality and readability.
I think that #2 is relatively rarely useful, but there *are* cases where
it is useful. Historically, I think misuse of actual mocking as
described in #2 has led to resistance towards this framework. I am
actually sympathetic to this -- mocking can easily be overused. However
I think this is not a significant concern in LLVM. First and foremost,
LLVM has very careful and rare exposure of abstract interfaces or
dependency injection, which are the most prone to abuse with mocks. So
there are few opportunities to abuse them. Second, a large fraction of
LLVM's unittests are testing *generic code* where mocks actually make
tremendous sense. And gmock is well suited to building interfaces that
exercise generic libraries. Finally, I still think we should be willing
to have testing utilities in tree even if they should be used rarely. We
can use code review to help guide the usage here.
For a longer and more complete discussion of this, see the llvm-dev
thread here:
http://lists.llvm.org/pipermail/llvm-dev/2017-January/108672.html
The general consensus seems that this is a reasonable direction to start
down, but that doesn't mean we should race ahead and use this
everywhere. I have one test that is blocked on this to land and that was
specifically used as an example. Before widespread adoption, I'm going
to work up some (brief) guidelines as some of these facilities should be
used sparingly and carefully.
Differential Revision: https://reviews.llvm.org/D28156
llvm-svn: 291606
2017-01-11 06:32:26 +08:00
|
|
|
// Copyright 2007, Google Inc.
|
|
|
|
// All rights reserved.
|
|
|
|
//
|
|
|
|
// Redistribution and use in source and binary forms, with or without
|
|
|
|
// modification, are permitted provided that the following conditions are
|
|
|
|
// met:
|
|
|
|
//
|
|
|
|
// * Redistributions of source code must retain the above copyright
|
|
|
|
// notice, this list of conditions and the following disclaimer.
|
|
|
|
// * Redistributions in binary form must reproduce the above
|
|
|
|
// copyright notice, this list of conditions and the following disclaimer
|
|
|
|
// in the documentation and/or other materials provided with the
|
|
|
|
// distribution.
|
|
|
|
// * Neither the name of Google Inc. nor the names of its
|
|
|
|
// contributors may be used to endorse or promote products derived from
|
|
|
|
// this software without specific prior written permission.
|
|
|
|
//
|
|
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
|
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
|
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
|
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
|
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
//
|
|
|
|
// Author: wan@google.com (Zhanyong Wan)
|
|
|
|
|
|
|
|
// Google Mock - a framework for writing C++ mock classes.
|
|
|
|
//
|
|
|
|
// This file implements some commonly used cardinalities. More
|
|
|
|
// cardinalities can be defined by the user implementing the
|
|
|
|
// CardinalityInterface interface if necessary.
|
|
|
|
|
2019-08-07 16:45:38 +08:00
|
|
|
// IWYU pragma: private, include "gmock/gmock.h"
|
|
|
|
|
Add the 'googlemock' component of Google Test to LLVM's unittest libraries.
I have two immediate motivations for adding this:
1) It makes writing expectations in tests *dramatically* easier. A
quick example that is a taste of what is possible:
std::vector<int> v = ...;
EXPECT_THAT(v, UnorderedElementsAre(1, 2, 3));
This checks that v contains '1', '2', and '3' in some order. There
are a wealth of other helpful matchers like this. They tend to be
highly generic and STL-friendly so they will in almost all cases work
out of the box even on custom LLVM data structures.
I actually find the matcher syntax substantially easier to read even
for simple assertions:
EXPECT_THAT(a, Eq(b));
EXPECT_THAT(b, Ne(c));
Both of these make it clear what is being *tested* and what is being
*expected*. With `EXPECT_EQ` this is implicit (the LHS is expected,
the RHS is tested) and often confusing. With `EXPECT_NE` it is just
not clear. Even the failure error messages are superior with the
matcher based expectations.
2) When testing any kind of generic code, you are continually defining
dummy types with interfaces and then trying to check that the
interfaces are manipulated in a particular way. This is actually what
mocks are *good* for -- testing *interface interactions*. With
generic code, there is often no "fake" or other object that can be
used.
For a concrete example of where this is currently causing significant
pain, look at the pass manager unittests which are riddled with
counters incremented when methods are called. All of these could be
replaced with mocks. The result would be more effective at testing
the code by having tighter constraints. It would be substantially
more readable and maintainable when updating the code. And the error
messages on failure would have substantially more information as
mocks automatically record stack traces and other information *when
the API is misused* instead of trying to diagnose it after the fact.
I expect that #1 will be the overwhelming majority of the uses of gmock,
but I think that is sufficient to justify having it. I would actually
like to update the coding standards to encourage the use of matchers
rather than any other form of `EXPECT_...` macros as they are IMO
a strict superset in terms of functionality and readability.
I think that #2 is relatively rarely useful, but there *are* cases where
it is useful. Historically, I think misuse of actual mocking as
described in #2 has led to resistance towards this framework. I am
actually sympathetic to this -- mocking can easily be overused. However
I think this is not a significant concern in LLVM. First and foremost,
LLVM has very careful and rare exposure of abstract interfaces or
dependency injection, which are the most prone to abuse with mocks. So
there are few opportunities to abuse them. Second, a large fraction of
LLVM's unittests are testing *generic code* where mocks actually make
tremendous sense. And gmock is well suited to building interfaces that
exercise generic libraries. Finally, I still think we should be willing
to have testing utilities in tree even if they should be used rarely. We
can use code review to help guide the usage here.
For a longer and more complete discussion of this, see the llvm-dev
thread here:
http://lists.llvm.org/pipermail/llvm-dev/2017-January/108672.html
The general consensus seems that this is a reasonable direction to start
down, but that doesn't mean we should race ahead and use this
everywhere. I have one test that is blocked on this to land and that was
specifically used as an example. Before widespread adoption, I'm going
to work up some (brief) guidelines as some of these facilities should be
used sparingly and carefully.
Differential Revision: https://reviews.llvm.org/D28156
llvm-svn: 291606
2017-01-11 06:32:26 +08:00
|
|
|
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
|
|
|
#define GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
|
|
|
|
|
|
|
#include <limits.h>
|
|
|
|
#include <ostream> // NOLINT
|
|
|
|
#include "gmock/internal/gmock-port.h"
|
|
|
|
#include "gtest/gtest.h"
|
|
|
|
|
|
|
|
namespace testing {
|
|
|
|
|
|
|
|
// To implement a cardinality Foo, define:
|
|
|
|
// 1. a class FooCardinality that implements the
|
|
|
|
// CardinalityInterface interface, and
|
|
|
|
// 2. a factory function that creates a Cardinality object from a
|
|
|
|
// const FooCardinality*.
|
|
|
|
//
|
|
|
|
// The two-level delegation design follows that of Matcher, providing
|
|
|
|
// consistency for extension developers. It also eases ownership
|
|
|
|
// management as Cardinality objects can now be copied like plain values.
|
|
|
|
|
|
|
|
// The implementation of a cardinality.
|
|
|
|
class CardinalityInterface {
|
|
|
|
public:
|
|
|
|
virtual ~CardinalityInterface() {}
|
|
|
|
|
|
|
|
// Conservative estimate on the lower/upper bound of the number of
|
|
|
|
// calls allowed.
|
|
|
|
virtual int ConservativeLowerBound() const { return 0; }
|
|
|
|
virtual int ConservativeUpperBound() const { return INT_MAX; }
|
|
|
|
|
|
|
|
// Returns true iff call_count calls will satisfy this cardinality.
|
|
|
|
virtual bool IsSatisfiedByCallCount(int call_count) const = 0;
|
|
|
|
|
|
|
|
// Returns true iff call_count calls will saturate this cardinality.
|
|
|
|
virtual bool IsSaturatedByCallCount(int call_count) const = 0;
|
|
|
|
|
|
|
|
// Describes self to an ostream.
|
|
|
|
virtual void DescribeTo(::std::ostream* os) const = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
// A Cardinality is a copyable and IMMUTABLE (except by assignment)
|
|
|
|
// object that specifies how many times a mock function is expected to
|
|
|
|
// be called. The implementation of Cardinality is just a linked_ptr
|
|
|
|
// to const CardinalityInterface, so copying is fairly cheap.
|
|
|
|
// Don't inherit from Cardinality!
|
|
|
|
class GTEST_API_ Cardinality {
|
|
|
|
public:
|
|
|
|
// Constructs a null cardinality. Needed for storing Cardinality
|
|
|
|
// objects in STL containers.
|
|
|
|
Cardinality() {}
|
|
|
|
|
|
|
|
// Constructs a Cardinality from its implementation.
|
|
|
|
explicit Cardinality(const CardinalityInterface* impl) : impl_(impl) {}
|
|
|
|
|
|
|
|
// Conservative estimate on the lower/upper bound of the number of
|
|
|
|
// calls allowed.
|
|
|
|
int ConservativeLowerBound() const { return impl_->ConservativeLowerBound(); }
|
|
|
|
int ConservativeUpperBound() const { return impl_->ConservativeUpperBound(); }
|
|
|
|
|
|
|
|
// Returns true iff call_count calls will satisfy this cardinality.
|
|
|
|
bool IsSatisfiedByCallCount(int call_count) const {
|
|
|
|
return impl_->IsSatisfiedByCallCount(call_count);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Returns true iff call_count calls will saturate this cardinality.
|
|
|
|
bool IsSaturatedByCallCount(int call_count) const {
|
|
|
|
return impl_->IsSaturatedByCallCount(call_count);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Returns true iff call_count calls will over-saturate this
|
|
|
|
// cardinality, i.e. exceed the maximum number of allowed calls.
|
|
|
|
bool IsOverSaturatedByCallCount(int call_count) const {
|
|
|
|
return impl_->IsSaturatedByCallCount(call_count) &&
|
|
|
|
!impl_->IsSatisfiedByCallCount(call_count);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Describes self to an ostream
|
|
|
|
void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); }
|
|
|
|
|
|
|
|
// Describes the given actual call count to an ostream.
|
|
|
|
static void DescribeActualCallCountTo(int actual_call_count,
|
|
|
|
::std::ostream* os);
|
|
|
|
|
|
|
|
private:
|
|
|
|
internal::linked_ptr<const CardinalityInterface> impl_;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Creates a cardinality that allows at least n calls.
|
|
|
|
GTEST_API_ Cardinality AtLeast(int n);
|
|
|
|
|
|
|
|
// Creates a cardinality that allows at most n calls.
|
|
|
|
GTEST_API_ Cardinality AtMost(int n);
|
|
|
|
|
|
|
|
// Creates a cardinality that allows any number of calls.
|
|
|
|
GTEST_API_ Cardinality AnyNumber();
|
|
|
|
|
|
|
|
// Creates a cardinality that allows between min and max calls.
|
|
|
|
GTEST_API_ Cardinality Between(int min, int max);
|
|
|
|
|
|
|
|
// Creates a cardinality that allows exactly n calls.
|
|
|
|
GTEST_API_ Cardinality Exactly(int n);
|
|
|
|
|
|
|
|
// Creates a cardinality from its implementation.
|
|
|
|
inline Cardinality MakeCardinality(const CardinalityInterface* c) {
|
|
|
|
return Cardinality(c);
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace testing
|
|
|
|
|
|
|
|
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|