#include "pch.h"

#include <Cache.h>

#include "CppUnitTest.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace FrameworkTests
{
    TEST_CLASS (StreamTests)
    {
    public:
        TEST_METHOD (EmtptyTest)
        {
            Framework::Array<int> array;
            array.stream().forEach([](int i) { Assert::Fail(); });
        }

        TEST_METHOD (FilterTest)
        {
            Framework::Array<int> array;
            array.add(1);
            array.add(2);
            array.add(4);
            array.add(5);
            array.add(7);
            int count = 0;
            array.stream()
                .filter([](int i) { return i % 2 == 0; })
                .forEach([&count](int i) { count++; });
            Assert::AreEqual(2, count);
        }

        TEST_METHOD (MapTest)
        {
            Framework::Array<int> array;
            array.add(1);
            array.add(2);
            array.add(4);
            array.add(5);
            array.add(7);
            Framework::Array<int>* result
                = array.stream()
                      .map<int>([](int i) { return i * 2; })
                      .collect<Framework::Array<int>*>(
                          [](Framework::Array<int>* curr, int i) {
                              curr->add(i);
                              return curr;
                          },
                          new Framework::Array<int>());
            Assert::AreEqual(5, result->getEntryCount());
            Assert::AreEqual(2, result->get(0));
            Assert::AreEqual(4, result->get(1));
            Assert::AreEqual(8, result->get(2));
            Assert::AreEqual(10, result->get(3));
            Assert::AreEqual(14, result->get(4));
            result->release();
        }

        TEST_METHOD (FlatMapTest)
        {
            Framework::RCArray<Framework::Array<int>> array;
            array.add(new Framework::Array<int>());
            array.add(new Framework::Array<int>());
            array.add(new Framework::Array<int>());
            array.z(1)->add(1);
            array.z(1)->add(2);
            array.z(1)->add(4);
            array.z(2)->add(5);
            array.z(2)->add(7);
            Framework::Array<int>* result
                = array.stream()
                      .flatMap<int>([](Framework::Array<int>* val) {
                          return val->stream();
                      })
                      .collect<Framework::Array<int>*>(
                          [](Framework::Array<int>* curr, int i) {
                              curr->add(i);
                              return curr;
                          },
                          new Framework::Array<int>());
            Assert::AreEqual(5, result->getEntryCount());
            Assert::AreEqual(1, result->get(0));
            Assert::AreEqual(2, result->get(1));
            Assert::AreEqual(4, result->get(2));
            Assert::AreEqual(5, result->get(3));
            Assert::AreEqual(7, result->get(4));
            result->release();
        }
    };
} // namespace FrameworkTests