1 #include "../test.h" 2 #include <rxcpp/operators/rx-switch_if_empty.hpp> 3 4 SCENARIO("switch_if_empty should not switch if the source is not empty", "[switch_if_empty][operators]"){ 5 GIVEN("a source"){ 6 auto sc = rxsc::make_test(); 7 auto w = sc.create_worker(); 8 const rxsc::test::messages<int> on; 9 10 auto ys = sc.make_cold_observable({ 11 on.next(10, 2), 12 on.completed(230) 13 }); 14 15 auto xs = sc.make_hot_observable({ 16 on.next(210, 1), 17 on.completed(250) 18 }); 19 20 WHEN("started"){ 21 22 auto res = w.start( __anonea71d4810102() 23 [xs, ys]() { 24 return xs 25 | rxo::switch_if_empty(ys) 26 // forget type to workaround lambda deduction bug on msvc 2013 27 | rxo::as_dynamic(); 28 } 29 ); 30 31 THEN("the output only contains an item from the source") { 32 auto required = rxu::to_vector({ 33 on.next(210, 1), 34 on.completed(250) 35 }); 36 auto actual = res.get_observer().messages(); 37 REQUIRE(required == actual); 38 } 39 40 THEN("there was 1 subscription/unsubscription to the source"){ 41 auto required = rxu::to_vector({ 42 on.subscribe(200, 250) 43 }); 44 auto actual = xs.subscriptions(); 45 REQUIRE(required == actual); 46 } 47 48 THEN("there was no subscription/unsubscription to ys"){ 49 auto required = std::vector<rxn::subscription>(); 50 auto actual = ys.subscriptions(); 51 REQUIRE(required == actual); 52 } 53 } 54 } 55 } 56 57 SCENARIO("switch_if_empty should switch if the source is empty", "[switch_if_empty][operators]"){ 58 GIVEN("a source"){ 59 auto sc = rxsc::make_test(); 60 auto w = sc.create_worker(); 61 const rxsc::test::messages<int> on; 62 63 auto ys = sc.make_cold_observable({ 64 on.next(10, 2), 65 on.completed(20) 66 }); 67 68 auto xs = sc.make_hot_observable({ 69 on.next(150, 1), 70 on.completed(250) 71 }); 72 73 WHEN("started"){ 74 75 auto res = w.start( __anonea71d4810202() 76 [xs, ys]() { 77 return xs 78 .switch_if_empty(ys) 79 // forget type to workaround lambda deduction bug on msvc 2013 80 .as_dynamic(); 81 } 82 ); 83 84 THEN("the output only contains an item from the backup source") { 85 auto required = rxu::to_vector({ 86 on.next(260, 2), 87 on.completed(270) 88 }); 89 auto actual = res.get_observer().messages(); 90 REQUIRE(required == actual); 91 } 92 93 THEN("there was 1 subscription/unsubscription to the source"){ 94 auto required = rxu::to_vector({ 95 on.subscribe(200, 250) 96 }); 97 auto actual = xs.subscriptions(); 98 REQUIRE(required == actual); 99 } 100 101 THEN("there was 1 subscription/unsubscription to ys"){ 102 auto required = rxu::to_vector({ 103 on.subscribe(250, 270) 104 }); 105 auto actual = ys.subscriptions(); 106 REQUIRE(required == actual); 107 } 108 } 109 } 110 } 111 112 SCENARIO("switch_if_empty - never", "[switch_if_empty][operators]"){ 113 GIVEN("a source"){ 114 auto sc = rxsc::make_test(); 115 auto w = sc.create_worker(); 116 const rxsc::test::messages<int> on; 117 118 auto ys = sc.make_cold_observable({ 119 on.next(10, 2), 120 on.completed(20) 121 }); 122 123 auto xs = sc.make_hot_observable({ 124 on.next(150, 1) 125 }); 126 127 WHEN("started"){ 128 129 auto res = w.start( __anonea71d4810302() 130 [xs, ys]() { 131 return xs 132 .switch_if_empty(ys) 133 // forget type to workaround lambda deduction bug on msvc 2013 134 .as_dynamic(); 135 } 136 ); 137 138 THEN("the output is empty"){ 139 auto required = std::vector<rxsc::test::messages<int>::recorded_type>(); 140 auto actual = res.get_observer().messages(); 141 REQUIRE(required == actual); 142 } 143 144 THEN("there was 1 subscription/unsubscription to the source"){ 145 auto required = rxu::to_vector({ 146 on.subscribe(200, 1000) 147 }); 148 auto actual = xs.subscriptions(); 149 REQUIRE(required == actual); 150 } 151 152 THEN("there was no subscription/unsubscription to ys"){ 153 auto required = std::vector<rxn::subscription>(); 154 auto actual = ys.subscriptions(); 155 REQUIRE(required == actual); 156 } 157 } 158 } 159 } 160 161 SCENARIO("switch_if_empty - source throws", "[switch_if_empty][operators]"){ 162 GIVEN("a source"){ 163 auto sc = rxsc::make_test(); 164 auto w = sc.create_worker(); 165 const rxsc::test::messages<int> on; 166 167 std::runtime_error ex("switch_if_empty on_error from source"); 168 169 auto ys = sc.make_cold_observable({ 170 on.next(10, 2), 171 on.completed(20) 172 }); 173 174 auto xs = sc.make_hot_observable({ 175 on.next(150, 1), 176 on.error(250, ex) 177 }); 178 179 WHEN("started"){ 180 181 auto res = w.start( __anonea71d4810402() 182 [xs, ys]() { 183 return xs 184 .switch_if_empty(ys) 185 // forget type to workaround lambda deduction bug on msvc 2013 186 .as_dynamic(); 187 } 188 ); 189 190 THEN("the output only contains an error from the source"){ 191 auto required = rxu::to_vector({ 192 on.error(250, ex) 193 }); 194 auto actual = res.get_observer().messages(); 195 REQUIRE(required == actual); 196 } 197 198 THEN("there was 1 subscription/unsubscription to the source"){ 199 auto required = rxu::to_vector({ 200 on.subscribe(200, 250) 201 }); 202 auto actual = xs.subscriptions(); 203 REQUIRE(required == actual); 204 } 205 206 THEN("there was no subscription/unsubscription to ys"){ 207 auto required = std::vector<rxn::subscription>(); 208 auto actual = ys.subscriptions(); 209 REQUIRE(required == actual); 210 } 211 } 212 } 213 } 214 215 SCENARIO("switch_if_empty - backup source throws", "[switch_if_empty][operators]"){ 216 GIVEN("a source"){ 217 auto sc = rxsc::make_test(); 218 auto w = sc.create_worker(); 219 const rxsc::test::messages<int> on; 220 221 std::runtime_error ex("switch_if_empty on_error from backup source"); 222 223 auto ys = sc.make_cold_observable({ 224 on.error(10, ex) 225 }); 226 227 auto xs = sc.make_hot_observable({ 228 on.next(150, 1), 229 on.completed(250) 230 }); 231 232 WHEN("started"){ 233 234 auto res = w.start( __anonea71d4810502() 235 [xs, ys]() { 236 return xs 237 .switch_if_empty(ys) 238 // forget type to workaround lambda deduction bug on msvc 2013 239 .as_dynamic(); 240 } 241 ); 242 243 THEN("the output only contains an error from the backup source"){ 244 auto required = rxu::to_vector({ 245 on.error(260, ex) 246 }); 247 auto actual = res.get_observer().messages(); 248 REQUIRE(required == actual); 249 } 250 251 THEN("there was 1 subscription/unsubscription to the source"){ 252 auto required = rxu::to_vector({ 253 on.subscribe(200, 250) 254 }); 255 auto actual = xs.subscriptions(); 256 REQUIRE(required == actual); 257 } 258 259 THEN("there was 1 subscription/unsubscription to ys"){ 260 auto required = rxu::to_vector({ 261 on.subscribe(250, 260) 262 }); 263 auto actual = ys.subscriptions(); 264 REQUIRE(required == actual); 265 } 266 } 267 } 268 } 269