Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/source/scriptinterface/tests/test_ScriptConversions.h
Show All 29 Lines | |||||
class TestScriptConversions : public CxxTest::TestSuite | class TestScriptConversions : public CxxTest::TestSuite | ||||
{ | { | ||||
template <typename T> | template <typename T> | ||||
void convert_to(const T& value, const std::string& expected) | void convert_to(const T& value, const std::string& expected) | ||||
{ | { | ||||
ScriptInterface script("Test", "Test", g_ScriptRuntime); | ScriptInterface script("Test", "Test", g_ScriptRuntime); | ||||
TS_ASSERT(script.LoadGlobalScripts()); | TS_ASSERT(script.LoadGlobalScripts()); | ||||
JSContext* cx = script.GetContext(); | ScriptInterface::Request rq(script); | ||||
JSAutoRequest rq(cx); | |||||
JS::RootedValue v1(cx); | JS::RootedValue v1(rq.cx); | ||||
ScriptInterface::ToJSVal(cx, &v1, value); | ScriptInterface::ToJSVal(rq, &v1, value); | ||||
// We want to convert values to strings, but can't just call toSource() on them | // We want to convert values to strings, but can't just call toSource() on them | ||||
// since they might not be objects. So just use uneval. | // since they might not be objects. So just use uneval. | ||||
std::string source; | std::string source; | ||||
JS::RootedValue global(cx, script.GetGlobalObject()); | JS::RootedValue global(rq.cx, script.GetGlobalObject()); | ||||
TS_ASSERT(script.CallFunction(global, "uneval", source, v1)); | TS_ASSERT(script.CallFunction(global, "uneval", source, v1)); | ||||
TS_ASSERT_STR_EQUALS(source, expected); | TS_ASSERT_STR_EQUALS(source, expected); | ||||
} | } | ||||
template <typename T> | template <typename T> | ||||
void roundtrip(const T& value, const char* expected) | void roundtrip(const T& value, const char* expected) | ||||
{ | { | ||||
ScriptInterface script("Test", "Test", g_ScriptRuntime); | ScriptInterface script("Test", "Test", g_ScriptRuntime); | ||||
TS_ASSERT(script.LoadGlobalScripts()); | TS_ASSERT(script.LoadGlobalScripts()); | ||||
JSContext* cx = script.GetContext(); | ScriptInterface::Request rq(script); | ||||
JSAutoRequest rq(cx); | |||||
JS::RootedValue v1(cx); | JS::RootedValue v1(rq.cx); | ||||
ScriptInterface::ToJSVal(cx, &v1, value); | ScriptInterface::ToJSVal(rq, &v1, value); | ||||
std::string source; | std::string source; | ||||
JS::RootedValue global(cx, script.GetGlobalObject()); | JS::RootedValue global(rq.cx, script.GetGlobalObject()); | ||||
TS_ASSERT(script.CallFunction(global, "uneval", source, v1)); | TS_ASSERT(script.CallFunction(global, "uneval", source, v1)); | ||||
if (expected) | if (expected) | ||||
TS_ASSERT_STR_EQUALS(source, expected); | TS_ASSERT_STR_EQUALS(source, expected); | ||||
T v2 = T(); | T v2 = T(); | ||||
TS_ASSERT(ScriptInterface::FromJSVal(cx, v1, v2)); | TS_ASSERT(ScriptInterface::FromJSVal(rq, v1, v2)); | ||||
TS_ASSERT_EQUALS(value, v2); | TS_ASSERT_EQUALS(value, v2); | ||||
} | } | ||||
template <typename T> | template <typename T> | ||||
void call_prototype_function(const T& u, const T& v, const std::string& func, const std::string& expected) | void call_prototype_function(const T& u, const T& v, const std::string& func, const std::string& expected) | ||||
{ | { | ||||
ScriptInterface script("Test", "Test", g_ScriptRuntime); | ScriptInterface script("Test", "Test", g_ScriptRuntime); | ||||
TS_ASSERT(script.LoadGlobalScripts()); | TS_ASSERT(script.LoadGlobalScripts()); | ||||
JSContext* cx = script.GetContext(); | ScriptInterface::Request rq(script); | ||||
JSAutoRequest rq(cx); | |||||
JS::RootedValue v1(cx); | JS::RootedValue v1(rq.cx); | ||||
ScriptInterface::ToJSVal(cx, &v1, v); | ScriptInterface::ToJSVal(rq, &v1, v); | ||||
JS::RootedValue u1(cx); | JS::RootedValue u1(rq.cx); | ||||
ScriptInterface::ToJSVal(cx, &u1, u); | ScriptInterface::ToJSVal(rq, &u1, u); | ||||
T r; | T r; | ||||
JS::RootedValue r1(cx); | JS::RootedValue r1(rq.cx); | ||||
TS_ASSERT(script.CallFunction(u1, func.c_str(), r, v1)); | TS_ASSERT(script.CallFunction(u1, func.c_str(), r, v1)); | ||||
ScriptInterface::ToJSVal(cx, &r1, r); | ScriptInterface::ToJSVal(rq, &r1, r); | ||||
std::string source; | std::string source; | ||||
JS::RootedValue global(cx, script.GetGlobalObject()); | JS::RootedValue global(rq.cx, script.GetGlobalObject()); | ||||
TS_ASSERT(script.CallFunction(global, "uneval", source, r1)); | TS_ASSERT(script.CallFunction(global, "uneval", source, r1)); | ||||
TS_ASSERT_STR_EQUALS(source, expected); | TS_ASSERT_STR_EQUALS(source, expected); | ||||
} | } | ||||
public: | public: | ||||
void setUp() | void setUp() | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | void test_roundtrip() | ||||
roundtrip<fixed>(fixed::FromInt(123), "123"); | roundtrip<fixed>(fixed::FromInt(123), "123"); | ||||
roundtrip<fixed>(fixed::FromInt(-123), "-123"); | roundtrip<fixed>(fixed::FromInt(-123), "-123"); | ||||
roundtrip<fixed>(fixed::FromDouble(123.25), "123.25"); | roundtrip<fixed>(fixed::FromDouble(123.25), "123.25"); | ||||
} | } | ||||
void test_integers() | void test_integers() | ||||
{ | { | ||||
ScriptInterface script("Test", "Test", g_ScriptRuntime); | ScriptInterface script("Test", "Test", g_ScriptRuntime); | ||||
JSContext* cx = script.GetContext(); | ScriptInterface::Request rq(script); | ||||
JSAutoRequest rq(cx); | |||||
// using new uninitialized variables each time to be sure the test doesn't succeeed if ToJSVal doesn't touch the value at all. | // using new uninitialized variables each time to be sure the test doesn't succeeed if ToJSVal doesn't touch the value at all. | ||||
JS::RootedValue val0(cx), val1(cx), val2(cx), val3(cx), val4(cx), val5(cx), val6(cx), val7(cx), val8(cx); | JS::RootedValue val0(rq.cx), val1(rq.cx), val2(rq.cx), val3(rq.cx), val4(rq.cx), val5(rq.cx), val6(rq.cx), val7(rq.cx), val8(rq.cx); | ||||
ScriptInterface::ToJSVal<i32>(cx, &val0, 0); | ScriptInterface::ToJSVal<i32>(rq, &val0, 0); | ||||
ScriptInterface::ToJSVal<i32>(cx, &val1, JSVAL_INT_MAX - 1); | ScriptInterface::ToJSVal<i32>(rq, &val1, JSVAL_INT_MAX - 1); | ||||
ScriptInterface::ToJSVal<i32>(cx, &val2, JSVAL_INT_MAX); | ScriptInterface::ToJSVal<i32>(rq, &val2, JSVAL_INT_MAX); | ||||
ScriptInterface::ToJSVal<i32>(cx, &val3, JSVAL_INT_MIN + 1); | ScriptInterface::ToJSVal<i32>(rq, &val3, JSVAL_INT_MIN + 1); | ||||
ScriptInterface::ToJSVal<i32>(cx, &val4, -(i64)2147483648u); // JSVAL_INT_MIN | ScriptInterface::ToJSVal<i32>(rq, &val4, -(i64)2147483648u); // JSVAL_INT_MIN | ||||
TS_ASSERT(val0.isInt32()); | TS_ASSERT(val0.isInt32()); | ||||
TS_ASSERT(val1.isInt32()); | TS_ASSERT(val1.isInt32()); | ||||
TS_ASSERT(val2.isInt32()); | TS_ASSERT(val2.isInt32()); | ||||
TS_ASSERT(val3.isInt32()); | TS_ASSERT(val3.isInt32()); | ||||
TS_ASSERT(val4.isInt32()); | TS_ASSERT(val4.isInt32()); | ||||
ScriptInterface::ToJSVal<u32>(cx, &val5, 0); | ScriptInterface::ToJSVal<u32>(rq, &val5, 0); | ||||
ScriptInterface::ToJSVal<u32>(cx, &val6, 2147483646u); // JSVAL_INT_MAX-1 | ScriptInterface::ToJSVal<u32>(rq, &val6, 2147483646u); // JSVAL_INT_MAX-1 | ||||
ScriptInterface::ToJSVal<u32>(cx, &val7, 2147483647u); // JSVAL_INT_MAX | ScriptInterface::ToJSVal<u32>(rq, &val7, 2147483647u); // JSVAL_INT_MAX | ||||
ScriptInterface::ToJSVal<u32>(cx, &val8, 2147483648u); // JSVAL_INT_MAX+1 | ScriptInterface::ToJSVal<u32>(rq, &val8, 2147483648u); // JSVAL_INT_MAX+1 | ||||
TS_ASSERT(val5.isInt32()); | TS_ASSERT(val5.isInt32()); | ||||
TS_ASSERT(val6.isInt32()); | TS_ASSERT(val6.isInt32()); | ||||
TS_ASSERT(val7.isInt32()); | TS_ASSERT(val7.isInt32()); | ||||
TS_ASSERT(val8.isDouble()); | TS_ASSERT(val8.isDouble()); | ||||
} | } | ||||
void test_nonfinite() | void test_nonfinite() | ||||
{ | { | ||||
roundtrip<float>(std::numeric_limits<float>::infinity(), "Infinity"); | roundtrip<float>(std::numeric_limits<float>::infinity(), "Infinity"); | ||||
roundtrip<float>(-std::numeric_limits<float>::infinity(), "-Infinity"); | roundtrip<float>(-std::numeric_limits<float>::infinity(), "-Infinity"); | ||||
convert_to<float>(std::numeric_limits<float>::quiet_NaN(), "NaN"); // can't use roundtrip since nan != nan | convert_to<float>(std::numeric_limits<float>::quiet_NaN(), "NaN"); // can't use roundtrip since nan != nan | ||||
ScriptInterface script("Test", "Test", g_ScriptRuntime); | ScriptInterface script("Test", "Test", g_ScriptRuntime); | ||||
JSContext* cx = script.GetContext(); | ScriptInterface::Request rq(script); | ||||
JSAutoRequest rq(cx); | |||||
float f = 0; | float f = 0; | ||||
JS::RootedValue testNANVal(cx); | JS::RootedValue testNANVal(rq.cx); | ||||
ScriptInterface::ToJSVal(cx, &testNANVal, NAN); | ScriptInterface::ToJSVal(rq, &testNANVal, NAN); | ||||
TS_ASSERT(ScriptInterface::FromJSVal(cx, testNANVal, f)); | TS_ASSERT(ScriptInterface::FromJSVal(rq, testNANVal, f)); | ||||
TS_ASSERT(isnan(f)); | TS_ASSERT(isnan(f)); | ||||
} | } | ||||
// NOTE: fixed and vector conversions are defined in simulation2/scripting/EngineScriptConversions.cpp | // NOTE: fixed and vector conversions are defined in simulation2/scripting/EngineScriptConversions.cpp | ||||
void test_fixed() | void test_fixed() | ||||
{ | { | ||||
fixed f; | fixed f; | ||||
Show All 29 Lines | void test_vector3d() | ||||
call_prototype_function<CFixedVector3D>(u, v, "add", "({x:3.1415863037109375, y:3.1415863037109375, z:3})"); | call_prototype_function<CFixedVector3D>(u, v, "add", "({x:3.1415863037109375, y:3.1415863037109375, z:3})"); | ||||
} | } | ||||
void test_utf8utf16_conversion() | void test_utf8utf16_conversion() | ||||
{ | { | ||||
// Fancier conversion: we store UTF8 and get UTF16 and vice-versa | // Fancier conversion: we store UTF8 and get UTF16 and vice-versa | ||||
ScriptInterface script("Test", "Test", g_ScriptRuntime); | ScriptInterface script("Test", "Test", g_ScriptRuntime); | ||||
TS_ASSERT(script.LoadGlobalScripts()); | TS_ASSERT(script.LoadGlobalScripts()); | ||||
JSContext* cx = script.GetContext(); | ScriptInterface::Request rq(script); | ||||
JSAutoRequest rq(cx); | |||||
std::string in_utf8("éè!§$-aezi134900°°©©¢¢ÇÇ‘{¶«¡Ç’[å»ÛÁØ"); | std::string in_utf8("éè!§$-aezi134900°°©©¢¢ÇÇ‘{¶«¡Ç’[å»ÛÁØ"); | ||||
std::wstring in_utf16(L"éè!§$-aezi134900°°©©¢¢ÇÇ‘{¶«¡Ç’[å»ÛÁØ"); | std::wstring in_utf16(L"éè!§$-aezi134900°°©©¢¢ÇÇ‘{¶«¡Ç’[å»ÛÁØ"); | ||||
JS::RootedValue v1(cx); | JS::RootedValue v1(rq.cx); | ||||
ScriptInterface::ToJSVal(cx, &v1, in_utf8); | ScriptInterface::ToJSVal(rq, &v1, in_utf8); | ||||
std::wstring test_out_utf16; | std::wstring test_out_utf16; | ||||
TS_ASSERT(ScriptInterface::FromJSVal(cx, v1, test_out_utf16)); | TS_ASSERT(ScriptInterface::FromJSVal(rq, v1, test_out_utf16)); | ||||
TS_ASSERT_EQUALS(test_out_utf16, in_utf16); | TS_ASSERT_EQUALS(test_out_utf16, in_utf16); | ||||
JS::RootedValue v2(cx); | JS::RootedValue v2(rq.cx); | ||||
ScriptInterface::ToJSVal(cx, &v2, in_utf16); | ScriptInterface::ToJSVal(rq, &v2, in_utf16); | ||||
std::string test_out_utf8; | std::string test_out_utf8; | ||||
TS_ASSERT(ScriptInterface::FromJSVal(cx, v2, test_out_utf8)); | TS_ASSERT(ScriptInterface::FromJSVal(rq, v2, test_out_utf8)); | ||||
TS_ASSERT_EQUALS(test_out_utf8, in_utf8); | TS_ASSERT_EQUALS(test_out_utf8, in_utf8); | ||||
} | } | ||||
}; | }; |
Wildfire Games · Phabricator