summaryrefslogtreecommitdiff
path: root/src/mongo/unittest
diff options
context:
space:
mode:
authorAndy Schwerin <schwerin@mongodb.com>2014-07-09 10:56:07 -0400
committerAndy Schwerin <schwerin@mongodb.com>2014-07-22 19:01:08 -0400
commitbd82779747f79f3a634df748a09bfa40c557b1bf (patch)
tree311f74082bf5aa9eb5e9198f8386f83d0dc6deb7 /src/mongo/unittest
parentf4e485e9d323496beaaa420d59a460dc9755f9bf (diff)
downloadmongo-bd82779747f79f3a634df748a09bfa40c557b1bf.tar.gz
SERVER-14653 Allow streaming into ASSERT_TRUE and ASSERT_FALSE.
Also contains some basic simplifications of the internal unittest code to facilitate the change.
Diffstat (limited to 'src/mongo/unittest')
-rw-r--r--src/mongo/unittest/unittest.cpp29
-rw-r--r--src/mongo/unittest/unittest.h55
-rw-r--r--src/mongo/unittest/unittest_test.cpp52
3 files changed, 99 insertions, 37 deletions
diff --git a/src/mongo/unittest/unittest.cpp b/src/mongo/unittest/unittest.cpp
index 5f0ed282dd2..e728ced46b1 100644
--- a/src/mongo/unittest/unittest.cpp
+++ b/src/mongo/unittest/unittest.cpp
@@ -316,19 +316,11 @@ namespace mongo {
void Suite::setupTests() {}
- TestAssertionFailureDetails::TestAssertionFailureDetails(
- const std::string& theFile,
- unsigned theLine,
- const std::string& theMessage )
- : file( theFile ), line( theLine ), message( theMessage ) {
- }
-
TestAssertionFailureException::TestAssertionFailureException(
const std::string& theFile,
unsigned theLine,
const std::string& theFailingExpression )
- : _details( new TestAssertionFailureDetails( theFile, theLine, theFailingExpression ) ) {
- }
+ : _file(theFile), _line(theLine), _message(theFailingExpression) {}
std::string TestAssertionFailureException::toString() const {
std::ostringstream os;
@@ -336,6 +328,25 @@ namespace mongo {
return os.str();
}
+ TestAssertionFailure::TestAssertionFailure(const std::string& file,
+ unsigned line,
+ const std::string& message)
+ : _exception(file, line, message) {}
+
+ TestAssertionFailure::~TestAssertionFailure()
+#if __cplusplus >= 201103
+ noexcept(false)
+#endif
+ {
+ if (!_stream.str().empty())
+ _exception.setMessage(_exception.getMessage() + " " + _stream.str());
+ throw _exception;
+ }
+
+ std::ostream& TestAssertionFailure::stream() {
+ return _stream;
+ }
+
TestAssertion::TestAssertion( const char* file, unsigned line )
: _file( file ), _line( line ) {
diff --git a/src/mongo/unittest/unittest.h b/src/mongo/unittest/unittest.h
index df9ce18e127..8e27707b391 100644
--- a/src/mongo/unittest/unittest.h
+++ b/src/mongo/unittest/unittest.h
@@ -57,8 +57,7 @@
/**
* Fails unless "EXPRESSION" is true.
*/
-#define ASSERT_TRUE(EXPRESSION) ::mongo::unittest::TestAssertion( __FILE__, __LINE__ ).failIf( \
- !(EXPRESSION), "Expected: " #EXPRESSION )
+#define ASSERT_TRUE(EXPRESSION) if (!(EXPRESSION)) ::mongo::unittest::TestAssertionFailure(__FILE__, __LINE__, "Expected: " #EXPRESSION).stream()
#define ASSERT(EXPRESSION) ASSERT_TRUE(EXPRESSION)
/**
@@ -74,8 +73,8 @@
/**
* Fails if "EXPRESSION" is true.
*/
-#define ASSERT_FALSE(EXPRESSION) ::mongo::unittest::TestAssertion( __FILE__, __LINE__ ).failIf( \
- (EXPRESSION), "Expected: !(" #EXPRESSION ")" )
+#define ASSERT_FALSE(EXPRESSION) if (EXPRESSION) \
+::mongo::unittest::TestAssertionFailure(__FILE__, __LINE__, "Expected: !(" #EXPRESSION ")").stream()
/*
* Binary comparison assertions.
@@ -347,21 +346,6 @@ namespace mongo {
};
/**
- * Collection of information about failed tests. Used in reporting
- * failures.
- */
- class TestAssertionFailureDetails : private boost::noncopyable {
- public:
- TestAssertionFailureDetails( const std::string& theFile,
- unsigned theLine,
- const std::string& theMessage );
-
- const std::string file;
- const unsigned line;
- const std::string message;
- };
-
- /**
* Exception thrown when a test assertion fails.
*
* Typically thrown by helpers in the TestAssertion class and its ilk, below.
@@ -372,18 +356,37 @@ namespace mongo {
*/
class TestAssertionFailureException {
public:
- TestAssertionFailureException( const std::string& theFile,
- unsigned theLine,
- const std::string& theMessage );
+ TestAssertionFailureException(const std::string& theFile,
+ unsigned theLine,
+ const std::string& theMessage);
- const std::string& getFile() const { return _details->file; }
- unsigned getLine() const { return _details->line; }
- const std::string& getMessage() const { return _details->message; }
+ const std::string& getFile() const { return _file; }
+ unsigned getLine() const { return _line; }
+ const std::string& getMessage() const { return _message; }
+ void setMessage(const std::string& message) { _message = message; }
std::string toString() const;
private:
- boost::shared_ptr<TestAssertionFailureDetails> _details;
+ std::string _file;
+ unsigned _line;
+ std::string _message;
+ };
+
+ class TestAssertionFailure {
+ MONGO_DISALLOW_COPYING(TestAssertionFailure);
+ public:
+ TestAssertionFailure(
+ const std::string& file, unsigned line, const std::string& message);
+#if __cplusplus < 201103
+ ~TestAssertionFailure();
+#else
+ ~TestAssertionFailure() noexcept(false);
+#endif
+ std::ostream& stream();
+ private:
+ TestAssertionFailureException _exception;
+ std::ostringstream _stream;
};
/**
diff --git a/src/mongo/unittest/unittest_test.cpp b/src/mongo/unittest/unittest_test.cpp
index 595933de1cf..4e62c47761c 100644
--- a/src/mongo/unittest/unittest_test.cpp
+++ b/src/mongo/unittest/unittest_test.cpp
@@ -1,21 +1,63 @@
/**
- * Copyright (C) 2012 10gen Inc.
- */
+* Copyright (C) 2012 MongoDB, Inc.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License, version 3,
+* as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+* As a special exception, the copyright holders give permission to link the
+* code of portions of this program with the OpenSSL library under certain
+* conditions as described in each individual source file and distribute
+* linked combinations including the program with the OpenSSL library. You
+* must comply with the GNU Affero General Public License in all respects
+* for all of the code used other than as permitted herein. If you modify
+* file(s) with this exception, you may extend this exception to your
+* version of the file(s), but you are not obligated to do so. If you do not
+* wish to do so, delete this exception statement from your version. If you
+* delete this exception statement from all source files in the program,
+* then also delete it in the license file.
+*/
/**
* Unit tests of the unittest framework itself.
*/
+#include "mongo/platform/basic.h"
+
#include "mongo/unittest/unittest.h"
#include <limits>
#include <string>
+#include "mongo/stdx/functional.h"
+
namespace {
+ namespace stdx = mongo::stdx;
+
+ bool containsPattern(const std::string& pattern, const std::string& value) {
+ return value.find(pattern) != std::string::npos;
+ }
#define ASSERT_TEST_FAILS(TEST_EXPR) \
ASSERT_THROWS((TEST_EXPR), mongo::unittest::TestAssertionFailureException)
+#define ASSERT_TEST_FAILS_MATCH(TEST_EXPR, PATTERN) \
+ ASSERT_THROWS_PRED( \
+ TEST_EXPR, \
+ mongo::unittest::TestAssertionFailureException, \
+ stdx::bind(containsPattern, \
+ PATTERN, \
+ stdx::bind(&mongo::unittest::TestAssertionFailureException::getMessage, \
+ stdx::placeholders::_1)))
+
TEST(UnitTestSelfTest, DoNothing) {
}
@@ -76,4 +118,10 @@ namespace {
ASSERT_TEST_FAILS(ASSERT_EQUALS("hello", std::string("good bye!")));
}
+ TEST(UnitTestSelfTest, TestStreamingIntoFailures) {
+ ASSERT_TEST_FAILS_MATCH(ASSERT_TRUE(false) << "Told you so", "Told you so");
+ ASSERT_TEST_FAILS_MATCH(ASSERT(false) << "Told you so", "Told you so");
+ ASSERT_TEST_FAILS_MATCH(ASSERT_FALSE(true) << "Told you so", "Told you so");
+ }
+
} // namespace