stream.t.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. //
  2. // stream_td.hpp
  3. // stream
  4. //
  5. // Created by Sam Jaffe on 1/28/17.
  6. //
  7. #pragma once
  8. #include <cxxtest/TestSuite.h>
  9. #include <string>
  10. #include <vector>
  11. #include "streams.hpp"
  12. // Workaround for OSX and pointer-to-member-functions
  13. template class std::basic_string<char>;
  14. class stream_TestSuite : public CxxTest::TestSuite {
  15. public:
  16. using int_t = int const &;
  17. using vec_t = std::vector<int>;
  18. public:
  19. void test_preserved() {
  20. vec_t v{1, 2, 3, 4, 5};
  21. auto s = stream::make_stream(v);
  22. vec_t o{s.begin(), s.end()};
  23. TS_ASSERT_EQUALS(v, o);
  24. }
  25. void test_collect_preserves() {
  26. vec_t v{1, 2, 3, 4, 5};
  27. auto s = stream::make_stream(v);
  28. vec_t o{s.begin(), s.end()};
  29. vec_t o2{s.collect()};
  30. TS_ASSERT_EQUALS(v, o);
  31. TS_ASSERT_EQUALS(v, o2);
  32. }
  33. void test_collect_arg_preserves() {
  34. vec_t v{1, 2, 3, 4, 5};
  35. auto s = stream::make_stream(v);
  36. std::set<int> o{};
  37. s.collect(o);
  38. for ( int i : v ) {
  39. TS_ASSERT_EQUALS(o.count( i ), 1);
  40. }
  41. }
  42. void test_map_identity() {
  43. vec_t v{1, 2, 3, 4, 5};
  44. auto identity = [](int_t i) { return i; };
  45. auto s = stream::make_stream(v).map( identity );
  46. vec_t o{s.begin(), s.end()};
  47. TS_ASSERT_EQUALS(v, o);
  48. }
  49. void test_map_change() {
  50. vec_t v{1, 2, 3, 4, 5};
  51. vec_t expected{3, 5, 7, 9, 11};
  52. auto fmap = [](int_t i) { return 2*i+1; };
  53. auto s = stream::make_stream(v).map( fmap );
  54. vec_t o{s.begin(), s.end()};
  55. TS_ASSERT_EQUALS(expected, o);
  56. }
  57. void test_singleton_stream() {
  58. int_t value = 11;
  59. auto even = [](int_t i) { return i%2==0; };
  60. auto s = stream::make_stream(&value).filter( even );
  61. TS_ASSERT(s.empty());
  62. }
  63. void test_stream_on_subrange() {
  64. vec_t v{1, 2, 3, 4, 5};
  65. vec_t expected{5, 7};
  66. auto fmap = [](int_t i) { return 2*i+1; };
  67. auto s = stream::make_stream(v.begin()+1, v.begin()+3).map( fmap );
  68. vec_t o{s.begin(), s.end()};
  69. TS_ASSERT_EQUALS(expected, o);
  70. }
  71. void test_filter_noop() {
  72. vec_t v{1, 2, 3, 4, 5};
  73. auto pass = [](int_t) { return true; };
  74. auto s = stream::make_stream(v).filter( pass );
  75. vec_t o{s.begin(), s.end()};
  76. TS_ASSERT_EQUALS(v, o);
  77. }
  78. void test_filter_value() {
  79. vec_t v{1, 2, 3, 4, 5};
  80. vec_t expected{2, 4};
  81. auto even = [](int_t i) { return i%2 == 0; };
  82. auto s = stream::make_stream(v).filter( even );
  83. vec_t o{s.begin(), s.end()};
  84. TS_ASSERT_EQUALS(expected, o);
  85. }
  86. void test_accumulate() {
  87. vec_t v{1, 2, 3, 4, 5};
  88. auto even = [](int_t i) { return i%2 == 0; };
  89. auto s = stream::make_stream(v).filter( even );
  90. TS_ASSERT_EQUALS( 6 , s.accumulate(0) );
  91. }
  92. void test_accumulate_custom_function() {
  93. vec_t v{1, 2, 3, 4, 5};
  94. auto even = [](int_t i) { return i%2 == 0; };
  95. auto prod =[](int_t lhs, int_t rhs) { return lhs * rhs; };
  96. auto s = stream::make_stream(v).filter( even );
  97. TS_ASSERT_EQUALS( 8 , s.accumulate(prod, 1) );
  98. }
  99. void test_flatmap_joins_lists() {
  100. vec_t vv{1, 2, 3, 4, 5};
  101. auto next3 = [](int_t i) { return vec_t{i, i+1, i+2}; };
  102. vec_t expected{1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 5, 6, 5, 6, 7};
  103. auto s = stream::make_stream(vv).flatmap( next3 );
  104. vec_t o{s.begin(), s.end()};
  105. TS_ASSERT_EQUALS(expected, o);
  106. }
  107. void test_dereference() {
  108. int val = 5;
  109. std::vector<int*> v{&val};
  110. auto data = stream::make_stream(v).deref().collect();
  111. TS_ASSERT_EQUALS(data.front(), val);
  112. }
  113. void test_foreach() {
  114. int hits = 0;
  115. vec_t v{1, 2, 3, 4, 5};
  116. stream::make_stream(v).each([&hits](int_t){ ++hits; });
  117. TS_ASSERT_EQUALS(hits, 5);
  118. }
  119. void test_getmember() {
  120. struct test { int val; };
  121. std::vector<test> v{{1}, {3}, {2}};
  122. vec_t expected{1, 3, 2};
  123. auto out = stream::make_stream(v).map(&test::val).collect();
  124. TS_ASSERT_EQUALS(out, expected);
  125. }
  126. void test_memberfunction() {
  127. std::vector<std::string> v{"hello", "goodbye"};
  128. std::vector<std::string::size_type> expected{5, 7};
  129. auto out = stream::make_stream(v).map(&std::string::size).collect();
  130. TS_ASSERT_EQUALS(out, expected);
  131. }
  132. void test_cast() {
  133. struct base { char cat[4] = "cat"; };
  134. struct test : base { test(int v) : val(v) {} int val; };
  135. std::vector<test> v{{1}, {3}, {2}};
  136. auto strm = stream::make_stream(v).cast<base>();
  137. auto first = stream::make_stream(v).map([](test const & t) { return (void*)&t; }).collect();
  138. auto second = strm.map([](base const & t) { return (void*)&t; }).collect();
  139. TS_ASSERT_EQUALS(first, second);
  140. }
  141. };