1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright 2007, Google Inc. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// All rights reserved. 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Redistribution and use in source and binary forms, with or without 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// modification, are permitted provided that the following conditions are 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// met: 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// * Redistributions of source code must retain the above copyright 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// notice, this list of conditions and the following disclaimer. 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// * Redistributions in binary form must reproduce the above 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// copyright notice, this list of conditions and the following disclaimer 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// in the documentation and/or other materials provided with the 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// distribution. 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// * Neither the name of Google Inc. nor the names of its 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// contributors may be used to endorse or promote products derived from 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// this software without specific prior written permission. 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Author: wan@google.com (Zhanyong Wan) 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Google Mock - a framework for writing C++ mock classes. 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This file implements cardinalities. 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 36dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "gmock/gmock-cardinalities.h" 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <limits.h> 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <ostream> // NOLINT 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <sstream> 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string> 42dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "gmock/internal/gmock-internal-utils.h" 43dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "gtest/gtest.h" 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace testing { 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Implements the Between(m, n) cardinality. 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass BetweenCardinalityImpl : public CardinalityInterface { 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BetweenCardinalityImpl(int min, int max) 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : min_(min >= 0 ? min : 0), 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch max_(max >= min_ ? max : min_) { 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::stringstream ss; 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (min < 0) { 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ss << "The invocation lower bound must be >= 0, " 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << "but is actually " << min << "."; 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch internal::Expect(false, __FILE__, __LINE__, ss.str()); 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (max < 0) { 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ss << "The invocation upper bound must be >= 0, " 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << "but is actually " << max << "."; 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch internal::Expect(false, __FILE__, __LINE__, ss.str()); 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (min > max) { 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ss << "The invocation upper bound (" << max 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << ") must be >= the invocation lower bound (" << min 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << ")."; 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch internal::Expect(false, __FILE__, __LINE__, ss.str()); 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Conservative estimate on the lower/upper bound of the number of 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // calls allowed. 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual int ConservativeLowerBound() const { return min_; } 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual int ConservativeUpperBound() const { return max_; } 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual bool IsSatisfiedByCallCount(int call_count) const { 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return min_ <= call_count && call_count <= max_ ; 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual bool IsSaturatedByCallCount(int call_count) const { 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return call_count >= max_; 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void DescribeTo(::std::ostream* os) const; 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int min_; 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int max_; 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GTEST_DISALLOW_COPY_AND_ASSIGN_(BetweenCardinalityImpl); 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Formats "n times" in a human-friendly way. 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochinline internal::string FormatTimes(int n) { 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (n == 1) { 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return "once"; 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (n == 2) { 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return "twice"; 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::stringstream ss; 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ss << n << " times"; 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ss.str(); 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Describes the Between(m, n) cardinality in human-friendly text. 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BetweenCardinalityImpl::DescribeTo(::std::ostream* os) const { 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (min_ == 0) { 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (max_ == 0) { 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *os << "never called"; 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (max_ == INT_MAX) { 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *os << "called any number of times"; 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *os << "called at most " << FormatTimes(max_); 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (min_ == max_) { 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *os << "called " << FormatTimes(min_); 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (max_ == INT_MAX) { 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *os << "called at least " << FormatTimes(min_); 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 0 < min_ < max_ < INT_MAX 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *os << "called between " << min_ << " and " << max_ << " times"; 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // Unnamed namespace 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Describes the given call count to an ostream. 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Cardinality::DescribeActualCallCountTo(int actual_call_count, 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ::std::ostream* os) { 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (actual_call_count > 0) { 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *os << "called " << FormatTimes(actual_call_count); 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *os << "never called"; 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Creates a cardinality that allows at least n calls. 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochCardinality AtLeast(int n) { return Between(n, INT_MAX); } 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Creates a cardinality that allows at most n calls. 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochCardinality AtMost(int n) { return Between(0, n); } 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Creates a cardinality that allows any number of calls. 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochCardinality AnyNumber() { return AtLeast(0); } 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Creates a cardinality that allows between min and max calls. 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochCardinality Between(int min, int max) { 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return Cardinality(new BetweenCardinalityImpl(min, max)); 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Creates a cardinality that allows exactly n calls. 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochCardinality Exactly(int n) { return Between(n, n); } 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace testing 156