1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
|
/*
* Copyright 2021 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef SDF_TEST_UTILS_HH_
#define SDF_TEST_UTILS_HH_
#include <ostream>
#include "sdf/Console.hh"
namespace sdf
{
namespace testing
{
/// \brief Calls a function when going out of scope.
/// Taken from:
/// https://github.com/ros2/rclcpp/blob/master/rclcpp/include/rclcpp/scope_exit.hpp
template <typename Callable>
struct ScopeExit
{
/// \brief Constructor
/// \param[in] _callable Any callable object that does not throw.
explicit ScopeExit(Callable _callable)
: callable(_callable)
{
}
~ScopeExit()
{
this->callable();
}
private: Callable callable;
};
/// \brief A class used for redirecting the output of sdferr, sdfwarn, etc to a
/// more convenient stream object like a std::stringstream for testing purposes.
/// The class reverts to the original stream object when it goes out of scope.
///
/// Usage example:
///
/// Redirect console output to a std::stringstream object:
///
/// ```
/// std::stringstream buffer;
/// sdf::testing::RedirectConsoleStream redir(
/// sdf::Console::Instance()->GetMsgStream(), &buffer);
///
/// sdfwarn << "Test message";
///
/// ```
/// `buffer` will now contain "Test message" with additional information,
/// such as the file and line number where sdfwarn was called from.
///
/// sdfdbg uses a log file as its output, so to redirect that, we can do
///
/// ```
/// std::stringstream buffer;
/// sdf::testing::RedirectConsoleStream redir(
/// sdf::Console::Instance()->GetLogStream(), &buffer);
///
/// sdfdbg << "Test message";
/// ```
class RedirectConsoleStream
{
/// \brief Constructor
/// \param[in] _consoleStream Mutable reference to a console stream.
/// \param[in] _newSink Pointer to any object derived from std::ostream
public: RedirectConsoleStream(sdf::Console::ConsoleStream &_consoleStream,
std::ostream *_newSink)
: consoleStreamRef(_consoleStream)
, oldStream(_consoleStream)
{
this->consoleStreamRef = sdf::Console::ConsoleStream(_newSink);
}
/// \brief Destructor. Restores the console to the original ConsoleStream
/// object.
public: ~RedirectConsoleStream()
{
this->consoleStreamRef = this->oldStream;
}
/// \brief Reference to the console stream object. This is usually obtained
/// from the singleton sdf::Console object by calling either
/// sdf::Console::GetMsgStream() or sdf::Console::GetLogStream()
private: sdf::Console::ConsoleStream &consoleStreamRef;
/// \brief Copy of the original console stream object. This will be used to
/// restore the console stream when this object goes out of scope.
private: sdf::Console::ConsoleStream oldStream;
};
} // namespace testing
} // namespace sdf
#endif
|