Jan Kundrát | 5c80521 | 2018-03-02 13:57:12 +0100 | [diff] [blame] | 1 | #pragma once |
| 2 | |
| 3 | #ifdef REQUIRE |
| 4 | # error This file needs to be included prior to including anything from Catch. |
| 5 | #endif |
| 6 | |
| 7 | // clang-format off |
| 8 | |
| 9 | #include <ostream> |
| 10 | #include <thread> |
| 11 | #include <catch.hpp> |
| 12 | #include <trompeloeil.hpp> |
| 13 | |
| 14 | // this is copy-paste from https://github.com/rollbear/trompeloeil/blob/master/docs/CookBook.md/#unit_test_frameworks |
| 15 | namespace trompeloeil { |
| 16 | |
| 17 | /** @short Pass reports from the Trompeloeil mocker to Catch for processing as test failures */ |
| 18 | template <> |
| 19 | struct reporter<trompeloeil::specialized> |
| 20 | { |
| 21 | static void send(trompeloeil::severity s, |
| 22 | const char* file, |
| 23 | unsigned long line, |
| 24 | const char* msg) |
| 25 | { |
| 26 | std::ostringstream os; |
| 27 | if (line) os << file << ':' << line << '\n'; |
| 28 | os << msg; |
| 29 | auto failure = os.str(); |
| 30 | if (s == severity::fatal) |
| 31 | { |
| 32 | FAIL(failure); |
| 33 | } |
| 34 | else |
| 35 | { |
| 36 | CAPTURE(failure); |
| 37 | CHECK(failure.empty()); |
| 38 | } |
| 39 | } |
| 40 | }; |
| 41 | } |
| 42 | |
| 43 | /** @short Wait until a given sequence of expectation is matched, and then a bit more to ensure that there's silence afterwards */ |
| 44 | void waitForCompletionAndBitMore(const trompeloeil::sequence& seq) |
| 45 | { |
| 46 | using namespace std::literals; |
| 47 | using clock = std::chrono::steady_clock; |
| 48 | |
| 49 | // We're busy-waiting a bit |
| 50 | const auto waitingStep = 30ms; |
| 51 | // Timeout after this much |
| 52 | const auto completionTimeout = 5000ms; |
| 53 | // When checking for silence afterwards, wait at least this long. |
| 54 | // We'll also wait as long as it originally took to process everything. |
| 55 | const auto minExtraWait = 100ms; |
| 56 | |
| 57 | auto start = clock::now(); |
| 58 | while (!seq.is_completed()) { |
| 59 | std::this_thread::sleep_for(waitingStep); |
| 60 | if (clock::now() - start > completionTimeout) { |
| 61 | break; |
| 62 | } |
| 63 | } |
| 64 | REQUIRE(seq.is_completed()); |
| 65 | auto duration = std::chrono::duration<double>(clock::now() - start); |
| 66 | std::this_thread::sleep_for(std::max(duration, decltype(duration)(minExtraWait))); |
| 67 | } |