RTBKit  0.9
Open-source framework to create real-time ad bidding systems.
soa/sigslot/testing/slot_test.cc
00001 /* slot_test.cc
00002    Jeremy Barnes, 4 November 2010
00003    Copyright (c) 2010 Datacratic.  All rights reserved.
00004 
00005    Test the slot class.
00006 
00007 */
00008 
00009 #define BOOST_TEST_MAIN
00010 #define BOOST_TEST_DYN_LINK
00011 
00012 #include <boost/test/unit_test.hpp>
00013 #include <iostream>
00014 #include "jml/arch/exception_handler.h"
00015 #include "jml/utils/vector_utils.h"
00016 #include "jml/utils/string_functions.h"
00017 
00018 #include "soa/sigslot/slot.h"
00019 #include "soa/sigslot/slot_impl_js.h"
00020 
00021 #include "soa/js/js_call.h"
00022 #include "soa/js/js_utils.h"
00023 
00024 using namespace std;
00025 using namespace ML;
00026 using namespace Datacratic;
00027 
00028 template<typename T>
00029 void printSize()
00030 {
00031     cerr << "sizeof(" << ML::type_name<T>() << ") = "
00032          << sizeof(T) << endl;
00033 }
00034 
00035 RegisterJsOps<int (int)> reg4;
00036 
00037 BOOST_AUTO_TEST_CASE( test_sizes )
00038 {
00039     printSize<boost::function<void ()> >();
00040     printSize<boost::function<int ()> >();
00041     printSize<boost::function<int (int)> >();
00042     printSize<boost::function<int (int, int)> >();
00043     printSize<boost::function<int (int, int, int)> >();
00044     printSize<Slot>();
00045 }
00046 
00047 BOOST_AUTO_TEST_CASE( test_c_calling_c )
00048 {
00049     typedef int (Fn1) (int);
00050     typedef int (Fn2) (unsigned);
00051 
00052     auto f1 = [] (int val) -> int { return val; };
00053     auto f2 = [] (unsigned val) -> int { return 2 * val; };
00054 
00055     Slot n1 = slot<Fn1>(f1);
00056     BOOST_CHECK_EQUAL(n1.call<Fn1>(1), 1);
00057 
00058     {
00059         JML_TRACE_EXCEPTIONS(false);
00060         BOOST_CHECK_THROW(n1.call<Fn2>(1), ML::Exception);
00061     }
00062 
00063     n1 = slot<Fn1>(f2);
00064     BOOST_CHECK_EQUAL(n1.call<Fn1>(1), 2);
00065 }
00066 
00067 BOOST_AUTO_TEST_CASE( test_js_calling_c )
00068 {
00069     typedef int (Fn1) (int);
00070     typedef int (Fn2) (unsigned);
00071 
00072     auto f1 = [] (int val) -> int { return val; };
00073     auto f2 = [] (unsigned val) -> int { return 2 * val; };
00074 
00075     Slot n1 = slot<Fn1>(f1);
00076     BOOST_CHECK_EQUAL(n1.call<Fn1>(1), 1);
00077 
00078     {
00079         JML_TRACE_EXCEPTIONS(false);
00080         BOOST_CHECK_THROW(n1.call<Fn2>(1), ML::Exception);
00081     }
00082 
00083     n1 = slot<Fn1>(f2);
00084     BOOST_CHECK_EQUAL(n1.call<Fn1>(1), 2);
00085 
00086     using namespace v8;
00087 
00088     HandleScope handle_scope;
00089     Persistent<Context> context = Context::New();
00090     Context::Scope context_scope(context);
00091     
00092     // Goal: call the slot from Javascript
00093     int argc = 1;
00094     Handle<Value> argv[argc];
00095     argv[0] = JS::toJS(1);
00096 
00097     BOOST_CHECK_EQUAL(JS::cstr(n1.call(context->Global(), argc, argv)), "2");
00098     n1 = slot<Fn1>(f1);
00099     BOOST_CHECK_EQUAL(JS::cstr(n1.call(context->Global(), argc, argv)), "1");
00100   
00101     context.Dispose();
00102 }
00103 
00104 BOOST_AUTO_TEST_CASE( test_c_calling_js )
00105 {
00106     using namespace v8;
00107 
00108     HandleScope handle_scope;
00109     Persistent<Context> context = Context::New();
00110     Context::Scope context_scope(context);
00111     
00112     v8::Handle<v8::Function> fn1
00113         = JS::getFunction("function f1(val) { return val; };  f1;");
00114     v8::Handle<v8::Function> fn2
00115         = JS::getFunction("function f2(val) { return val * 2; };  f2;");
00116 
00117     typedef int (Fn) (int);
00118 
00119     Slot n1(fn1);
00120 
00121     BOOST_CHECK_EQUAL(n1.call<Fn>(1), 1);
00122 
00123     n1 = Slot(fn2);
00124     
00125     BOOST_CHECK_EQUAL(n1.call<Fn>(1), 2);
00126 
00127     context.Dispose();
00128 }
00129 
00130 BOOST_AUTO_TEST_CASE( test_js_calling_js )
00131 {
00132     using namespace v8;
00133 
00134     HandleScope handle_scope;
00135     Persistent<Context> context = Context::New();
00136     Context::Scope context_scope(context);
00137 
00138     v8::Handle<v8::Function> fn1
00139         = JS::getFunction("function f1(val) { return val; };  f1;");
00140     v8::Handle<v8::Function> fn2
00141         = JS::getFunction("function f2(val) { return val * 2; };  f2;");
00142 
00143     Slot n1(fn1);
00144     
00145     // Goal: call the slot from Javascript
00146     int argc = 1;
00147     Handle<Value> argv[argc];
00148     argv[0] = JS::toJS(1);
00149 
00150     BOOST_CHECK_EQUAL(JS::cstr(n1.call(context->Global(), argc, argv)), "1");
00151     n1 = Slot(fn2);
00152     BOOST_CHECK_EQUAL(JS::cstr(n1.call(context->Global(), argc, argv)), "2");
00153   
00154     context.Dispose();
00155 }
00156 
00157 RegisterJsOps<void (void)> reg5;
00158 
00159 BOOST_AUTO_TEST_CASE( test_conversion_to_function )
00160 {
00161     int i = 0;
00162 
00163     boost::function<void ()> fn;
00164 
00165     SlotT<void ()> slot([&] () { i += 1; });
00166 
00167     fn = slot;
00168 
00169     fn();
00170 
00171     BOOST_CHECK_EQUAL(i, 1);
00172 
00173     slot();
00174 
00175     BOOST_CHECK_EQUAL(i, 2);
00176 
00177     Slot slot2 = slot;
00178 
00179     slot2.call<void ()>();
00180 
00181     //fn = slot2;
00182 
00183     BOOST_CHECK_EQUAL(i, 3);
00184 }
00185 
00186 BOOST_AUTO_TEST_CASE( dispose )
00187 {
00188     v8::V8::Dispose();
00189 }
00190 
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator