| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | //====================================================================================================================== | ||
| 2 | //! @file | ||
| 3 | /* | ||
| 4 | TTS - Tiny Test System | ||
| 5 | Copyright : TTS Contributors & Maintainers | ||
| 6 | SPDX-License-Identifier: BSL-1.0 | ||
| 7 | */ | ||
| 8 | //====================================================================================================================== | ||
| 9 | #pragma once | ||
| 10 | |||
| 11 | #include <tts/tools/preprocessor.hpp> | ||
| 12 | #include <tts/tools/options.hpp> | ||
| 13 | #include <tts/tools/text.hpp> | ||
| 14 | |||
| 15 | namespace tts::_ | ||
| 16 | { | ||
| 17 | struct section_guard | ||
| 18 | { | ||
| 19 | int& id; | ||
| 20 | int const& section; | ||
| 21 | |||
| 22 | 8 | section_guard(int& id_, int const& section_, int& count) | |
| 23 | 8 | : id(id_) | |
| 24 | 8 | , section(section_) | |
| 25 | { | ||
| 26 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
|
8 | if(section == 0) id = count++ - 1; |
| 27 | 8 | } | |
| 28 | |||
| 29 | 8 | bool check(char const* desc) | |
| 30 | { | ||
| 31 |
5/8✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 8 times.
|
8 | if(id == section && desc && ::tts::is_verbose()) |
| 32 | ✗ | ::tts::output().writeln(" And then: %s", desc); | |
| 33 | 8 | return id == section; | |
| 34 | } | ||
| 35 | }; | ||
| 36 | |||
| 37 | struct only_once | ||
| 38 | { | ||
| 39 | bool once = true; | ||
| 40 | 16 | explicit operator bool() | |
| 41 | { | ||
| 42 | 16 | bool result = once; | |
| 43 | 16 | once = false; | |
| 44 | 16 | return result; | |
| 45 | } | ||
| 46 | }; | ||
| 47 | } | ||
| 48 | |||
| 49 | //====================================================================================================================== | ||
| 50 | /** | ||
| 51 | @name Scoped scenarios | ||
| 52 | @ingroup test-scenario | ||
| 53 | @{ | ||
| 54 | **/ | ||
| 55 | //====================================================================================================================== | ||
| 56 | |||
| 57 | //====================================================================================================================== | ||
| 58 | /** | ||
| 59 | @def TTS_WHEN | ||
| 60 | @ingroup test-scenario | ||
| 61 | @brief Start a block of scoped environment. | ||
| 62 | |||
| 63 | Code in a scoped environment can contain: | ||
| 64 | + Normal expressions. | ||
| 65 | + scoped tests introduced by @ref TTS_AND_THEN. | ||
| 66 | |||
| 67 | @see TTS_AND_THEN | ||
| 68 | |||
| 69 | @groupheader{Example} | ||
| 70 | @snippet doc/when.cpp snippet | ||
| 71 | **/ | ||
| 72 | //====================================================================================================================== | ||
| 73 | #if defined(TTS_DOXYGEN_INVOKED) | ||
| 74 | #define TTS_WHEN(STORY) | ||
| 75 | #else | ||
| 76 | #define TTS_WHEN(STORY) \ | ||
| 77 | TTS_DISABLE_WARNING_PUSH \ | ||
| 78 | TTS_DISABLE_WARNING_SHADOW( \ | ||
| 79 | ::tts::is_verbose() ? (::tts::output().writeln("When : %s", ::tts::text {STORY}.data()), 0) \ | ||
| 80 | : 0); \ | ||
| 81 | for(int tts_section = 0, tts_count = 1; tts_section < tts_count; \ | ||
| 82 | tts_count -= 0 == tts_section++) \ | ||
| 83 | for(tts::_::only_once tts_only_once_setup {}; tts_only_once_setup;) \ | ||
| 84 | TTS_DISABLE_WARNING_POP \ | ||
| 85 | /**/ | ||
| 86 | #endif | ||
| 87 | |||
| 88 | #define TTS_AND_THEN_IMPL(TTS_LOCAL_ID, MESSAGE) \ | ||
| 89 | TTS_DISABLE_WARNING_PUSH \ | ||
| 90 | TTS_DISABLE_WARNING_SHADOW \ | ||
| 91 | static int TTS_LOCAL_ID = 0; \ | ||
| 92 | if(::tts::_::section_guard(TTS_LOCAL_ID, tts_section, tts_count).check(MESSAGE)) \ | ||
| 93 | for(int tts_section = 0, tts_count = 1; tts_section < tts_count; \ | ||
| 94 | tts_count -= 0 == tts_section++) \ | ||
| 95 | for(tts::_::only_once tts__only_once_section {}; tts__only_once_section;) \ | ||
| 96 | TTS_DISABLE_WARNING_POP \ | ||
| 97 | /**/ | ||
| 98 | |||
| 99 | //====================================================================================================================== | ||
| 100 | /** | ||
| 101 | @def TTS_AND_THEN | ||
| 102 | @ingroup test-scenario | ||
| 103 | @brief Add a scoped tests to current scoped environment. | ||
| 104 | |||
| 105 | Compared to regular local scope, whenever a scoped test is run, the data defined in the enclosing | ||
| 106 | @ref TTS_WHEN are re-initialized, thus serving as a setup/tear-down system. | ||
| 107 | |||
| 108 | @see TTS_WHEN | ||
| 109 | |||
| 110 | @groupheader{Example} | ||
| 111 | @snippet doc/when.cpp snippet | ||
| 112 | **/ | ||
| 113 | //====================================================================================================================== | ||
| 114 | #if defined(TTS_DOXYGEN_INVOKED) | ||
| 115 | #define TTS_AND_THEN(MESSAGE) | ||
| 116 | #else | ||
| 117 | #define TTS_AND_THEN(MESSAGE) TTS_AND_THEN_IMPL(TTS_UNIQUE(id), MESSAGE) | ||
| 118 | #endif | ||
| 119 | |||
| 120 | //====================================================================================================================== | ||
| 121 | /// @} | ||
| 122 | //====================================================================================================================== | ||
| 123 |