File: test_utils.hh

package info (click to toggle)
sdformat 12.3.0%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 7,980 kB
  • sloc: cpp: 54,706; python: 3,729; javascript: 704; ruby: 366; sh: 97; ansic: 30; makefile: 16
file content (111 lines) | stat: -rw-r--r-- 3,322 bytes parent folder | download
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