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