doctest

FORK: The fastest feature-rich C++11/14/17/20 single-header testing framework
git clone https://git.neptards.moe/neptards/doctest.git
Log | Files | Refs | README

how_subcases_work.cpp (2563B)


      1 /* THE OUTPUT IS:
      2 
      3 creating empty vector
      4 + 2
      5 == size: 2
      6 + 2
      7 == size: 4
      8 
      9 creating empty vector
     10 + 2
     11 == size: 2
     12 + 1
     13 == size: 3
     14 
     15 creating empty vector
     16 + 1
     17 == size: 1
     18 
     19 */
     20 
     21 #include <iostream>
     22 #include <vector>
     23 #include <set>
     24 
     25 using namespace std;
     26 
     27 set<pair<const char*, int> > passed_subcases;
     28 set<int> entered_levels;
     29 int current_level;
     30 bool has_skipped;
     31 
     32 struct Subcase {
     33     Subcase(const char* file, int line)
     34         : m_entered(false)
     35         , m_file(file)
     36         , m_line(line)
     37     {
     38         m_entered = false;
     39 
     40         // if we have already completed it
     41         if(passed_subcases.count(pair<const char*, int>(file, line)) != 0)
     42             return;
     43 
     44         // if a Subcase on the same level has already been entered
     45         if(entered_levels.count(current_level) != 0) {
     46             has_skipped = true;
     47             return;
     48         }
     49 
     50         entered_levels.insert(current_level++);
     51 
     52         m_entered = true;
     53     }
     54 
     55     ~Subcase() {
     56         if(m_entered) {
     57             current_level--;
     58             // only mark the subcase as passed if no subcases have been skipped
     59             if(has_skipped == false)
     60                 passed_subcases.insert(pair<const char*, int>(m_file, m_line));
     61         }
     62     }
     63 
     64     operator bool() const { return m_entered; }
     65 
     66     bool m_entered;
     67     const char* m_file;
     68     int m_line;
     69 };
     70 
     71 #define STR_CONCAT_IMPL(s1, s2) s1##s2
     72 #define STR_CONCAT(s1, s2) STR_CONCAT_IMPL(s1, s2)
     73 #define ANON_VAR STR_CONCAT(anon, __LINE__)
     74 
     75 #define subcase(title) if(const Subcase& ANON_VAR = Subcase(__FILE__, __LINE__))
     76 
     77 void test() {
     78     cout << endl << "creating empty vector" << endl;
     79     vector<int> data;
     80 
     81     subcase("size should grow to 2") {
     82         cout << "+ 2" << endl;
     83         data.push_back(42);
     84         data.push_back(10);
     85         cout << "== size: " << data.size() << endl;
     86 
     87         subcase("size should grow to 4") {
     88             cout << "+ 2" << endl;
     89             data.push_back(666);
     90             data.push_back(100);
     91             cout << "== size: " << data.size() << endl;
     92         }
     93         subcase("size should grow to 3") {
     94             cout << "+ 1" << endl;
     95             data.push_back(666);
     96             cout << "== size: " << data.size() << endl;
     97         }
     98     }
     99     subcase("size should grow to 1") {
    100         cout << "+ 1" << endl;
    101         data.push_back(42);
    102         cout << "== size: " << data.size() << endl;
    103     }
    104 }
    105 
    106 int main() {
    107     passed_subcases.clear();
    108     do {
    109         has_skipped = false;
    110         current_level = 0;
    111         entered_levels.clear();
    112         test();
    113     } while(has_skipped == true);
    114 
    115     return 0;
    116 }