diff options
author | Andy Schwerin <schwerin@mongodb.com> | 2014-07-09 10:56:07 -0400 |
---|---|---|
committer | Andy Schwerin <schwerin@mongodb.com> | 2014-07-22 19:01:08 -0400 |
commit | bd82779747f79f3a634df748a09bfa40c557b1bf (patch) | |
tree | 311f74082bf5aa9eb5e9198f8386f83d0dc6deb7 /src/mongo/unittest | |
parent | f4e485e9d323496beaaa420d59a460dc9755f9bf (diff) | |
download | mongo-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.cpp | 29 | ||||
-rw-r--r-- | src/mongo/unittest/unittest.h | 55 | ||||
-rw-r--r-- | src/mongo/unittest/unittest_test.cpp | 52 |
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 |