summaryrefslogtreecommitdiff
path: root/Rx/v2/test
diff options
context:
space:
mode:
authorKirk Shoop <kirk.shoop@microsoft.com>2017-02-01 08:58:39 -0800
committerGrigoriy Chudnov <g.chudnov@gmail.com>2017-02-03 09:08:56 +0300
commit6245a18869836ef29f9116808435cefac0eebcb7 (patch)
tree7c42f28dfc2df14930bc11d97fcb5324f3c45ee3 /Rx/v2/test
parent07d5e235baabc841d01bfeac6d4476deda0a1bb0 (diff)
downloadRxCpp-6245a18869836ef29f9116808435cefac0eebcb7.tar.gz
move sources docs out of observable
shift tests to include aliases
Diffstat (limited to 'Rx/v2/test')
-rw-r--r--Rx/v2/test/operators/concat_map.cpp116
-rw-r--r--Rx/v2/test/operators/flat_map.cpp134
-rw-r--r--Rx/v2/test/operators/on_error_resume_next.cpp71
-rw-r--r--Rx/v2/test/operators/reduce.cpp55
4 files changed, 329 insertions, 47 deletions
diff --git a/Rx/v2/test/operators/concat_map.cpp b/Rx/v2/test/operators/concat_map.cpp
index 0a3ee6b..e6551d6 100644
--- a/Rx/v2/test/operators/concat_map.cpp
+++ b/Rx/v2/test/operators/concat_map.cpp
@@ -8,7 +8,7 @@
static const int static_tripletCount = 100;
-SCENARIO("concat_map pythagorian ranges", "[hide][range][concat_map][pythagorian][perf]"){
+SCENARIO("concat_transform pythagorian ranges", "[hide][range][concat_transform][pythagorian][perf]"){
const int& tripletCount = static_tripletCount;
GIVEN("some ranges"){
WHEN("generating pythagorian triplets"){
@@ -25,14 +25,14 @@ SCENARIO("concat_map pythagorian ranges", "[hide][range][concat_map][pythagorian
auto start = clock::now();
auto triples =
rxs::range(1, so)
- .concat_map(
+ .concat_transform(
[&c, so](int z){
return rxs::range(1, z, 1, so)
- .concat_map(
+ .concat_transform(
[&c, so, z](int x){
return rxs::range(x, z, 1, so)
.filter([&c, z, x](int y){++c; return x*x + y*y == z*z;})
- .map([z, x](int y){return std::make_tuple(x, y, z);})
+ .transform([z, x](int y){return std::make_tuple(x, y, z);})
// forget type to workaround lambda deduction bug on msvc 2013
.as_dynamic();},
[](int /*x*/, std::tuple<int,int,int> triplet){return triplet;})
@@ -53,7 +53,7 @@ SCENARIO("concat_map pythagorian ranges", "[hide][range][concat_map][pythagorian
}
}
-SCENARIO("synchronize concat_map pythagorian ranges", "[hide][range][concat_map][synchronize][pythagorian][perf]"){
+SCENARIO("synchronize concat_transform pythagorian ranges", "[hide][range][concat_transform][synchronize][pythagorian][perf]"){
const int& tripletCount = static_tripletCount;
GIVEN("some ranges"){
WHEN("generating pythagorian triplets"){
@@ -67,10 +67,10 @@ SCENARIO("synchronize concat_map pythagorian ranges", "[hide][range][concat_map]
auto start = clock::now();
auto triples =
rxs::range(1, so)
- .concat_map(
+ .concat_transform(
[&c, so](int z){
return rxs::range(1, z, 1, so)
- .concat_map(
+ .concat_transform(
[&c, so, z](int x){
return rxs::range(x, z, 1, so)
.filter([&c, z, x](int y){
@@ -79,7 +79,7 @@ SCENARIO("synchronize concat_map pythagorian ranges", "[hide][range][concat_map]
return true;}
else {
return false;}})
- .map([z, x](int y){return std::make_tuple(x, y, z);})
+ .transform([z, x](int y){return std::make_tuple(x, y, z);})
// forget type to workaround lambda deduction bug on msvc 2013
.as_dynamic();},
[](int /*x*/, std::tuple<int,int,int> triplet){return triplet;},
@@ -101,7 +101,7 @@ SCENARIO("synchronize concat_map pythagorian ranges", "[hide][range][concat_map]
}
}
-SCENARIO("observe_on concat_map pythagorian ranges", "[hide][range][concat_map][observe_on][pythagorian][perf]"){
+SCENARIO("observe_on concat_transform pythagorian ranges", "[hide][range][concat_transform][observe_on][pythagorian][perf]"){
const int& tripletCount = static_tripletCount;
GIVEN("some ranges"){
WHEN("generating pythagorian triplets"){
@@ -115,10 +115,10 @@ SCENARIO("observe_on concat_map pythagorian ranges", "[hide][range][concat_map][
auto start = clock::now();
auto triples =
rxs::range(1, so)
- .concat_map(
+ .concat_transform(
[&c, so](int z){
return rxs::range(1, z, 1, so)
- .concat_map(
+ .concat_transform(
[&c, so, z](int x){
return rxs::range(x, z, 1, so)
.filter([&c, z, x](int y){
@@ -127,7 +127,7 @@ SCENARIO("observe_on concat_map pythagorian ranges", "[hide][range][concat_map][
return true;}
else {
return false;}})
- .map([z, x](int y){return std::make_tuple(x, y, z);})
+ .transform([z, x](int y){return std::make_tuple(x, y, z);})
// forget type to workaround lambda deduction bug on msvc 2013
.as_dynamic();},
[](int /*x*/, std::tuple<int,int,int> triplet){return triplet;},
@@ -150,7 +150,7 @@ SCENARIO("observe_on concat_map pythagorian ranges", "[hide][range][concat_map][
}
}
-SCENARIO("serialize concat_map pythagorian ranges", "[hide][range][concat_map][serialize][pythagorian][perf]"){
+SCENARIO("serialize concat_transform pythagorian ranges", "[hide][range][concat_transform][serialize][pythagorian][perf]"){
const int& tripletCount = static_tripletCount;
GIVEN("some ranges"){
WHEN("generating pythagorian triplets"){
@@ -164,10 +164,10 @@ SCENARIO("serialize concat_map pythagorian ranges", "[hide][range][concat_map][s
auto start = clock::now();
auto triples =
rxs::range(1, so)
- .concat_map(
+ .concat_transform(
[&c, so](int z){
return rxs::range(1, z, 1, so)
- .concat_map(
+ .concat_transform(
[&c, so, z](int x){
return rxs::range(x, z, 1, so)
.filter([&c, z, x](int y){
@@ -176,7 +176,7 @@ SCENARIO("serialize concat_map pythagorian ranges", "[hide][range][concat_map][s
return true;}
else {
return false;}})
- .map([z, x](int y){return std::make_tuple(x, y, z);})
+ .transform([z, x](int y){return std::make_tuple(x, y, z);})
// forget type to workaround lambda deduction bug on msvc 2013
.as_dynamic();},
[](int /*x*/, std::tuple<int,int,int> triplet){return triplet;},
@@ -199,7 +199,7 @@ SCENARIO("serialize concat_map pythagorian ranges", "[hide][range][concat_map][s
}
}
-SCENARIO("concat_map completes", "[concat_map][map][operators]"){
+SCENARIO("concat_map completes", "[concat_map][transform][map][operators]"){
GIVEN("two cold observables. one of ints. one of strings."){
auto sc = rxsc::make_test();
auto w = sc.create_worker();
@@ -268,13 +268,85 @@ SCENARIO("concat_map completes", "[concat_map][map][operators]"){
REQUIRE(required == actual);
}
}
+ }
+}
+
+SCENARIO("concat_transform completes", "[concat_transform][transform][map][operators]"){
+ GIVEN("two cold observables. one of ints. one of strings."){
+ auto sc = rxsc::make_test();
+ auto w = sc.create_worker();
+ const rxsc::test::messages<int> i_on;
+ const rxsc::test::messages<std::string> s_on;
+
+ auto xs = sc.make_cold_observable({
+ i_on.next(100, 4),
+ i_on.next(200, 2),
+ i_on.completed(500)
+ });
+
+ auto ys = sc.make_cold_observable({
+ s_on.next(50, "foo"),
+ s_on.next(100, "bar"),
+ s_on.next(150, "baz"),
+ s_on.next(200, "qux"),
+ s_on.completed(250)
+ });
+
+ WHEN("each int is mapped to the strings"){
+
+ auto res = w.start(
+ [&]() {
+ return xs
+ | rxo::concat_transform(
+ [&](int){
+ return ys;},
+ [](int, std::string s){
+ return s;})
+ // forget type to workaround lambda deduction bug on msvc 2013
+ | rxo::as_dynamic();
+ }
+ );
+
+ THEN("the output contains strings repeated for each int"){
+ auto required = rxu::to_vector({
+ s_on.next(350, "foo"),
+ s_on.next(400, "bar"),
+ s_on.next(450, "baz"),
+ s_on.next(500, "qux"),
+ s_on.next(600, "foo"),
+ s_on.next(650, "bar"),
+ s_on.next(700, "baz"),
+ s_on.next(750, "qux"),
+ s_on.completed(800)
+ });
+ auto actual = res.get_observer().messages();
+ REQUIRE(required == actual);
+ }
+
+ THEN("there was one subscription and one unsubscription to the ints"){
+ auto required = rxu::to_vector({
+ i_on.subscribe(200, 700)
+ });
+ auto actual = xs.subscriptions();
+ REQUIRE(required == actual);
+ }
+
+ THEN("there were 2 subscription and unsubscription to the strings"){
+ auto required = rxu::to_vector({
+ s_on.subscribe(300, 550),
+ s_on.subscribe(550, 800)
+ });
+ auto actual = ys.subscriptions();
+ REQUIRE(required == actual);
+ }
+ }
WHEN("each int is mapped to the strings with coordinator"){
auto res = w.start(
[&]() {
return xs
- .concat_map(
+ .concat_transform(
[&](int){
return ys;},
[](int, std::string s){
@@ -321,7 +393,7 @@ SCENARIO("concat_map completes", "[concat_map][map][operators]"){
}
}
-SCENARIO("concat_map, no result selector, no coordination", "[concat_map][map][operators]"){
+SCENARIO("concat_transform, no result selector, no coordination", "[concat_transform][transform][map][operators]"){
GIVEN("two cold observables. one of ints. one of strings."){
auto sc = rxsc::make_test();
auto w = sc.create_worker();
@@ -347,7 +419,7 @@ SCENARIO("concat_map, no result selector, no coordination", "[concat_map][map][o
auto res = w.start(
[&]() {
return xs
- .concat_map(
+ .concat_transform(
[&](int){
return ys;})
// forget type to workaround lambda deduction bug on msvc 2013
@@ -391,7 +463,7 @@ SCENARIO("concat_map, no result selector, no coordination", "[concat_map][map][o
}
}
-SCENARIO("concat_map, no result selector, with coordination", "[concat_map][map][operators]"){
+SCENARIO("concat_transform, no result selector, with coordination", "[concat_transform][transform][map][operators]"){
GIVEN("two cold observables. one of ints. one of strings."){
auto sc = rxsc::make_test();
auto w = sc.create_worker();
@@ -417,7 +489,7 @@ SCENARIO("concat_map, no result selector, with coordination", "[concat_map][map]
auto res = w.start(
[&]() {
return xs
- .concat_map(
+ .concat_transform(
[&](int){
return ys;},
rx::identity_current_thread())
diff --git a/Rx/v2/test/operators/flat_map.cpp b/Rx/v2/test/operators/flat_map.cpp
index e2e3cf8..2e01a30 100644
--- a/Rx/v2/test/operators/flat_map.cpp
+++ b/Rx/v2/test/operators/flat_map.cpp
@@ -45,7 +45,7 @@ SCENARIO("pythagorian for loops", "[hide][for][pythagorian][perf]"){
}
}
-SCENARIO("flat_map pythagorian ranges", "[hide][range][flat_map][pythagorian][perf]"){
+SCENARIO("merge_transform pythagorian ranges", "[hide][range][merge_transform][pythagorian][perf]"){
const int& tripletCount = static_tripletCount;
GIVEN("some ranges"){
WHEN("generating pythagorian triplets"){
@@ -60,14 +60,14 @@ SCENARIO("flat_map pythagorian ranges", "[hide][range][flat_map][pythagorian][pe
auto start = clock::now();
auto triples =
rxs::range(1, so)
- .flat_map(
+ .merge_transform(
[&c, so](int z){
return rxs::range(1, z, 1, so)
.flat_map(
[&c, so, z](int x){
return rxs::range(x, z, 1, so)
.filter([&c, z, x](int y){++c; return x*x + y*y == z*z;})
- .map([z, x](int y){return std::make_tuple(x, y, z);})
+ .transform([z, x](int y){return std::make_tuple(x, y, z);})
// forget type to workaround lambda deduction bug on msvc 2013
.as_dynamic();},
[](int /*x*/, std::tuple<int,int,int> triplet){return triplet;})
@@ -89,7 +89,7 @@ SCENARIO("flat_map pythagorian ranges", "[hide][range][flat_map][pythagorian][pe
}
}
-SCENARIO("synchronize flat_map pythagorian ranges", "[hide][range][flat_map][synchronize][pythagorian][perf]"){
+SCENARIO("synchronize merge_transform pythagorian ranges", "[hide][range][merge_transform][synchronize][pythagorian][perf]"){
const int& tripletCount = static_tripletCount;
GIVEN("some ranges"){
WHEN("generating pythagorian triplets"){
@@ -103,10 +103,10 @@ SCENARIO("synchronize flat_map pythagorian ranges", "[hide][range][flat_map][syn
auto start = clock::now();
auto triples =
rxs::range(1, so)
- .flat_map(
+ .merge_transform(
[&c, so](int z){
return rxs::range(1, z, 1, so)
- .flat_map(
+ .merge_transform(
[&c, so, z](int x){
return rxs::range(x, z, 1, so)
.filter([&c, z, x](int y){
@@ -115,7 +115,7 @@ SCENARIO("synchronize flat_map pythagorian ranges", "[hide][range][flat_map][syn
return true;}
else {
return false;}})
- .map([z, x](int y){return std::make_tuple(x, y, z);})
+ .transform([z, x](int y){return std::make_tuple(x, y, z);})
// forget type to workaround lambda deduction bug on msvc 2013
.as_dynamic();},
[](int /*x*/, std::tuple<int,int,int> triplet){return triplet;},
@@ -137,7 +137,7 @@ SCENARIO("synchronize flat_map pythagorian ranges", "[hide][range][flat_map][syn
}
}
-SCENARIO("observe_on flat_map pythagorian ranges", "[hide][range][flat_map][observe_on][pythagorian][perf]"){
+SCENARIO("observe_on merge_transform pythagorian ranges", "[hide][range][merge_transform][observe_on][pythagorian][perf]"){
const int& tripletCount = static_tripletCount;
GIVEN("some ranges"){
WHEN("generating pythagorian triplets"){
@@ -151,10 +151,10 @@ SCENARIO("observe_on flat_map pythagorian ranges", "[hide][range][flat_map][obse
auto start = clock::now();
auto triples =
rxs::range(1, so)
- .flat_map(
+ .merge_transform(
[&c, so](int z){
return rxs::range(1, z, 1, so)
- .flat_map(
+ .merge_transform(
[&c, so, z](int x){
return rxs::range(x, z, 1, so)
.filter([&c, z, x](int y){
@@ -163,7 +163,7 @@ SCENARIO("observe_on flat_map pythagorian ranges", "[hide][range][flat_map][obse
return true;}
else {
return false;}})
- .map([z, x](int y){return std::make_tuple(x, y, z);})
+ .transform([z, x](int y){return std::make_tuple(x, y, z);})
// forget type to workaround lambda deduction bug on msvc 2013
.as_dynamic();},
[](int /*x*/, std::tuple<int,int,int> triplet){return triplet;},
@@ -185,7 +185,7 @@ SCENARIO("observe_on flat_map pythagorian ranges", "[hide][range][flat_map][obse
}
}
-SCENARIO("serialize flat_map pythagorian ranges", "[hide][range][flat_map][serialize][pythagorian][perf]"){
+SCENARIO("serialize merge_transform pythagorian ranges", "[hide][range][merge_transform][serialize][pythagorian][perf]"){
const int& tripletCount = static_tripletCount;
GIVEN("some ranges"){
WHEN("generating pythagorian triplets"){
@@ -199,10 +199,10 @@ SCENARIO("serialize flat_map pythagorian ranges", "[hide][range][flat_map][seria
auto start = clock::now();
auto triples =
rxs::range(1, so)
- .flat_map(
+ .merge_transform(
[&c, so](int z){
return rxs::range(1, z, 1, so)
- .flat_map(
+ .merge_transform(
[&c, so, z](int x){
return rxs::range(x, z, 1, so)
.filter([&c, z, x](int y){
@@ -211,7 +211,7 @@ SCENARIO("serialize flat_map pythagorian ranges", "[hide][range][flat_map][seria
return true;}
else {
return false;}})
- .map([z, x](int y){return std::make_tuple(x, y, z);})
+ .transform([z, x](int y){return std::make_tuple(x, y, z);})
// forget type to workaround lambda deduction bug on msvc 2013
.as_dynamic();},
[](int /*x*/, std::tuple<int,int,int> triplet){return triplet;},
@@ -314,13 +314,97 @@ SCENARIO("flat_map completes", "[flat_map][map][operators]"){
REQUIRE(required == actual);
}
}
+ }
+}
+
+SCENARIO("merge_transform completes", "[merge_transform][transform][map][operators]"){
+ GIVEN("two cold observables. one of ints. one of strings."){
+ auto sc = rxsc::make_test();
+ auto w = sc.create_worker();
+ const rxsc::test::messages<int> i_on;
+ const rxsc::test::messages<std::string> s_on;
+
+ auto xs = sc.make_cold_observable({
+ i_on.next(100, 4),
+ i_on.next(200, 2),
+ i_on.next(300, 3),
+ i_on.next(400, 1),
+ i_on.completed(500)
+ });
+
+ auto ys = sc.make_cold_observable({
+ s_on.next(50, "foo"),
+ s_on.next(100, "bar"),
+ s_on.next(150, "baz"),
+ s_on.next(200, "qux"),
+ s_on.completed(250)
+ });
+
+ WHEN("each int is mapped to the strings"){
+
+ auto res = w.start(
+ [&]() {
+ return xs
+ | rxo::merge_transform(
+ [&](int){
+ return ys;},
+ [](int, std::string s){
+ return s;})
+ // forget type to workaround lambda deduction bug on msvc 2013
+ | rxo::as_dynamic();
+ }
+ );
+
+ THEN("the output contains strings repeated for each int"){
+ auto required = rxu::to_vector({
+ s_on.next(350, "foo"),
+ s_on.next(400, "bar"),
+ s_on.next(450, "baz"),
+ s_on.next(450, "foo"),
+ s_on.next(500, "qux"),
+ s_on.next(500, "bar"),
+ s_on.next(550, "baz"),
+ s_on.next(550, "foo"),
+ s_on.next(600, "qux"),
+ s_on.next(600, "bar"),
+ s_on.next(650, "baz"),
+ s_on.next(650, "foo"),
+ s_on.next(700, "qux"),
+ s_on.next(700, "bar"),
+ s_on.next(750, "baz"),
+ s_on.next(800, "qux"),
+ s_on.completed(850)
+ });
+ auto actual = res.get_observer().messages();
+ REQUIRE(required == actual);
+ }
+
+ THEN("there was one subscription and one unsubscription to the ints"){
+ auto required = rxu::to_vector({
+ i_on.subscribe(200, 700)
+ });
+ auto actual = xs.subscriptions();
+ REQUIRE(required == actual);
+ }
+
+ THEN("there were four subscription and unsubscription to the strings"){
+ auto required = rxu::to_vector({
+ s_on.subscribe(300, 550),
+ s_on.subscribe(400, 650),
+ s_on.subscribe(500, 750),
+ s_on.subscribe(600, 850)
+ });
+ auto actual = ys.subscriptions();
+ REQUIRE(required == actual);
+ }
+ }
WHEN("each int is mapped to the strings with coordinator"){
auto res = w.start(
[&]() {
return xs
- .flat_map(
+ .merge_transform(
[&](int){
return ys;},
[](int, std::string s){
@@ -377,7 +461,7 @@ SCENARIO("flat_map completes", "[flat_map][map][operators]"){
}
}
-SCENARIO("flat_map source never ends", "[flat_map][map][operators]"){
+SCENARIO("merge_transform source never ends", "[merge_transform][transform][map][operators]"){
GIVEN("two cold observables. one of ints. one of strings."){
auto sc = rxsc::make_test();
auto w = sc.create_worker();
@@ -406,7 +490,7 @@ SCENARIO("flat_map source never ends", "[flat_map][map][operators]"){
auto res = w.start(
[&]() {
return xs
- .flat_map([&](int){return ys;}, [](int, std::string s){return s;})
+ .merge_transform([&](int){return ys;}, [](int, std::string s){return s;})
// forget type to workaround lambda deduction bug on msvc 2013
.as_dynamic();
}
@@ -464,7 +548,7 @@ SCENARIO("flat_map source never ends", "[flat_map][map][operators]"){
}
}
-SCENARIO("flat_map inner error", "[flat_map][map][operators]"){
+SCENARIO("merge_transform inner error", "[merge_transform][transform][map][operators]"){
GIVEN("two cold observables. one of ints. one of strings."){
auto sc = rxsc::make_test();
auto w = sc.create_worker();
@@ -494,7 +578,7 @@ SCENARIO("flat_map inner error", "[flat_map][map][operators]"){
auto res = w.start(
[&]() {
return xs
- .flat_map([&](int){return ys;}, [](int, std::string s){return s;})
+ .merge_transform([&](int){return ys;}, [](int, std::string s){return s;})
// forget type to workaround lambda deduction bug on msvc 2013
.as_dynamic();
}
@@ -538,7 +622,7 @@ SCENARIO("flat_map inner error", "[flat_map][map][operators]"){
}
}
-SCENARIO("flat_map, no result selector, no coordination", "[flat_map][map][operators]"){
+SCENARIO("merge_transform, no result selector, no coordination", "[merge_transform][transform][map][operators]"){
GIVEN("two cold observables. one of ints. one of strings."){
auto sc = rxsc::make_test();
auto w = sc.create_worker();
@@ -566,7 +650,7 @@ SCENARIO("flat_map, no result selector, no coordination", "[flat_map][map][opera
auto res = w.start(
[&]() {
return xs
- .flat_map(
+ .merge_transform(
[&](int){
return ys;})
// forget type to workaround lambda deduction bug on msvc 2013
@@ -620,7 +704,7 @@ SCENARIO("flat_map, no result selector, no coordination", "[flat_map][map][opera
}
}
-SCENARIO("flat_map, no result selector, with coordination", "[flat_map][map][operators]"){
+SCENARIO("merge_transform, no result selector, with coordination", "[merge_transform][transform][map][operators]"){
GIVEN("two cold observables. one of ints. one of strings."){
auto sc = rxsc::make_test();
auto w = sc.create_worker();
@@ -648,7 +732,7 @@ SCENARIO("flat_map, no result selector, with coordination", "[flat_map][map][ope
auto res = w.start(
[&]() {
return xs
- .flat_map(
+ .merge_transform(
[&](int){
return ys;},
rx::identity_current_thread())
@@ -701,4 +785,4 @@ SCENARIO("flat_map, no result selector, with coordination", "[flat_map][map][ope
}
}
}
-} \ No newline at end of file
+}
diff --git a/Rx/v2/test/operators/on_error_resume_next.cpp b/Rx/v2/test/operators/on_error_resume_next.cpp
index 490bd92..3761094 100644
--- a/Rx/v2/test/operators/on_error_resume_next.cpp
+++ b/Rx/v2/test/operators/on_error_resume_next.cpp
@@ -1,6 +1,77 @@
#include "../test.h"
#include <rxcpp/operators/rx-on_error_resume_next.hpp>
+SCENARIO("switch_on_error stops on completion", "[switch_on_error][on_error_resume_next][operators]"){
+ GIVEN("a test hot observable of ints"){
+ auto sc = rxsc::make_test();
+ auto w = sc.create_worker();
+ const rxsc::test::messages<int> on;
+ long invoked = 0;
+
+ auto xs = sc.make_hot_observable({
+ on.next(180, 1),
+ on.next(210, 2),
+ on.next(240, 3),
+ on.next(290, 4),
+ on.next(350, 5),
+ on.completed(400),
+ on.next(410, -1),
+ on.completed(420),
+ on.error(430, std::runtime_error("error on unsubscribed stream"))
+ });
+
+ auto ys = sc.make_cold_observable({
+ on.next(10, -1),
+ on.completed(20),
+ });
+
+ WHEN("passed through unchanged"){
+
+ auto res = w.start(
+ [xs, ys, &invoked]() {
+ return xs
+ .switch_on_error([ys, &invoked](std::exception_ptr) {
+ invoked++;
+ return ys;
+ })
+ // forget type to workaround lambda deduction bug on msvc 2013
+ .as_dynamic();
+ }
+ );
+
+ THEN("the output stops on completion"){
+ auto required = rxu::to_vector({
+ on.next(210, 2),
+ on.next(240, 3),
+ on.next(290, 4),
+ on.next(350, 5),
+ on.completed(400)
+ });
+ auto actual = res.get_observer().messages();
+ REQUIRE(required == actual);
+ }
+
+ THEN("there was one xs subscription and one unsubscription"){
+ auto required = rxu::to_vector({
+ on.subscribe(200, 400)
+ });
+ auto actual = xs.subscriptions();
+ REQUIRE(required == actual);
+ }
+
+ THEN("there was no ys subscription"){
+ auto required = std::vector<rxcpp::notifications::subscription>();
+ auto actual = ys.subscriptions();
+ REQUIRE(required == actual);
+ }
+
+ THEN("switch_on_error selector was not called"){
+ REQUIRE(0 == invoked);
+ }
+ }
+ }
+}
+
SCENARIO("on_error_resume_next stops on completion", "[on_error_resume_next][operators]"){
GIVEN("a test hot observable of ints"){
auto sc = rxsc::make_test();
diff --git a/Rx/v2/test/operators/reduce.cpp b/Rx/v2/test/operators/reduce.cpp
index 819f86c..33a0644 100644
--- a/Rx/v2/test/operators/reduce.cpp
+++ b/Rx/v2/test/operators/reduce.cpp
@@ -56,6 +56,61 @@ SCENARIO("reduce some data with seed", "[reduce][operators]"){
}
}
+SCENARIO("accumulate some data with seed", "[accumulate][reduce][operators]"){
+ GIVEN("a test hot observable of ints"){
+ auto sc = rxsc::make_test();
+ auto w = sc.create_worker();
+ const rxsc::test::messages<int> on;
+
+ int seed = 42;
+
+ auto xs = sc.make_hot_observable({
+ on.next(150, 1),
+ on.next(210, 0),
+ on.next(220, 1),
+ on.next(230, 2),
+ on.next(240, 3),
+ on.next(250, 4),
+ on.completed(260)
+ });
+
+ WHEN("mapped to ints that are one larger"){
+
+ auto res = w.start(
+ [&]() {
+ return xs
+ .accumulate(seed,
+ [](int sum, int x) {
+ return sum + x;
+ },
+ [](int sum) {
+ return sum * 5;
+ })
+ // forget type to workaround lambda deduction bug on msvc 2013
+ .as_dynamic();
+ }
+ );
+
+ THEN("the output stops on completion"){
+ auto required = rxu::to_vector({
+ on.next(260, (seed + 0 + 1 + 2 + 3 + 4) * 5),
+ on.completed(260)
+ });
+ auto actual = res.get_observer().messages();
+ REQUIRE(required == actual);
+ }
+
+ THEN("there was one subscription and one unsubscription"){
+ auto required = rxu::to_vector({
+ on.subscribe(200, 260)
+ });
+ auto actual = xs.subscriptions();
+ REQUIRE(required == actual);
+ }
+ }
+ }
+}
+
SCENARIO("average some data", "[reduce][average][operators]"){
GIVEN("a test hot observable of ints"){
auto sc = rxsc::make_test();