1 #include "../test.h"
2 #include "rxcpp/operators/rx-retry.hpp"
3 
4 SCENARIO("retry, basic test", "[retry][operators]") {
5     GIVEN("hot observable of 3x4x7 ints with errors inbetween the groups. Infinite retry.") {
6         auto sc = rxsc::make_test();
7         auto w = sc.create_worker();
8         const rxsc::test::messages<int> on;
9         std::runtime_error ex("retry on_error from source");
10 
11         auto xs = sc.make_hot_observable({
12             on.next(300, 1),
13             on.next(325, 2),
14             on.next(350, 3),
15             on.error(400, ex),
16             on.next(425, 1),
17             on.next(450, 2),
18             on.next(475, 3),
19             on.next(500, 4),
20             on.error(525, ex),
21             on.next(550, 1),
22             on.next(575, 2),
23             on.next(600, 3),
24             on.next(625, 4),
25             on.next(650, 5),
26             on.next(675, 6),
27             on.next(700, 7),
28             on.completed(725)
29         });
30 
31         WHEN("infinite retry is launched") {
32 
33             auto res = w.start(
__anon691f1ea00102() 34                 [&]() {
35                 return xs
36                     | rxo::retry()
37                     // forget type to workaround lambda deduction bug on msvc 2013
38                     | rxo::as_dynamic();
39             }
40             );
41 
42             THEN("the output contains all the data until complete") {
43                 auto required = rxu::to_vector({
44                     on.next(300, 1),
45                     on.next(325, 2),
46                     on.next(350, 3),
47                     on.next(425, 1),
48                     on.next(450, 2),
49                     on.next(475, 3),
50                     on.next(500, 4),
51                     on.next(550, 1),
52                     on.next(575, 2),
53                     on.next(600, 3),
54                     on.next(625, 4),
55                     on.next(650, 5),
56                     on.next(675, 6),
57                     on.next(700, 7),
58                     on.completed(725)
59                 });
60                 auto actual = res.get_observer().messages();
61                 REQUIRE(required == actual);
62             }
63 
64             THEN("there were 3 subscriptions and 3 unsubscriptions to the ints") {
65                 auto required = rxu::to_vector({
66                     on.subscribe(200, 400),
67                     on.subscribe(400, 525),
68                     on.subscribe(525, 725)
69                 });
70                 auto actual = xs.subscriptions();
71                 REQUIRE(required == actual);
72             }
73         }
74     }
75 }
76 
77 SCENARIO("retry 0, basic test", "[retry][operators]") {
78   GIVEN("hot observable of 3 ints. Infinite retry.") {
79     auto sc = rxsc::make_test();
80     auto w = sc.create_worker();
81     const rxsc::test::messages<int> on;
82     std::runtime_error ex("retry on_error from source");
83 
84     auto xs = sc.make_hot_observable({
85         on.next(100, 1),
86           on.next(150, 2),
87           on.next(200, 3),
88           });;
89 
90     WHEN("retry is invoked with 0 times as argument") {
91 
92       auto res = w.start(
__anon691f1ea00202() 93                          [&]() {
94                            return xs
95                            | rxo::retry(0)
96                            // forget type to workaround lambda deduction bug on msvc 2013
97                            | rxo::as_dynamic();
98                          }
99                          );
100 
101       THEN("the output should be empty"){
102         auto required = rxu::to_vector({
103             on.completed(200)
104               });
105         auto actual = res.get_observer().messages();
106         REQUIRE(required == actual);
107       }
108 
109       THEN("no subscriptions in retry(0)"){
110         auto required = std::vector<rxcpp::notifications::subscription>();
111         auto actual = xs.subscriptions();
112         REQUIRE(required == actual);
113       }
114 
115     }
116 
117   }
118 }
119 
120 
121 SCENARIO("retry with failure", "[retry][operators]") {
122     GIVEN("hot observable of 3x4x7 ints with errors inbetween the groups. Retry 2. Must fail.") {
123         auto sc = rxsc::make_test();
124         auto w = sc.create_worker();
125         const rxsc::test::messages<int> on;
126         std::runtime_error ex("retry on_error from source");
127 
128         auto xs = sc.make_hot_observable({
129             on.next(300, 1),
130             on.next(325, 2),
131             on.next(350, 3),
132             on.error(400, ex),
133             on.next(425, 1),
134             on.next(450, 2),
135             on.next(475, 3),
136             on.next(500, 4),
137             on.error(525, ex),
138             on.next(550, 1),
139             on.next(575, 2),
140             on.next(600, 3),
141             on.next(625, 4),
142             on.next(650, 5),
143             on.next(675, 6),
144             on.next(700, 7),
145             on.completed(725)
146         });
147 
148         WHEN("retry of 2 is launched with expected error before complete") {
149 
150             auto res = w.start(
__anon691f1ea00302() 151                 [&]() {
152                 return xs
153                     .retry(2)
154                     // forget type to workaround lambda deduction bug on msvc 2013
155                     .as_dynamic();
156             });
157 
158             THEN("The output contains all the data until retry fails") {
159                 auto required = rxu::to_vector({
160                     on.next(300, 1),
161                     on.next(325, 2),
162                     on.next(350, 3),
163                     on.next(425, 1),
164                     on.next(450, 2),
165                     on.next(475, 3),
166                     on.next(500, 4),
167                     on.error(525, ex),
168                 });
169                 auto actual = res.get_observer().messages();
170                 REQUIRE(actual == required);
171             }
172 
173             THEN("There were 2 subscriptions and 2 unsubscriptions to the ints") {
174                 auto required = rxu::to_vector({
175                     on.subscribe(200, 400),
176                     on.subscribe(400, 525)
177                 });
178                 auto actual = xs.subscriptions();
179                 REQUIRE(required == actual);
180             }
181         }
182     }
183 }
184 
185 
186