#include #include #include #include #include #include #include #include #include template static VectorSource vectorSource(const Obj (&data)[Size]) { std::vector vector(data, data + Size); return VectorSource(vector); } template static void expect(const Source& source, const Data (&data)[Size], EqFn eqFn) { BOOST_STATIC_ASSERT(Size > 2); for(size_t markPos = 0; markPos < Size; markPos++) { boost::shared_ptr mark; Source current = source; for(size_t i = 0; i < Size; i++) { ASSERT_TRUE(current.step()); if(i == markPos) mark = boost::make_shared(current.mark() ); ASSERT_TRUE(eqFn(*current.get(), data[i])); } ASSERT_FALSE(current.step()); current.restore(*mark); for(size_t i = markPos; i < Size; i++) { ASSERT_TRUE(eqFn(*current.get(), data[i])); if(i < Size - 1) { ASSERT_TRUE(current.step()); } } ASSERT_FALSE(current.step()); } } template static void expect(Source source, const Data (&data)[Size]) { expect(source, data, std::equal_to() ); } TEST(Cursors, vectorSource) { const int data[] = { 1, 2, 3 }; VectorSource source = vectorSource(data); expect(source, data); } TEST(Cursors, union) { const std::pair data1[] = { std::make_pair(1, 1), std::make_pair(1, 2), std::make_pair(2, 2) }; const std::pair data2[] = { std::make_pair(1, 3), std::make_pair(2, 3) }; const std::pair expected[] = { std::make_pair(1, 3), std::make_pair(1, 1), std::make_pair(1, 2), std::make_pair(2, 3), std::make_pair(2, 2) }; struct Fn { static int key(std::pair pair) { return pair.first; } }; expect( db::unionBy( Fn::key, vectorSource(data1), vectorSource(data2) ), expected); } TEST(Cursors, select) { const int data[] = { 1, 2, 3, 4 }; const int expected[] = { -1, -2, -3, -4 }; struct Fn { static int op(int i) { return -i; } }; expect( vectorSource(data) | db::select(Fn::op), expected); } TEST(Cursors, leftJoinEq) { const int data1[] = { 1, 2, 2, 3, 4 }; const int data2[] = { 1, 2, 3, 3, 5 }; const std::pair expected[] = { std::make_pair(1, 1), std::make_pair(2, 2), std::make_pair(2, 2), std::make_pair(3, 3), std::make_pair(3, 3), std::make_pair(4, 0), }; struct Fn { static bool eq(std::pair left, std::pair right) { return left.first == right.first && ( (right.second == 0 && left.second == NULL) || (right.second != 0 && left.second != NULL && right.second == *left.second) ); } static int key(int i) { return i; } }; expect( db::leftJoinBy( Fn::key, vectorSource(data1), vectorSource(data2) ), expected, Fn::eq); } struct TestGroupOps { typedef int KeyType; typedef int ProjType; typedef int GroupType; int count; TestGroupOps() : count(0) {} KeyType key(int i) { return i; } ProjType project(int i) { return -i; } void step(int i) { this->count += 1; } int finish() { int result = this->count; this->count = 0; return result; } }; TEST(Cursors, group) { const int data[] = { 1, 2, 2, 3 }; const std::pair expected[] = { std::make_pair(-1, 1), std::make_pair(-2, 2), std::make_pair(-3, 1) }; expect( vectorSource(data) | db::groupBy(TestGroupOps() ), expected); } TEST(Cursors, filter) { const int data[] = { 1, 2, 2, 3 }; const int expected[] = { 2, 2, 3 }; struct Fn { static bool fn(int i) { return i > 1; } }; expect( vectorSource(data) | db::where(Fn::fn), expected); } TEST(Cursors, distinct) { const int data[] = { 1, 2, 2, 3 }; const int expected[] = { 1, 2, 3 }; struct Fn { static int fn(int i) { return i; } }; expect( vectorSource(data) | db::distinctBy(Fn::fn), expected); }