Browse Source

Fixing two traits bugs (calling memfnptr, void* isn't dereferenceable).
Adding test cases to reach effectively 100% code coverage of current library.

Samuel Jaffe 8 years ago
parent
commit
8c396c13f3
2 changed files with 48 additions and 3 deletions
  1. 44 2
      stream.t.h
  2. 4 1
      streams/traits.hpp

+ 44 - 2
stream.t.h

@@ -9,10 +9,13 @@
 
 #include <cxxtest/TestSuite.h>
 
+#include <string>
 #include <vector>
 
 #include "streams.hpp"
 
+// Workaround for OSX and pointer-to-member-functions
+template class std::basic_string<char>;
 
 class stream_TestSuite : public CxxTest::TestSuite {
 public:
@@ -82,9 +85,16 @@ public:
   void test_accumulate() {
     vec_t v{1, 2, 3, 4, 5};
     auto even = [](int_t i) { return i%2 == 0; };
-    auto sum =[](int_t lhs, int_t rhs) { return lhs + rhs; };
     auto s = stream::make_stream(v).filter( even );
-    TS_ASSERT_EQUALS( 6 , s.accumulate(sum, 0) );
+    TS_ASSERT_EQUALS( 6 , s.accumulate(0) );
+  }
+
+  void test_accumulate_custom_function() {
+    vec_t v{1, 2, 3, 4, 5};
+    auto even = [](int_t i) { return i%2 == 0; };
+    auto prod =[](int_t lhs, int_t rhs) { return lhs * rhs; };
+    auto s = stream::make_stream(v).filter( even );
+    TS_ASSERT_EQUALS( 8 , s.accumulate(prod, 1) );
   }
   
   void test_flatmap_joins_lists() {
@@ -102,4 +112,36 @@ public:
     auto data = stream::make_stream(v).deref().collect();
     TS_ASSERT_EQUALS(data.front(), val);
   }
+  
+  void test_foreach() {
+    int hits = 0;
+    vec_t v{1, 2, 3, 4, 5};
+    stream::make_stream(v).each([&hits](int_t val){ ++hits; });
+    TS_ASSERT_EQUALS(hits, 5);
+  }
+  
+  void test_getmember() {
+    struct test { int val; };
+    std::vector<test> v{{1}, {3}, {2}};
+    vec_t expected{1, 3, 2};
+    auto out = stream::make_stream(v).map(&test::val).collect();
+    TS_ASSERT_EQUALS(out, expected);
+  }
+  
+  void test_memberfunction() {
+    std::vector<std::string> v{"hello", "goodbye"};
+    std::vector<std::string::size_type> expected{5, 7};
+    auto out = stream::make_stream(v).map(&std::string::size).collect();
+    TS_ASSERT_EQUALS(out, expected);
+  }
+  
+  void test_cast() {
+    struct base { char cat[4] = "cat"; };
+    struct test : base { test(int v) : val(v) {} int val; };
+    std::vector<test> v{{1}, {3}, {2}};
+    auto strm = stream::make_stream(v).cast<base>();
+    auto first = stream::make_stream(v).map([](test const & t) { return (void*)&t; }).collect();
+    auto second = strm.map([](base const & t) { return (void*)&t; }).collect();
+    TS_ASSERT_EQUALS(first, second);
+  }
 };

+ 4 - 1
streams/traits.hpp

@@ -36,7 +36,7 @@ namespace stream { namespace detail {
   template <typename T, typename R>
   struct map_member_function<R (T::*)() const> {
     using type = R;
-    type operator()(T const & val) const { return val.*mem(); }
+    type operator()(T const & val) const { return (val.*mem)(); }
     R (T::* mem)() const;
   };
 }}
@@ -44,6 +44,9 @@ namespace stream { namespace detail {
 namespace stream { namespace detail {
   template <typename T, typename = void>
   struct is_dereferencable : public std::false_type {};
+
+  template <>
+  struct is_dereferencable<void*> : public std::false_type {};
   
   template <typename T>
   struct is_dereferencable<T, typename std::enable_if<!std::is_void<decltype(*std::declval<T>())>::value>::type> : public std::true_type {};