1 #include "../test.h" 2 #include <rxcpp/operators/rx-finally.hpp> 3 4 SCENARIO("finally - never", "[finally][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 long invoked = 0; 10 11 auto xs = sc.make_hot_observable({ 12 on.next(150, 1) 13 }); 14 15 WHEN("finally action is set"){ 16 17 auto res = w.start( __anon3b3dc5f90102() 18 [xs, &invoked]() { 19 return xs 20 | rxo::finally([&invoked]() { 21 ++invoked; 22 }) 23 // forget type to workaround lambda deduction bug on msvc 2013 24 | rxo::as_dynamic(); 25 } 26 ); 27 28 THEN("finally called once"){ 29 REQUIRE(1 == invoked); 30 } 31 32 THEN("the output is empty"){ 33 auto required = std::vector<rxsc::test::messages<int>::recorded_type>(); 34 auto actual = res.get_observer().messages(); 35 REQUIRE(required == actual); 36 } 37 38 THEN("there was 1 subscription/unsubscription to the source"){ 39 auto required = rxu::to_vector({ 40 on.subscribe(200, 1000) 41 }); 42 auto actual = xs.subscriptions(); 43 REQUIRE(required == actual); 44 } 45 } 46 } 47 } 48 49 SCENARIO("finally - empty", "[finally][operators]"){ 50 GIVEN("a source"){ 51 auto sc = rxsc::make_test(); 52 auto w = sc.create_worker(); 53 const rxsc::test::messages<int> on; 54 long invoked = 0; 55 56 auto xs = sc.make_hot_observable({ 57 on.next(150, 1), 58 on.completed(250) 59 }); 60 61 WHEN("finally action is set"){ 62 63 auto res = w.start( __anon3b3dc5f90302() 64 [xs, &invoked]() { 65 return xs 66 .finally([&invoked]() { 67 ++invoked; 68 }) 69 // forget type to workaround lambda deduction bug on msvc 2013 70 .as_dynamic(); 71 } 72 ); 73 74 THEN("finally called once"){ 75 REQUIRE(1 == invoked); 76 } 77 78 THEN("the output only contains complete message"){ 79 auto required = rxu::to_vector({ 80 on.completed(250) 81 }); 82 auto actual = res.get_observer().messages(); 83 REQUIRE(required == actual); 84 } 85 86 THEN("there was 1 subscription/unsubscription to the source"){ 87 auto required = rxu::to_vector({ 88 on.subscribe(200, 250) 89 }); 90 auto actual = xs.subscriptions(); 91 REQUIRE(required == actual); 92 } 93 94 } 95 } 96 } 97 98 SCENARIO("finally - items emitted", "[finally][operators]"){ 99 GIVEN("a source"){ 100 auto sc = rxsc::make_test(); 101 auto w = sc.create_worker(); 102 const rxsc::test::messages<int> on; 103 long invoked = 0; 104 105 auto xs = sc.make_hot_observable({ 106 on.next(150, 1), 107 on.next(210, 2), 108 on.next(240, 3), 109 on.completed(300) 110 }); 111 112 WHEN("finally action is set"){ 113 114 auto res = w.start( __anon3b3dc5f90502() 115 [xs, &invoked]() { 116 return xs 117 .finally([&invoked]() { 118 ++invoked; 119 }) 120 // forget type to workaround lambda deduction bug on msvc 2013 121 .as_dynamic(); 122 } 123 ); 124 125 THEN("finally called once"){ 126 REQUIRE(1 == invoked); 127 } 128 129 THEN("the output only contains items sent while subscribed"){ 130 auto required = rxu::to_vector({ 131 on.next(210, 2), 132 on.next(240, 3), 133 on.completed(300) 134 }); 135 auto actual = res.get_observer().messages(); 136 REQUIRE(required == actual); 137 } 138 139 THEN("there was 1 subscription/unsubscription to the source"){ 140 auto required = rxu::to_vector({ 141 on.subscribe(200, 300) 142 }); 143 auto actual = xs.subscriptions(); 144 REQUIRE(required == actual); 145 } 146 147 } 148 } 149 } 150 151 SCENARIO("finally - throw", "[finally][operators]"){ 152 GIVEN("a source"){ 153 auto sc = rxsc::make_test(); 154 auto w = sc.create_worker(); 155 const rxsc::test::messages<int> on; 156 long invoked = 0; 157 158 std::runtime_error ex("finally on_error from source"); 159 160 auto xs = sc.make_hot_observable({ 161 on.next(150, 1), 162 on.error(250, ex) 163 }); 164 165 WHEN("finally action is set"){ 166 167 auto res = w.start( __anon3b3dc5f90702() 168 [xs, &invoked]() { 169 return xs 170 .finally([&invoked]() { 171 ++invoked; 172 }) 173 // forget type to workaround lambda deduction bug on msvc 2013 174 .as_dynamic(); 175 } 176 ); 177 178 THEN("finally called once"){ 179 REQUIRE(1 == invoked); 180 } 181 182 THEN("the output only contains only error"){ 183 auto required = rxu::to_vector({ 184 on.error(250, ex) 185 }); 186 auto actual = res.get_observer().messages(); 187 REQUIRE(required == actual); 188 } 189 190 THEN("there was 1 subscription/unsubscription to the source"){ 191 auto required = rxu::to_vector({ 192 on.subscribe(200, 250) 193 }); 194 auto actual = xs.subscriptions(); 195 REQUIRE(required == actual); 196 } 197 198 } 199 } 200 } 201