#include "test.hh"

template <typename T>
bool array_sum(std::vector<T>&& v)
{
  T acc = (T)0;
  for(auto e : v) acc += e;
  return js.call<T>("array_sum", v) == acc;
}

/**
 * Test: defining values
 */
void test()
{
  include_test_js();

  // Variadic template call, return=int
  test_expect( js.call<int>("sum", 1,2,3,4,5) == 1+2+3+4+5 );
  // Variadic template call, return=string
  test_expect( js.call<string>("sum", "1","2","3","4","5") == "012345" );
  // Variadic template call, return=char, char --> first char of string
  test_expect( js.call<char>("sum", "1","2","3","4","5") == '0' );

  // Return type conversions
  test_expect( array_sum<short>({1,2,3,4,5}) );
  test_expect( array_sum<int>({1,2,3,4,5}) );
  test_expect( array_sum<float>({1,2,3,4,5}) );
  test_expect( array_sum<double>({1,2,3,4,5}) );
  test_expect( array_sum<long>({1,2,3,4,5}) );
  test_expect( array_sum<long long>({1,2,3,4,5}) );
  test_expect( array_sum<unsigned char>({1,2,3,4,5}) ); // uchar --> numeric
  test_expect( array_sum<unsigned short>({1,2,3,4,5}) );
  test_expect( array_sum<unsigned int>({1,2,3,4,5}) );
  test_expect( array_sum<unsigned long>({1,2,3,4,5}) );
  test_expect( array_sum<unsigned long long>({1,2,3,4,5}) );

  // Exception forwarding js Error ---> c++ v8i::js_exception
  test_expect_except( js.call<bool>("throwee") );

  // Call object methods, obj has var counter=0 and function count() { return ++this.counter; }
  test_expect( js.call<int>("obj.count") == 1 );
  test_expect( js.call<int>("obj.count") == 2 );
  test_expect( js.call<int>("obj.count") == 3 );

  // Variadic template call, multiple type numeric conversions
  {
    float b = 1;
    double a = 1;
    long double c = 1;
    unsigned char d = 1;
    short e = 1;
    unsigned short f = 1;
    int g = 1;
    unsigned int h = 1;
    long i = 1;
    unsigned long j = 1;
    long long k = 5;
    unsigned long long l = 5;
    test_expect ( js.call<double>("sum", a,b,c,d,e,f,g,h,i,j,k,l) == a+b+c+d+e+f+g+h+i+j+k+l );
  }

}
