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