~singpolyma/biboumi

6430479a3a6f15e221f0b9f3e822b44ca37af0f8 — Florent Le Coz 6 years ago 6fb4cf5
Add a IoTester class
2 files changed, 77 insertions(+), 0 deletions(-)

A tests/io_tester.cpp
A tests/io_tester.hpp
A tests/io_tester.cpp => tests/io_tester.cpp +30 -0
@@ 0,0 1,30 @@
#include "io_tester.hpp"
#include "catch.hpp"
#include <iostream>

/**
 * Directly test this class here
 */
TEST_CASE()
{
  {
    IoTester<std::ostream> out(std::cout);
    std::cout << "test";
    CHECK(out.str() == "test");
  }
  {
    IoTester<std::ostream> out(std::cout);
    CHECK(out.str().empty());
  }
}

TEST_CASE()
{
  {
    IoTester<std::istream> is(std::cin);
    is.set_string("coucou");
    std::string res;
    std::cin >> res;
    CHECK(res == "coucou");
  }
}

A tests/io_tester.hpp => tests/io_tester.hpp +47 -0
@@ 0,0 1,47 @@
#ifndef BIBOUMI_IO_TESTER_HPP
#define BIBOUMI_IO_TESTER_HPP

#include <ostream>
#include <sstream>

/**
 * Redirects a stream into a streambuf until the object is destroyed.
 */
template <typename StreamType>
class IoTester
{
public:
  IoTester(StreamType& ios):
    stream{},
    ios(ios),
    old_buf(ios.rdbuf())
  {
    // Redirect the given os into our stringstream’s buf
    this->ios.rdbuf(this->stream.rdbuf());
  }
  ~IoTester()
  {
    this->ios.rdbuf(this->old_buf);
  }
  IoTester& operator=(const IoTester&) = delete;
  IoTester& operator=(IoTester&&) = delete;
  IoTester(const IoTester&) = delete;
  IoTester(IoTester&&) = delete;

  std::string str() const
  {
    return this->stream.str();
  }

  void set_string(const std::string& s)
  {
    this->stream.str(s);
  }

private:
  std::stringstream stream;
  StreamType& ios;
  std::streambuf* const old_buf;
};

#endif //BIBOUMI_IO_TESTER_HPP