Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(313)

Unified Diff: extensions/renderer/api_bindings_system_unittest.cc

Issue 2753303003: [Extensions Bindings] Remove APIBindingsSystemTestWithRealAPI (Closed)
Patch Set: lazyboy's Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: extensions/renderer/api_bindings_system_unittest.cc
diff --git a/extensions/renderer/api_bindings_system_unittest.cc b/extensions/renderer/api_bindings_system_unittest.cc
index 3e43733ffc869cf75438b59ea3640be03c7193f8..83caeb2806ae3921c2edc9448276bda3d4975b82 100644
--- a/extensions/renderer/api_bindings_system_unittest.cc
+++ b/extensions/renderer/api_bindings_system_unittest.cc
@@ -35,6 +35,10 @@ const char kAlphaAPISpec[] =
" 'prop1': {'type': 'string'},"
" 'prop2': {'type': 'integer', 'optional': true}"
" }"
+ " }, {"
+ " 'id': 'alpha.enumRef',"
+ " 'type': 'string',"
+ " 'enum': ['cat', 'dog']"
" }],"
" 'functions': [{"
" 'name': 'functionWithCallback',"
@@ -54,6 +58,9 @@ const char kAlphaAPISpec[] =
" 'name': 'callback',"
" 'type': 'function'"
" }]"
+ " }, {"
+ " 'name': 'functionWithEnum',"
+ " 'parameters': [{'name': 'e', '$ref': 'alpha.enumRef'}]"
" }],"
" 'events': [{"
" 'name': 'alphaEvent'"
@@ -87,12 +94,14 @@ bool AllowAllAPIs(const std::string& name) {
// The base class to test the APIBindingsSystem. This allows subclasses to
// retrieve API schemas differently.
-class APIBindingsSystemTestBase : public APIBindingTest {
+class APIBindingsSystemTest : public APIBindingTest {
public:
// Returns the DictionaryValue representing the schema with the given API
// name.
- virtual const base::DictionaryValue& GetAPISchema(
- const std::string& api_name) = 0;
+ const base::DictionaryValue& GetAPISchema(const std::string& api_name) {
+ EXPECT_TRUE(base::ContainsKey(api_schemas_, api_name));
+ return *api_schemas_[api_name];
+ }
// Stores the request in |last_request_|.
void OnAPIRequest(std::unique_ptr<APIRequestHandler::Request> request,
@@ -106,17 +115,36 @@ class APIBindingsSystemTestBase : public APIBindingTest {
v8::Local<v8::Context> context) {}
protected:
- APIBindingsSystemTestBase() {}
+ APIBindingsSystemTest() {}
void SetUp() override {
APIBindingTest::SetUp();
+
+ // Create the fake API schemas.
+ {
+ struct APIData {
+ const char* name;
+ const char* spec;
+ } api_data[] = {
+ {kAlphaAPIName, kAlphaAPISpec},
+ {kBetaAPIName, kBetaAPISpec},
+ {kGammaAPIName, kGammaAPISpec},
+ };
+ for (const auto& api : api_data) {
+ std::unique_ptr<base::DictionaryValue> api_schema =
+ DictionaryValueFromString(api.spec);
+ ASSERT_TRUE(api_schema);
+ api_schemas_[api.name] = std::move(api_schema);
+ }
+ }
+
bindings_system_ = base::MakeUnique<APIBindingsSystem>(
base::Bind(&RunFunctionOnGlobalAndIgnoreResult),
base::Bind(&RunFunctionOnGlobalAndReturnHandle),
- base::Bind(&APIBindingsSystemTestBase::GetAPISchema,
+ base::Bind(&APIBindingsSystemTest::GetAPISchema,
base::Unretained(this)),
- base::Bind(&APIBindingsSystemTestBase::OnAPIRequest,
+ base::Bind(&APIBindingsSystemTest::OnAPIRequest,
base::Unretained(this)),
- base::Bind(&APIBindingsSystemTestBase::OnEventListenersChanged,
+ base::Bind(&APIBindingsSystemTest::OnEventListenersChanged,
base::Unretained(this)),
APILastError(APILastError::GetParent()));
}
@@ -135,7 +163,29 @@ class APIBindingsSystemTestBase : public APIBindingTest {
// Checks that |last_request_| exists and was provided with the
// |expected_name| and |expected_arguments|.
void ValidateLastRequest(const std::string& expected_name,
- const std::string& expected_arguments);
+ const std::string& expected_arguments) {
+ ASSERT_TRUE(last_request());
+ // Note that even if no arguments are provided by the API call, we should
+ // have an empty list.
+ ASSERT_TRUE(last_request()->arguments);
+ EXPECT_EQ(expected_name, last_request()->method_name);
+ EXPECT_EQ(ReplaceSingleQuotes(expected_arguments),
+ ValueToString(*last_request()->arguments));
+ }
+
+ void CallFunctionOnObject(v8::Local<v8::Context> context,
+ v8::Local<v8::Object> object,
+ const std::string& script_source) {
+ std::string wrapped_script_source =
+ base::StringPrintf("(function(obj) { %s })", script_source.c_str());
+
+ v8::Local<v8::Function> func =
+ FunctionFromString(context, wrapped_script_source);
+ ASSERT_FALSE(func.IsEmpty());
+
+ v8::Local<v8::Value> argv[] = {object};
+ RunFunction(func, context, 1, argv);
+ }
const APIRequestHandler::Request* last_request() const {
return last_request_.get();
@@ -144,6 +194,9 @@ class APIBindingsSystemTestBase : public APIBindingTest {
APIBindingsSystem* bindings_system() { return bindings_system_.get(); }
private:
+ // The API schemas for the fake APIs.
+ std::map<std::string, std::unique_ptr<base::DictionaryValue>> api_schemas_;
+
// The APIBindingsSystem associated with the test. Safe to use across multiple
// contexts.
std::unique_ptr<APIBindingsSystem> bindings_system_;
@@ -152,82 +205,9 @@ class APIBindingsSystemTestBase : public APIBindingTest {
// there is none.
std::unique_ptr<APIRequestHandler::Request> last_request_;
- DISALLOW_COPY_AND_ASSIGN(APIBindingsSystemTestBase);
-};
-
-void APIBindingsSystemTestBase::ValidateLastRequest(
- const std::string& expected_name,
- const std::string& expected_arguments) {
- ASSERT_TRUE(last_request());
- // Note that even if no arguments are provided by the API call, we should have
- // an empty list.
- ASSERT_TRUE(last_request()->arguments);
- EXPECT_EQ(expected_name, last_request()->method_name);
- EXPECT_EQ(ReplaceSingleQuotes(expected_arguments),
- ValueToString(*last_request()->arguments));
-}
-
-// An implementation that works with fake/supplied APIs, for easy testability.
-class APIBindingsSystemTest : public APIBindingsSystemTestBase {
- protected:
- APIBindingsSystemTest() {}
-
- // Calls a function constructed from |script_source| on the given |object|.
- void CallFunctionOnObject(v8::Local<v8::Context> context,
- v8::Local<v8::Object> object,
- const std::string& script_source);
-
- private:
- const base::DictionaryValue& GetAPISchema(
- const std::string& api_name) override {
- EXPECT_TRUE(base::ContainsKey(api_schemas_, api_name));
- return *api_schemas_[api_name];
- }
- void SetUp() override;
-
- // The API schemas for the fake APIs.
- std::map<std::string, std::unique_ptr<base::DictionaryValue>> api_schemas_;
-
DISALLOW_COPY_AND_ASSIGN(APIBindingsSystemTest);
};
-void APIBindingsSystemTest::CallFunctionOnObject(
- v8::Local<v8::Context> context,
- v8::Local<v8::Object> object,
- const std::string& script_source) {
- std::string wrapped_script_source =
- base::StringPrintf("(function(obj) { %s })", script_source.c_str());
-
- v8::Local<v8::Function> func =
- FunctionFromString(context, wrapped_script_source);
- ASSERT_FALSE(func.IsEmpty());
-
- v8::Local<v8::Value> argv[] = {object};
- RunFunction(func, context, 1, argv);
-}
-
-void APIBindingsSystemTest::SetUp() {
- // Create the fake API schemas.
- {
- struct APIData {
- const char* name;
- const char* spec;
- } api_data[] = {
- {kAlphaAPIName, kAlphaAPISpec},
- {kBetaAPIName, kBetaAPISpec},
- {kGammaAPIName, kGammaAPISpec},
- };
- for (const auto& api : api_data) {
- std::unique_ptr<base::DictionaryValue> api_schema =
- DictionaryValueFromString(api.spec);
- ASSERT_TRUE(api_schema);
- api_schemas_[api.name] = std::move(api_schema);
- }
- }
-
- APIBindingsSystemTestBase::SetUp();
-}
-
// Tests API object initialization, calling a method on the supplied APIs, and
// triggering the callback for the request.
TEST_F(APIBindingsSystemTest, TestInitializationAndCallbacks) {
@@ -285,6 +265,18 @@ TEST_F(APIBindingsSystemTest, TestInitializationAndCallbacks) {
}
{
+ // Test an invalid invocation -> throwing error.
+ const char kTestCall[] =
+ "(function(obj) { obj.functionWithEnum('mouse') })";
+ v8::Local<v8::Function> function = FunctionFromString(context, kTestCall);
+ v8::Local<v8::Value> args[] = {alpha_api};
+ RunFunctionAndExpectError(function, context, arraysize(args), args,
+ "Uncaught TypeError: Invalid invocation");
+ EXPECT_FALSE(last_request());
+ reset_last_request(); // Just to not pollute future results.
+ }
+
+ {
// Test an event registration -> event occurrence.
const char kTestCall[] =
"obj.alphaEvent.addListener(function() {\n"
@@ -445,153 +437,4 @@ TEST_F(APIBindingsSystemTest, CrossAPIReferences) {
}
}
-// An implementation using real API schemas.
-class APIBindingsSystemTestWithRealAPI : public APIBindingsSystemTestBase {
- protected:
- APIBindingsSystemTestWithRealAPI() {}
-
- // Executes the given |script_source| in |context|, expecting no exceptions.
- void ExecuteScript(v8::Local<v8::Context> context,
- const std::string& script_source);
-
- // Executes the given |script_source| in |context| and compares a caught
- // error to |expected_error|.
- void ExecuteScriptAndExpectError(v8::Local<v8::Context> context,
- const std::string& script_source,
- const std::string& expected_error);
-
- private:
- const base::DictionaryValue& GetAPISchema(
- const std::string& api_name) override {
- const base::DictionaryValue* schema =
- ExtensionAPI::GetSharedInstance()->GetSchema(api_name);
- EXPECT_TRUE(schema);
- return *schema;
- }
-
- DISALLOW_COPY_AND_ASSIGN(APIBindingsSystemTestWithRealAPI);
-};
-
-void APIBindingsSystemTestWithRealAPI::ExecuteScript(
- v8::Local<v8::Context> context,
- const std::string& script_source) {
- v8::TryCatch try_catch(isolate());
- // V8ValueFromScriptSource runs the source and returns the result; here, we
- // only care about running the source.
- V8ValueFromScriptSource(context, script_source);
- EXPECT_FALSE(try_catch.HasCaught())
- << gin::V8ToString(try_catch.Message()->Get());
-}
-
-void APIBindingsSystemTestWithRealAPI::ExecuteScriptAndExpectError(
- v8::Local<v8::Context> context,
- const std::string& script_source,
- const std::string& expected_error) {
- v8::TryCatch try_catch(isolate());
- V8ValueFromScriptSource(context, script_source);
- ASSERT_TRUE(try_catch.HasCaught()) << script_source;
- EXPECT_EQ(expected_error, gin::V8ToString(try_catch.Message()->Get()));
-}
-
-// The following test demonstrates how APIBindingsSystem can be used with "real"
-// Extension APIs; that is, using the raw Extension API schemas, rather than a
-// substituted test schema. This is useful to both show how the system is
-// intended to be used in the future as well as to make sure that it works with
-// actual APIs.
-TEST_F(APIBindingsSystemTestWithRealAPI, RealAPIs) {
- v8::HandleScope handle_scope(isolate());
- v8::Local<v8::Context> context = MainContext();
-
- v8::Local<v8::Object> chrome = v8::Object::New(isolate());
- {
- v8::Maybe<bool> res = context->Global()->Set(
- context, gin::StringToV8(isolate(), "chrome"), chrome);
- ASSERT_TRUE(res.IsJust());
- ASSERT_TRUE(res.FromJust());
- }
-
- auto add_api_to_chrome = [this, &chrome,
- &context](const std::string& api_name) {
- v8::Local<v8::Object> api = bindings_system()->CreateAPIInstance(
- api_name, context, context->GetIsolate(), base::Bind(&AllowAllAPIs),
- nullptr);
- ASSERT_FALSE(api.IsEmpty()) << api_name;
- v8::Maybe<bool> res = chrome->Set(
- context, gin::StringToV8(context->GetIsolate(), api_name), api);
- ASSERT_TRUE(res.IsJust());
- ASSERT_TRUE(res.FromJust());
- };
-
- // Pick two relatively small APIs that don't have any custom bindings (which
- // aren't supported yet).
- add_api_to_chrome("idle");
- add_api_to_chrome("power");
-
- // Test passing methods.
- {
- const char kTestCall[] = "chrome.power.requestKeepAwake('display');";
- ExecuteScript(context, kTestCall);
- ValidateLastRequest("power.requestKeepAwake", "['display']");
- EXPECT_EQ(-1, last_request()->request_id);
- reset_last_request();
- }
-
- {
- const char kTestCall[] = "chrome.power.releaseKeepAwake()";
- ExecuteScript(context, kTestCall);
- ValidateLastRequest("power.releaseKeepAwake", "[]");
- EXPECT_EQ(-1, last_request()->request_id);
- reset_last_request();
- }
-
- {
- const char kTestCall[] = "chrome.idle.queryState(30, function() {})";
- ExecuteScript(context, kTestCall);
- ValidateLastRequest("idle.queryState", "[30]");
- EXPECT_NE(-1, last_request()->request_id);
- reset_last_request();
- }
-
- {
- const char kTestCall[] = "chrome.idle.setDetectionInterval(30);";
- ExecuteScript(context, kTestCall);
- ValidateLastRequest("idle.setDetectionInterval", "[30]");
- EXPECT_EQ(-1, last_request()->request_id);
- reset_last_request();
- }
-
- // Check catching errors.
- const char kError[] = "Uncaught TypeError: Invalid invocation";
- {
- // "disp" is not an allowed enum value.
- const char kTestCall[] = "chrome.power.requestKeepAwake('disp');";
- ExecuteScriptAndExpectError(context, kTestCall, kError);
- EXPECT_FALSE(last_request());
- reset_last_request(); // Just to not pollute future results.
- }
-
- {
- // The queryState() param has a minimum of 15.
- const char kTestCall[] = "chrome.idle.queryState(10, function() {});";
- ExecuteScriptAndExpectError(context, kTestCall, kError);
- EXPECT_FALSE(last_request());
- reset_last_request(); // Just to not pollute future results.
- }
-
- {
- const char kTestCall[] =
- "chrome.idle.onStateChanged.addListener(state => {\n"
- " this.idleState = state;\n"
- "});\n";
- ExecuteScript(context, kTestCall);
- EXPECT_EQ("undefined", GetStringPropertyFromObject(context->Global(),
- context, "idleState"));
- bindings_system()->FireEventInContext("idle.onStateChanged", context,
- *ListValueFromString("['active']"));
-
- EXPECT_EQ("\"active\"", GetStringPropertyFromObject(context->Global(),
- context, "idleState"));
- }
-}
-
} // namespace extensions
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698