| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440 |
- // This file is part of Desktop App Toolkit,
- // a set of libraries for developing nice desktop applications.
- //
- // For license and copyright information please follow this link:
- // https://github.com/desktop-app/legal/blob/master/LEGAL
- //
- #include <catch.hpp>
- #include <rpl/producer.h>
- #include <rpl/event_stream.h>
- using namespace rpl;
- class OnDestructor {
- public:
- OnDestructor(std::function<void()> callback)
- : _callback(std::move(callback)) {
- }
- ~OnDestructor() {
- if (_callback) {
- _callback();
- }
- }
- private:
- std::function<void()> _callback;
- };
- TEST_CASE("basic producer tests", "[rpl::producer]") {
- SECTION("producer next, done and lifetime end test") {
- auto lifetimeEnded = std::make_shared<bool>(false);
- auto sum = std::make_shared<int>(0);
- auto doneGenerated = std::make_shared<bool>(false);
- auto destroyed = std::make_shared<bool>(false);
- {
- auto destroyCaller = std::make_shared<OnDestructor>([=] {
- *destroyed = true;
- });
- {
- auto alive = make_producer<int>([=](auto &&consumer) {
- (void)destroyCaller;
- consumer.put_next(1);
- consumer.put_next(2);
- consumer.put_next(3);
- consumer.put_done();
- return [=] {
- (void)destroyCaller;
- *lifetimeEnded = true;
- };
- }).start([=](int value) {
- (void)destroyCaller;
- *sum += value;
- }, [=](no_error) {
- (void)destroyCaller;
- }, [=]() {
- (void)destroyCaller;
- *doneGenerated = true;
- });
- }
- }
- REQUIRE(*sum == 1 + 2 + 3);
- REQUIRE(*doneGenerated);
- REQUIRE(*lifetimeEnded);
- REQUIRE(*destroyed);
- }
- SECTION("producer error test") {
- auto errorGenerated = std::make_shared<bool>(false);
- {
- auto alive = make_producer<no_value, bool>([=](auto &&consumer) {
- consumer.put_error(true);
- return lifetime();
- }).start([=](no_value) {
- }, [=](bool error) {
- *errorGenerated = error;
- }, [=]() {
- });
- }
- REQUIRE(*errorGenerated);
- }
- SECTION("nested lifetimes test") {
- auto lifetimeEndCount = std::make_shared<int>(0);
- {
- auto lifetimes = lifetime();
- {
- auto testProducer = make_producer<no_value>([=](auto &&consumer) {
- return [=] {
- ++*lifetimeEndCount;
- };
- });
- testProducer.start_copy([=](no_value) {
- }, [=](no_error) {
- }, [=] {
- }, lifetimes);
- std::move(testProducer).start([=](no_value) {
- }, [=](no_error) {
- }, [=] {
- }, lifetimes);
- }
- REQUIRE(*lifetimeEndCount == 0);
- }
- REQUIRE(*lifetimeEndCount == 2);
- }
- SECTION("nested producers test") {
- auto sum = std::make_shared<int>(0);
- auto lifetimeEndCount = std::make_shared<int>(0);
- auto saved = lifetime();
- {
- make_producer<int>([=](auto &&consumer) {
- auto inner = make_producer<int>([=](auto &&consumer) {
- consumer.put_next(1);
- consumer.put_next(2);
- consumer.put_next(3);
- return [=] {
- ++*lifetimeEndCount;
- };
- });
- auto result = lifetime([=] {
- ++*lifetimeEndCount;
- });
- inner.start_copy([=](int value) {
- consumer.put_next_copy(value);
- }, [=](no_error) {
- }, [=] {
- }, result);
- std::move(inner).start([=](int value) {
- consumer.put_next_copy(value);
- }, [=](no_error) {
- }, [=] {
- }, result);
- return result;
- }).start([=](int value) {
- *sum += value;
- }, [=](no_error) {
- }, [=] {
- }, saved);
- }
- REQUIRE(*sum == 1 + 2 + 3 + 1 + 2 + 3);
- REQUIRE(*lifetimeEndCount == 0);
- saved.destroy();
- REQUIRE(*lifetimeEndCount == 3);
- }
- SECTION("tuple producer test") {
- auto result = std::make_shared<int>(0);
- {
- auto alive = make_producer<std::tuple<int, double>>([=](
- auto &&consumer) {
- consumer.put_next(std::make_tuple(1, 2.));
- return lifetime();
- }).start([=](int a, double b) {
- *result = a + int(b);
- }, [=](no_error error) {
- }, [=]() {
- });
- }
- REQUIRE(*result == 3);
- }
- }
- TEST_CASE("basic event_streams tests", "[rpl::event_stream]") {
- SECTION("event_stream basic test") {
- auto sum = std::make_shared<int>(0);
- event_stream<int> stream;
- stream.fire(1);
- stream.fire(2);
- stream.fire(3);
- {
- auto saved = lifetime();
- stream.events().start([=](int value) {
- *sum += value;
- }, [=](no_error) {
- }, [=] {
- }, saved);
- stream.fire(11);
- stream.fire(12);
- stream.fire(13);
- }
- stream.fire(21);
- stream.fire(22);
- stream.fire(23);
- REQUIRE(11 + 12 + 13);
- }
- SECTION("event_stream add in handler test") {
- auto sum = std::make_shared<int>(0);
- event_stream<int> stream;
- {
- auto composite = lifetime();
- stream.events().start([=, &stream, &composite](int value) {
- *sum += value;
- stream.events().start([=](int value) {
- *sum += value;
- }, [=](no_error) {
- }, [=] {
- }, composite);
- }, [=](no_error) {
- }, [=] {
- }, composite);
- {
- auto inner = lifetime();
- stream.events().start([=, &stream, &inner](int value) {
- *sum += value;
- stream.events().start([=](int value) {
- *sum += value;
- }, [=](no_error) {
- }, [=] {
- }, inner);
- }, [=](no_error) {
- }, [=] {
- }, inner);
- stream.fire(1);
- stream.fire(2);
- stream.fire(3);
- }
- stream.fire(11);
- stream.fire(12);
- stream.fire(13);
- }
- stream.fire(21);
- stream.fire(22);
- stream.fire(23);
- REQUIRE(*sum ==
- (1 + 1) +
- ((2 + 2) + (2 + 2)) +
- ((3 + 3 + 3) + (3 + 3 + 3)) +
- (11 + 11 + 11 + 11) +
- (12 + 12 + 12 + 12 + 12) +
- (13 + 13 + 13 + 13 + 13 + 13));
- }
- SECTION("event_stream add and remove in handler test") {
- auto sum = std::make_shared<int>(0);
- event_stream<int> stream;
- {
- auto composite = lifetime();
- stream.events().start([=, &stream, &composite](int value) {
- *sum += value;
- composite.destroy();
- stream.events().start([=](int value) {
- *sum += value;
- }, [=](no_error) {
- }, [=] {
- }, composite);
- }, [=](no_error) {
- }, [=] {
- }, composite);
- {
- auto inner = lifetime();
- stream.events().start([=, &stream, &inner](int value) {
- *sum += value;
- inner.destroy();
- stream.events().start([=](int value) {
- *sum += value;
- }, [=](no_error) {
- }, [=] {
- }, inner);
- }, [=](no_error) {
- }, [=] {
- }, inner);
- stream.fire(1);
- stream.fire(2);
- stream.fire(3);
- }
- stream.fire(11);
- stream.fire(12);
- stream.fire(13);
- }
- stream.fire(21);
- stream.fire(22);
- stream.fire(23);
- REQUIRE(*sum ==
- (1 + 1) +
- (2 + 2) +
- (3 + 3) +
- (11) +
- (12) +
- (13));
- }
- SECTION("event_stream ends before handler lifetime") {
- auto sum = std::make_shared<int>(0);
- lifetime extended;
- {
- event_stream<int> stream;
- stream.events().start([=](int value) {
- *sum += value;
- }, [=](no_error) {
- }, [=] {
- }, extended);
- stream.fire(1);
- stream.fire(2);
- stream.fire(3);
- }
- REQUIRE(*sum == 1 + 2 + 3);
- }
- SECTION("event_stream move test") {
- auto sum = std::make_shared<int>(0);
- lifetime extended;
- {
- event_stream<int> stream;
- stream.events()
- | start_with_next([=](int value) {
- *sum += value;
- }, extended);
- stream.fire(1);
- stream.fire(2);
- auto movedStream = std::move(stream);
- movedStream.fire(3);
- movedStream.fire(4);
- }
- REQUIRE(*sum == 1 + 2 + 3 + 4);
- }
- }
- TEST_CASE("basic piping tests", "[rpl::producer]") {
- SECTION("start_with_*") {
- auto sum = std::make_shared<int>(0);
- auto dones = std::make_shared<int>(0);
- {
- auto alive = lifetime();
- make_producer<int, int>([=](auto &&consumer) {
- consumer.put_next(1);
- consumer.put_done();
- return lifetime();
- }) | start_with_next([=](int value) {
- *sum += value;
- }, alive);
- make_producer<int, int>([=](auto &&consumer) {
- consumer.put_next(11);
- consumer.put_error(111);
- return lifetime();
- }) | start_with_error([=](int value) {
- *sum += value;
- }, alive);
- make_producer<int, int>([=](auto &&consumer) {
- consumer.put_next(1111);
- consumer.put_done();
- return lifetime();
- }) | start_with_done([=]() {
- *dones += 1;
- }, alive);
- make_producer<int, int>([=](auto &&consumer) {
- consumer.put_next(11111);
- consumer.put_next(11112);
- consumer.put_next(11113);
- consumer.put_error(11114);
- return lifetime();
- }) | start_with_next_error([=](int value) {
- *sum += value;
- }, [=](int value) {
- *sum += value;
- }, alive);
- }
- auto alive = lifetime();
- make_producer<int, int>([=](auto &&consumer) {
- consumer.put_next(111111);
- consumer.put_next(111112);
- consumer.put_next(111113);
- consumer.put_done();
- return lifetime();
- }) | start_with_next_done([=](int value) {
- *sum += value;
- }, [=]() {
- *dones += 11;
- }, alive);
- make_producer<int, int>([=](auto &&consumer) {
- consumer.put_error(1111111);
- return lifetime();
- }) | start_with_error_done([=](int value) {
- *sum += value;
- }, [=]() {
- *dones = 0;
- }, alive);
- make_producer<int, int>([=](auto &&consumer) {
- consumer.put_next(11111111);
- consumer.put_next(11111112);
- consumer.put_next(11111113);
- consumer.put_error(11111114);
- return lifetime();
- }) | start_with_next_error_done([=](int value) {
- *sum += value;
- }, [=](int value) {
- *sum += value;
- }, [=]() {
- *dones = 0;
- }, alive);
- REQUIRE(*sum ==
- 1 +
- 111 +
- 11111 + 11112 + 11113 + 11114 +
- 111111 + 111112 + 111113 +
- 1111111 +
- 11111111 + 11111112 + 11111113 + 11111114);
- REQUIRE(*dones == 1 + 11);
- }
- SECTION("start_with_next should copy its callback") {
- auto sum = std::make_shared<int>(0);
- {
- auto next = [=](int value) {
- REQUIRE(sum != nullptr);
- *sum += value;
- };
- for (int i = 0; i != 3; ++i) {
- auto alive = lifetime();
- make_producer<int, int>([=](auto &&consumer) {
- consumer.put_next(1);
- consumer.put_done();
- return lifetime();
- }) | start_with_next(next, alive);
- }
- }
- REQUIRE(*sum == 3);
- }
- }
|