File: action.cpp

package info (click to toggle)
actor-framework 0.18.7-1~exp1
  • links: PTS
  • area: main
  • in suites: experimental
  • size: 8,740 kB
  • sloc: cpp: 85,162; sh: 491; python: 187; makefile: 11
file content (98 lines) | stat: -rw-r--r-- 2,783 bytes parent folder | download
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
// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.

#define CAF_SUITE action

#include "caf/action.hpp"

#include "core-test.hpp"

using namespace caf;

namespace {

using fixture = test_coordinator_fixture<>;

} // namespace

BEGIN_FIXTURE_SCOPE(fixture)

SCENARIO("actions wrap function calls") {
  GIVEN("an action wrapping a lambda") {
    WHEN("running the action") {
      THEN("it calls the lambda and transitions from scheduled to invoked") {
        auto called = false;
        auto uut = make_action([&called] { called = true; });
        CHECK(uut.scheduled());
        uut.run();
        CHECK(called);
        CHECK(uut.invoked());
      }
    }
    WHEN("disposing the action") {
      THEN("it transitions to disposed and run no longer calls the lambda") {
        auto called = false;
        auto uut = make_action([&called] { called = true; });
        CHECK(uut.scheduled());
        uut.dispose();
        CHECK(uut.disposed());
        uut.run();
        CHECK(!called);
        CHECK(uut.disposed());
      }
    }
    WHEN("running the action multiple times") {
      THEN("any call after the first becomes a no-op") {
        auto n = 0;
        auto uut = make_action([&n] { ++n; });
        uut.run();
        uut.run();
        uut.run();
        CHECK(uut.invoked());
        CHECK_EQ(n, 1);
      }
    }
    WHEN("re-scheduling an action after running it") {
      THEN("then the lambda gets invoked twice") {
        auto n = 0;
        auto uut = make_action([&n] { ++n; });
        uut.run();
        uut.run();
        CHECK_EQ(uut.reschedule(), action::transition::success);
        uut.run();
        uut.run();
        CHECK(uut.invoked());
        CHECK_EQ(n, 2);
      }
    }
    WHEN("converting an action to a disposable") {
      THEN("the disposable and the action point to the same impl object") {
        auto uut = make_action([] {});
        auto d1 = uut.as_disposable();         // const& overload
        auto d2 = action{uut}.as_disposable(); // && overload
        CHECK_EQ(uut.ptr(), d1.ptr());
        CHECK_EQ(uut.ptr(), d2.ptr());
      }
    }
  }
}

SCENARIO("actors run actions that they receive") {
  GIVEN("a scheduled actor") {
    WHEN("sending it an action") {
      THEN("the actor runs the action regardless of its behavior") {
        auto aut = sys.spawn([](caf::event_based_actor*) -> behavior {
          return {
            [](int32_t x) { return x; },
          };
        });
        auto n = 0;
        inject((action), to(aut).with(make_action([&n] { ++n; })));
        CHECK_EQ(n, 1);
      }
    }
  }
}

END_FIXTURE_SCOPE()