summaryrefslogtreecommitdiff
path: root/vendor/bandit/specs/describe.spec.cpp
blob: d4600a28435b44ba979dc2c4be9b303ea684ad4e (plain)
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
112
113
114
115
116
117
#include <specs/specs.h>

using namespace bandit::fakes;
namespace bd = bandit::detail;

SPEC_BEGIN(describe)

  describe("describe:", [](){
    bandit::detail::voidfunc_t describe_fn;
    fake_reporter_ptr reporter;
    std::unique_ptr<bd::contextstack_t> context_stack;
    std::unique_ptr<fake_context> global_context;

    before_each([&](){
      reporter = fake_reporter_ptr(new fake_reporter());

      context_stack = std::unique_ptr<bd::contextstack_t>(new bd::contextstack_t());

      global_context = std::unique_ptr<fake_context>(new fake_context());
      context_stack->push_back(global_context.get());
    });


    auto call_describe = [&](){
        describe("context name", describe_fn, *reporter, *context_stack);
    };

    describe("with a succeeding 'it'", [&](){
      int context_stack_size_while_running;

      before_each([&](){
        context_stack_size_while_running = 0;
        describe_fn = [&](){context_stack_size_while_running = context_stack->size();};
      });

      it("tells its parent context that execution has started", [&](){
        // This is important as once execution has started,
        // before_each and after_each calls cannot be guaranteed to
        // be run before any 'it' method.

        call_describe();
        AssertThat(global_context->call_log(), Has().AtLeast(1).EqualTo("execution_is_starting"));
      });

      it("tells reporter it's starting a run", [&](){
        call_describe();
        AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("context_starting: context name"));
      });

      it("tells reporter it's finished a run", [&](){
        call_describe();
        AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("context_ended: context name"));
      });

      it("pushes a new context during execution", [&](){
        call_describe();
        AssertThat(context_stack_size_while_running, Equals(2));
      });

      it("pops the context from the stack after execution so that only the global context is left", [&](){
          call_describe();
          AssertThat(*context_stack, Is().OfLength(1));
      });

    });

    describe("with test run error", [&](){
        //
        // This can occur if after_each or before_each are called
        // after execution has started for a context.
        // 
    
      before_each([&](){
        describe_fn = [&](){ throw bandit::detail::test_run_error("we dun goofed!"); };
      });

      it("doesn't propagate the error", [&](){
        call_describe();
      });

      it("tells reporter to report the error", [&](){
        call_describe();
        AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("test_run_error: context name (we dun goofed!)"));
      });
    
    });

    describe("skip", [&](){
      bool context_is_hard_skip;
      describe_fn = 
          [&](){ context_is_hard_skip = context_stack->back()->hard_skip(); };

      before_each([&](){
        context_is_hard_skip = false;
      });

      describe("describe_skip", [&](){
      
        it("pushes a context marked as skipped on the stack", [&](){
          describe_skip("context name", describe_fn, *reporter, *context_stack);
          AssertThat(context_is_hard_skip, IsTrue());
        });
      
      });

      describe("xdescribe", [&](){

        it("pushes a context marked as skipped on the stack", [&](){
          xdescribe("context name", describe_fn, *reporter, *context_stack);
          AssertThat(context_is_hard_skip, IsTrue());
        });

      });
    });
  });

SPEC_END