353 lines
12 KiB
C++
353 lines
12 KiB
C++
// Copyright (c) 2009 The Chromium Embedded Framework Authors. All rights
|
|
// reserved. Use of this source code is governed by a BSD-style license that
|
|
// can be found in the LICENSE file.
|
|
|
|
#include "include/cef.h"
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
|
#include "test_handler.h"
|
|
|
|
bool g_V8TestV8HandlerExecuteCalled;
|
|
bool g_V8TestV8HandlerExecute2Called;
|
|
|
|
class V8TestV8Handler : public CefThreadSafeBase<CefV8Handler>
|
|
{
|
|
public:
|
|
V8TestV8Handler(bool bindingTest) { binding_test_ = bindingTest; }
|
|
|
|
virtual bool Execute(const std::wstring& name,
|
|
CefRefPtr<CefV8Value> object,
|
|
const CefV8ValueList& arguments,
|
|
CefRefPtr<CefV8Value>& retval,
|
|
std::wstring& exception)
|
|
{
|
|
TestExecute(name, object, arguments, retval, exception);
|
|
return true;
|
|
}
|
|
|
|
void TestExecute(const std::wstring& name,
|
|
CefRefPtr<CefV8Value> object,
|
|
const CefV8ValueList& arguments,
|
|
CefRefPtr<CefV8Value>& retval,
|
|
std::wstring& exception)
|
|
{
|
|
if(name == L"execute") {
|
|
g_V8TestV8HandlerExecuteCalled = true;
|
|
|
|
ASSERT_EQ(8, arguments.size());
|
|
int argct = 0;
|
|
|
|
// basic types
|
|
ASSERT_TRUE(arguments[argct]->IsInt());
|
|
ASSERT_EQ(5, arguments[argct]->GetIntValue());
|
|
argct++;
|
|
|
|
ASSERT_TRUE(arguments[argct]->IsDouble());
|
|
ASSERT_EQ(6.543, arguments[argct]->GetDoubleValue());
|
|
argct++;
|
|
|
|
ASSERT_TRUE(arguments[argct]->IsBool());
|
|
ASSERT_EQ(true, arguments[argct]->GetBoolValue());
|
|
argct++;
|
|
|
|
ASSERT_TRUE(arguments[argct]->IsString());
|
|
ASSERT_EQ(L"test string", arguments[argct]->GetStringValue());
|
|
argct++;
|
|
|
|
CefRefPtr<CefV8Value> value;
|
|
|
|
// array
|
|
ASSERT_TRUE(arguments[argct]->IsArray());
|
|
ASSERT_EQ(4, arguments[argct]->GetArrayLength());
|
|
{
|
|
int subargct = 0;
|
|
value = arguments[argct]->GetValue(subargct);
|
|
ASSERT_TRUE(value.get() != NULL);
|
|
ASSERT_TRUE(value->IsInt());
|
|
ASSERT_EQ(7, value->GetIntValue());
|
|
subargct++;
|
|
|
|
value = arguments[argct]->GetValue(subargct);
|
|
ASSERT_TRUE(value.get() != NULL);
|
|
ASSERT_TRUE(value->IsDouble());
|
|
ASSERT_EQ(5.432, value->GetDoubleValue());
|
|
subargct++;
|
|
|
|
value = arguments[argct]->GetValue(subargct);
|
|
ASSERT_TRUE(value.get() != NULL);
|
|
ASSERT_TRUE(value->IsBool());
|
|
ASSERT_EQ(false, value->GetBoolValue());
|
|
subargct++;
|
|
|
|
value = arguments[argct]->GetValue(subargct);
|
|
ASSERT_TRUE(value.get() != NULL);
|
|
ASSERT_TRUE(value->IsString());
|
|
ASSERT_EQ(L"another string", value->GetStringValue());
|
|
subargct++;
|
|
}
|
|
argct++;
|
|
|
|
// object
|
|
ASSERT_TRUE(arguments[argct]->IsObject());
|
|
{
|
|
value = arguments[argct]->GetValue(L"arg0");
|
|
ASSERT_TRUE(value.get() != NULL);
|
|
ASSERT_TRUE(value->IsInt());
|
|
ASSERT_EQ(2, value->GetIntValue());
|
|
|
|
value = arguments[argct]->GetValue(L"arg1");
|
|
ASSERT_TRUE(value.get() != NULL);
|
|
ASSERT_TRUE(value->IsDouble());
|
|
ASSERT_EQ(3.433, value->GetDoubleValue());
|
|
|
|
value = arguments[argct]->GetValue(L"arg2");
|
|
ASSERT_TRUE(value.get() != NULL);
|
|
ASSERT_TRUE(value->IsBool());
|
|
ASSERT_EQ(true, value->GetBoolValue());
|
|
|
|
value = arguments[argct]->GetValue(L"arg3");
|
|
ASSERT_TRUE(value.get() != NULL);
|
|
ASSERT_TRUE(value->IsString());
|
|
ASSERT_EQ(L"some string", value->GetStringValue());
|
|
}
|
|
argct++;
|
|
|
|
// function that returns a value
|
|
ASSERT_TRUE(arguments[argct]->IsFunction());
|
|
{
|
|
CefV8ValueList args;
|
|
args.push_back(CefV8Value::CreateInt(5));
|
|
args.push_back(CefV8Value::CreateDouble(3.5));
|
|
args.push_back(CefV8Value::CreateBool(true));
|
|
args.push_back(CefV8Value::CreateString(L"10"));
|
|
CefRefPtr<CefV8Value> rv;
|
|
std::wstring exception;
|
|
ASSERT_TRUE(arguments[argct]->ExecuteFunction(
|
|
arguments[argct], args, rv, exception));
|
|
ASSERT_TRUE(rv.get() != NULL);
|
|
ASSERT_TRUE(rv->IsDouble());
|
|
ASSERT_EQ(19.5, rv->GetDoubleValue());
|
|
}
|
|
argct++;
|
|
|
|
// function that throws an exception
|
|
ASSERT_TRUE(arguments[argct]->IsFunction());
|
|
{
|
|
CefV8ValueList args;
|
|
args.push_back(CefV8Value::CreateDouble(5));
|
|
args.push_back(CefV8Value::CreateDouble(0));
|
|
CefRefPtr<CefV8Value> rv;
|
|
std::wstring exception;
|
|
ASSERT_TRUE(arguments[argct]->ExecuteFunction(
|
|
arguments[argct], args, rv, exception));
|
|
ASSERT_EQ(L"Uncaught My Exception", exception);
|
|
}
|
|
argct++;
|
|
|
|
if(binding_test_)
|
|
{
|
|
// values
|
|
value = object->GetValue(L"intVal");
|
|
ASSERT_TRUE(value.get() != NULL);
|
|
ASSERT_TRUE(value->IsInt());
|
|
ASSERT_EQ(12, value->GetIntValue());
|
|
|
|
value = object->GetValue(L"doubleVal");
|
|
ASSERT_TRUE(value.get() != NULL);
|
|
ASSERT_TRUE(value->IsDouble());
|
|
ASSERT_EQ(5.432, value->GetDoubleValue());
|
|
|
|
value = object->GetValue(L"boolVal");
|
|
ASSERT_TRUE(value.get() != NULL);
|
|
ASSERT_TRUE(value->IsBool());
|
|
ASSERT_EQ(true, value->GetBoolValue());
|
|
|
|
value = object->GetValue(L"stringVal");
|
|
ASSERT_TRUE(value.get() != NULL);
|
|
ASSERT_TRUE(value->IsString());
|
|
ASSERT_EQ(L"the string", value->GetStringValue());
|
|
|
|
value = object->GetValue(L"arrayVal");
|
|
ASSERT_TRUE(value.get() != NULL);
|
|
ASSERT_TRUE(value->IsArray());
|
|
{
|
|
CefRefPtr<CefV8Value> value2;
|
|
int subargct = 0;
|
|
value2 = value->GetValue(subargct);
|
|
ASSERT_TRUE(value2.get() != NULL);
|
|
ASSERT_TRUE(value2->IsInt());
|
|
ASSERT_EQ(4, value2->GetIntValue());
|
|
subargct++;
|
|
|
|
value2 = value->GetValue(subargct);
|
|
ASSERT_TRUE(value2.get() != NULL);
|
|
ASSERT_TRUE(value2->IsDouble());
|
|
ASSERT_EQ(120.43, value2->GetDoubleValue());
|
|
subargct++;
|
|
|
|
value2 = value->GetValue(subargct);
|
|
ASSERT_TRUE(value2.get() != NULL);
|
|
ASSERT_TRUE(value2->IsBool());
|
|
ASSERT_EQ(true, value2->GetBoolValue());
|
|
subargct++;
|
|
|
|
value2 = value->GetValue(subargct);
|
|
ASSERT_TRUE(value2.get() != NULL);
|
|
ASSERT_TRUE(value2->IsString());
|
|
ASSERT_EQ(L"a string", value2->GetStringValue());
|
|
subargct++;
|
|
}
|
|
}
|
|
|
|
retval = CefV8Value::CreateInt(5);
|
|
} else if(name == L"execute2") {
|
|
g_V8TestV8HandlerExecute2Called = true;
|
|
|
|
// check the result of calling the "execute" function
|
|
ASSERT_EQ(1, arguments.size());
|
|
ASSERT_TRUE(arguments[0]->IsInt());
|
|
ASSERT_EQ(5, arguments[0]->GetIntValue());
|
|
}
|
|
}
|
|
|
|
bool binding_test_;
|
|
};
|
|
|
|
class V8TestHandler : public TestHandler
|
|
{
|
|
public:
|
|
V8TestHandler(bool bindingTest) { binding_test_ = bindingTest; }
|
|
|
|
virtual void RunTest()
|
|
{
|
|
std::string object;
|
|
if(binding_test_) {
|
|
// binding uses the window object
|
|
object = "window.test";
|
|
} else {
|
|
// extension uses a global object
|
|
object = "test";
|
|
}
|
|
|
|
std::stringstream testHtml;
|
|
testHtml <<
|
|
"<html><body>"
|
|
"<script language=\"JavaScript\">"
|
|
"function func(a,b,c,d) { return a+b+(c?1:0)+parseFloat(d); }"
|
|
"function func2(a,b) { throw('My Exception'); }"
|
|
<< object << ".execute2("
|
|
" " << object << ".execute(5, 6.543, true, \"test string\","
|
|
" [7, 5.432, false, \"another string\"],"
|
|
" {arg0:2, arg1:3.433, arg2:true, arg3:\"some string\"}, func, func2)"
|
|
");"
|
|
"</script>"
|
|
"</body></html>";
|
|
|
|
AddResource(L"http://tests/run.html", testHtml.str(), L"text/html");
|
|
CreateBrowser(L"http://tests/run.html");
|
|
}
|
|
|
|
virtual RetVal HandleLoadEnd(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame)
|
|
{
|
|
if(!browser->IsPopup() && !frame.get())
|
|
DestroyTest();
|
|
return RV_CONTINUE;
|
|
}
|
|
|
|
virtual RetVal HandleJSBinding(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame,
|
|
CefRefPtr<CefV8Value> object)
|
|
{
|
|
if(binding_test_) {
|
|
TestHandleJSBinding(browser, frame, object);
|
|
return RV_HANDLED;
|
|
}
|
|
return RV_CONTINUE;
|
|
}
|
|
|
|
void TestHandleJSBinding(CefRefPtr<CefBrowser> browser,
|
|
CefRefPtr<CefFrame> frame,
|
|
CefRefPtr<CefV8Value> object)
|
|
{
|
|
// Create the new V8 object
|
|
CefRefPtr<CefV8Value> testObj = CefV8Value::CreateObject(NULL);
|
|
ASSERT_TRUE(testObj.get() != NULL);
|
|
ASSERT_TRUE(object->SetValue(L"test", testObj));
|
|
|
|
// Create an instance of V8ExecuteV8Handler
|
|
CefRefPtr<CefV8Handler> testHandler(new V8TestV8Handler(true));
|
|
ASSERT_TRUE(testHandler.get() != NULL);
|
|
|
|
// Add the functions
|
|
CefRefPtr<CefV8Value> testFunc;
|
|
testFunc = CefV8Value::CreateFunction(L"execute", testHandler);
|
|
ASSERT_TRUE(testFunc.get() != NULL);
|
|
ASSERT_TRUE(testObj->SetValue(L"execute", testFunc));
|
|
testFunc = CefV8Value::CreateFunction(L"execute2", testHandler);
|
|
ASSERT_TRUE(testFunc.get() != NULL);
|
|
ASSERT_TRUE(testObj->SetValue(L"execute2", testFunc));
|
|
|
|
// Add the values
|
|
ASSERT_TRUE(testObj->SetValue(L"intVal",
|
|
CefV8Value::CreateInt(12)));
|
|
ASSERT_TRUE(testObj->SetValue(L"doubleVal",
|
|
CefV8Value::CreateDouble(5.432)));
|
|
ASSERT_TRUE(testObj->SetValue(L"boolVal",
|
|
CefV8Value::CreateBool(true)));
|
|
ASSERT_TRUE(testObj->SetValue(L"stringVal",
|
|
CefV8Value::CreateString(L"the string")));
|
|
|
|
CefRefPtr<CefV8Value> testArray(CefV8Value::CreateArray());
|
|
ASSERT_TRUE(testArray.get() != NULL);
|
|
ASSERT_TRUE(testObj->SetValue(L"arrayVal", testArray));
|
|
ASSERT_TRUE(testArray->SetValue(0, CefV8Value::CreateInt(4)));
|
|
ASSERT_TRUE(testArray->SetValue(1, CefV8Value::CreateDouble(120.43)));
|
|
ASSERT_TRUE(testArray->SetValue(2, CefV8Value::CreateBool(true)));
|
|
ASSERT_TRUE(testArray->SetValue(3, CefV8Value::CreateString(L"a string")));
|
|
}
|
|
|
|
bool binding_test_;
|
|
};
|
|
|
|
// Verify window binding
|
|
TEST(V8Test, Binding)
|
|
{
|
|
g_V8TestV8HandlerExecuteCalled = false;
|
|
g_V8TestV8HandlerExecute2Called = false;
|
|
|
|
CefRefPtr<V8TestHandler> handler = new V8TestHandler(true);
|
|
handler->ExecuteTest();
|
|
|
|
ASSERT_TRUE(g_V8TestV8HandlerExecuteCalled);
|
|
ASSERT_TRUE(g_V8TestV8HandlerExecute2Called);
|
|
}
|
|
|
|
// Verify extensions
|
|
TEST(V8Test, Extension)
|
|
{
|
|
g_V8TestV8HandlerExecuteCalled = false;
|
|
g_V8TestV8HandlerExecute2Called = false;
|
|
|
|
std::wstring extensionCode =
|
|
L"var test;"
|
|
L"if (!test)"
|
|
L" test = {};"
|
|
L"(function() {"
|
|
L" test.execute = function(a,b,c,d,e,f,g,h) {"
|
|
L" native function execute();"
|
|
L" return execute(a,b,c,d,e,f,g,h);"
|
|
L" };"
|
|
L" test.execute2 = function(a) {"
|
|
L" native function execute2();"
|
|
L" return execute2(a);"
|
|
L" };"
|
|
L"})();";
|
|
CefRegisterExtension(L"v8/test", extensionCode, new V8TestV8Handler(false));
|
|
|
|
CefRefPtr<V8TestHandler> handler = new V8TestHandler(false);
|
|
handler->ExecuteTest();
|
|
|
|
ASSERT_TRUE(g_V8TestV8HandlerExecuteCalled);
|
|
ASSERT_TRUE(g_V8TestV8HandlerExecute2Called);
|
|
}
|