#include "Test.h"

#include "Any.h"
#include "Own.h"
//#include "Array.h"

#include <vector>

namespace MM
{

class Any_test : public Test
{
    Any *link;
public:
    Any_test (const Text& suite_name) : Test (suite_name) { }

    void run()
    {
        test_destroy();      count_tests();

        test_int();         count_tests();
        test_ptr();         count_tests();
        test_own();         count_tests();
        test_vector();      count_tests();
    }

    void test_destroy ()
    {
        Any i(111);
        TEST ("", !i.destroy());

        Any p(new int(222));
        TEST ("", !p.destroy());

        Any::Adopt p3(new int(333));
        Any      p3a = p3;
        TEST ("", p3a.destroy());
    }

    void test_int()
    {
        int         i  = 123;
        const int   ci = 789;

        Any         a (i);
        Any         b (456);
        Any         c (ci);
        

        TEST ("Successful construction.", any_cast <int> (a) == 123);
        TEST ("Successful construction.", any_cast <int> (b) == 456);
        TEST ("Successful construction.", any_cast <int> (c) == 789);

        any_cast <int> (a) = 111;
        any_cast <int> (b) = 222;
        any_cast <int> (c) = 333;

        TEST ("Successful assignment.", any_cast <int> (a) == 111);
        TEST ("Successful assignment.", any_cast <int> (b) == 222);
        TEST ("Successful assignment.", any_cast <int> (c) == 333);

        Any copy = a;
        //Any copy (a);
        
        TEST ("", any_cast <int> (copy) == 111);
        TEST ("", any_cast <int> (a)    == 111);//*/
    }

    void test_ptr()
    {
        int         i = 123;
        int        *ip = &i;

        Any         a (ip);
        

        TEST ("Successful construction.", *any_cast <int*> (a) == 123);

        *any_cast <int*> (a) = 111;

        TEST ("Successful assignment.", *any_cast <int*> (a) == 111);
    }

    void test_own()
    {
        Own <int>   i (new int(123));

        TEST ("", i.is_valid());

        Any         a (i);

        TEST ("", !i.is_valid());
        TEST ("Successful construction.", any_cast <Own <int> > (a)() == 123);
    }

    void test_vector()
    {
        std::vector <Any>   v;
        v.push_back (Any(1));
        v.push_back (Any(2.));
        v.push_back (Any (Own <double> (new double(3.3))));

        DOUBLES_EQUAL (any_cast <int>            (v[0]),      1,   0.00001);
        DOUBLES_EQUAL (any_cast <double>         (v[1]),      2.,  0.00001);
        DOUBLES_EQUAL (any_cast <Own <double> >  (v[2])(),    3.3, 0.00001);

        std::vector <Any>   copy = v;

        TEST ("", any_cast <int>                 (copy[0])   == 1);
        DOUBLES_EQUAL (any_cast <double>         (copy[1]),   2.,  0.00001);
        DOUBLES_EQUAL (any_cast <Own <double> >  (copy[2])(), 3.3, 0.00001);

        TEST ("",  any_cast <int>                (v[0])      == 1);
        DOUBLES_EQUAL (any_cast <double>         (v[1]),      2.,  0.00001);
        TEST ("", !any_cast <Own <double> >      (v[2]).is_valid());
    }
};

Any_test test_any ("correctness");

}//MM
