Commit bdfc03eb authored by miket@chromium.org's avatar miket@chromium.org

Refactor to allow same code to test both sync and async functions.

BUG=none
TEST=none


Review URL: http://codereview.chromium.org/8588067

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@111050 0039d316-1c4b-4281-b951-d872f2087c98
parent 60acf75e
...@@ -128,7 +128,7 @@ void ExtensionFunction::HandleBadMessage(base::ProcessHandle process) { ...@@ -128,7 +128,7 @@ void ExtensionFunction::HandleBadMessage(base::ProcessHandle process) {
} }
} }
UIThreadExtensionFunction::UIThreadExtensionFunction() UIThreadExtensionFunction::UIThreadExtensionFunction()
: render_view_host_(NULL), profile_(NULL) { : render_view_host_(NULL), profile_(NULL), delegate_(NULL) {
} }
UIThreadExtensionFunction::~UIThreadExtensionFunction() { UIThreadExtensionFunction::~UIThreadExtensionFunction() {
...@@ -154,13 +154,17 @@ Browser* UIThreadExtensionFunction::GetCurrentBrowser() { ...@@ -154,13 +154,17 @@ Browser* UIThreadExtensionFunction::GetCurrentBrowser() {
} }
void UIThreadExtensionFunction::SendResponse(bool success) { void UIThreadExtensionFunction::SendResponse(bool success) {
if (!render_view_host_ || !dispatcher()) if (delegate_) {
return; delegate_->OnSendResponse(this, success);
} else {
if (!render_view_host_ || !dispatcher())
return;
SendResponseImpl(render_view_host_->process()->GetHandle(), SendResponseImpl(render_view_host_->process()->GetHandle(),
render_view_host_, render_view_host_,
render_view_host_->routing_id(), render_view_host_->routing_id(),
success); success);
}
} }
IOThreadExtensionFunction::IOThreadExtensionFunction() IOThreadExtensionFunction::IOThreadExtensionFunction()
...@@ -187,14 +191,7 @@ void IOThreadExtensionFunction::SendResponse(bool success) { ...@@ -187,14 +191,7 @@ void IOThreadExtensionFunction::SendResponse(bool success) {
ipc_sender(), routing_id_, success); ipc_sender(), routing_id_, success);
} }
AsyncExtensionFunction::AsyncExtensionFunction() : delegate_(NULL) { AsyncExtensionFunction::AsyncExtensionFunction() {
}
void AsyncExtensionFunction::SendResponse(bool success) {
if (delegate_)
delegate_->OnSendResponse(this, success);
else
UIThreadExtensionFunction::SendResponse(success);
} }
AsyncExtensionFunction::~AsyncExtensionFunction() { AsyncExtensionFunction::~AsyncExtensionFunction() {
......
...@@ -208,10 +208,20 @@ class ExtensionFunction ...@@ -208,10 +208,20 @@ class ExtensionFunction
// this category. // this category.
class UIThreadExtensionFunction : public ExtensionFunction { class UIThreadExtensionFunction : public ExtensionFunction {
public: public:
// A delegate for use in testing, to intercept the call to SendResponse.
class DelegateForTests {
public:
virtual void OnSendResponse(UIThreadExtensionFunction* function,
bool success) = 0;
};
UIThreadExtensionFunction(); UIThreadExtensionFunction();
virtual UIThreadExtensionFunction* AsUIThreadExtensionFunction() OVERRIDE; virtual UIThreadExtensionFunction* AsUIThreadExtensionFunction() OVERRIDE;
void set_test_delegate(DelegateForTests* delegate) {
delegate_ = delegate;
}
// Set the profile which contains the extension that has originated this // Set the profile which contains the extension that has originated this
// function call. // function call.
void set_profile(Profile* profile) { profile_ = profile; } void set_profile(Profile* profile) { profile_ = profile; }
...@@ -285,6 +295,8 @@ class UIThreadExtensionFunction : public ExtensionFunction { ...@@ -285,6 +295,8 @@ class UIThreadExtensionFunction : public ExtensionFunction {
virtual void Destruct() const OVERRIDE; virtual void Destruct() const OVERRIDE;
scoped_ptr<RenderViewHostTracker> tracker_; scoped_ptr<RenderViewHostTracker> tracker_;
DelegateForTests* delegate_;
}; };
// Extension functions that run on the IO thread. This type of function avoids // Extension functions that run on the IO thread. This type of function avoids
...@@ -340,24 +352,10 @@ class IOThreadExtensionFunction : public ExtensionFunction { ...@@ -340,24 +352,10 @@ class IOThreadExtensionFunction : public ExtensionFunction {
// the browser's UI thread*. // the browser's UI thread*.
class AsyncExtensionFunction : public UIThreadExtensionFunction { class AsyncExtensionFunction : public UIThreadExtensionFunction {
public: public:
// A delegate for use in testing, to intercept the call to SendResponse.
class DelegateForTests {
public:
virtual void OnSendResponse(AsyncExtensionFunction* function,
bool success) = 0;
};
AsyncExtensionFunction(); AsyncExtensionFunction();
virtual void SendResponse(bool success) OVERRIDE;
void set_test_delegate(DelegateForTests* delegate) {
delegate_ = delegate;
}
protected: protected:
virtual ~AsyncExtensionFunction(); virtual ~AsyncExtensionFunction();
DelegateForTests* delegate_;
}; };
// A SyncExtensionFunction is an ExtensionFunction that runs synchronously // A SyncExtensionFunction is an ExtensionFunction that runs synchronously
......
...@@ -142,28 +142,10 @@ base::Value* RunFunctionAndReturnResult(UIThreadExtensionFunction* function, ...@@ -142,28 +142,10 @@ base::Value* RunFunctionAndReturnResult(UIThreadExtensionFunction* function,
return function->GetResultValue()->DeepCopy(); return function->GetResultValue()->DeepCopy();
} }
void RunFunction(UIThreadExtensionFunction* function,
const std::string& args,
Browser* browser,
RunFunctionFlags flags) {
scoped_ptr<base::ListValue> parsed_args(ParseList(args));
ASSERT_TRUE(parsed_args.get()) <<
"Could not parse extension function arguments: " << args;
function->SetArgs(parsed_args.get());
TestFunctionDispatcherDelegate dispatcher_delegate(browser);
ExtensionFunctionDispatcher dispatcher(
browser->profile(), &dispatcher_delegate);
function->set_dispatcher(dispatcher.AsWeakPtr());
function->set_profile(browser->profile());
function->set_include_incognito(flags & INCLUDE_INCOGNITO);
function->Run();
}
// This helps us be able to wait until an AsyncExtensionFunction calls // This helps us be able to wait until an AsyncExtensionFunction calls
// SendResponse. // SendResponse.
class SendResponseDelegate : public AsyncExtensionFunction::DelegateForTests { class SendResponseDelegate
: public UIThreadExtensionFunction::DelegateForTests {
public: public:
SendResponseDelegate() : should_post_quit_(false) {} SendResponseDelegate() : should_post_quit_(false) {}
...@@ -182,7 +164,8 @@ class SendResponseDelegate : public AsyncExtensionFunction::DelegateForTests { ...@@ -182,7 +164,8 @@ class SendResponseDelegate : public AsyncExtensionFunction::DelegateForTests {
return *response_.get(); return *response_.get();
} }
virtual void OnSendResponse(AsyncExtensionFunction* function, bool success) { virtual void OnSendResponse(UIThreadExtensionFunction* function,
bool success) {
ASSERT_FALSE(HasResponse()); ASSERT_FALSE(HasResponse());
response_.reset(new bool); response_.reset(new bool);
*response_ = success; *response_ = success;
...@@ -196,13 +179,25 @@ class SendResponseDelegate : public AsyncExtensionFunction::DelegateForTests { ...@@ -196,13 +179,25 @@ class SendResponseDelegate : public AsyncExtensionFunction::DelegateForTests {
bool should_post_quit_; bool should_post_quit_;
}; };
bool RunAsyncFunction(AsyncExtensionFunction* function, bool RunFunction(UIThreadExtensionFunction* function,
const std::string& args, const std::string& args,
Browser* browser, Browser* browser,
RunFunctionFlags flags) { RunFunctionFlags flags) {
SendResponseDelegate response_delegate; SendResponseDelegate response_delegate;
function->set_test_delegate(&response_delegate); function->set_test_delegate(&response_delegate);
RunFunction(function, args, browser, flags); scoped_ptr<base::ListValue> parsed_args(ParseList(args));
EXPECT_TRUE(parsed_args.get()) <<
"Could not parse extension function arguments: " << args;
function->SetArgs(parsed_args.get());
TestFunctionDispatcherDelegate dispatcher_delegate(browser);
ExtensionFunctionDispatcher dispatcher(
browser->profile(), &dispatcher_delegate);
function->set_dispatcher(dispatcher.AsWeakPtr());
function->set_profile(browser->profile());
function->set_include_incognito(flags & INCLUDE_INCOGNITO);
function->Run();
// If the RunImpl of |function| didn't already call SendResponse, run the // If the RunImpl of |function| didn't already call SendResponse, run the
// message loop until they do. // message loop until they do.
......
...@@ -49,8 +49,7 @@ enum RunFunctionFlags { ...@@ -49,8 +49,7 @@ enum RunFunctionFlags {
}; };
// Run |function| with |args| and return the resulting error. Adds an error to // Run |function| with |args| and return the resulting error. Adds an error to
// the current test if |function| returns a result. The caller releases // the current test if |function| returns a result.
// ownership of |function|.
std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function, std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function,
const std::string& args, const std::string& args,
Browser* browser, Browser* browser,
...@@ -60,8 +59,8 @@ std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function, ...@@ -60,8 +59,8 @@ std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function,
Browser* browser); Browser* browser);
// Run |function| with |args| and return the result. Adds an error to the // Run |function| with |args| and return the result. Adds an error to the
// current test if |function| returns an error. The caller releases ownership of // current test if |function| returns an error. The caller takes ownership of
// |function|. the caller takes ownership of the result. // the result.
base::Value* RunFunctionAndReturnResult(UIThreadExtensionFunction* function, base::Value* RunFunctionAndReturnResult(UIThreadExtensionFunction* function,
const std::string& args, const std::string& args,
Browser* browser, Browser* browser,
...@@ -70,28 +69,21 @@ base::Value* RunFunctionAndReturnResult(UIThreadExtensionFunction* function, ...@@ -70,28 +69,21 @@ base::Value* RunFunctionAndReturnResult(UIThreadExtensionFunction* function,
const std::string& args, const std::string& args,
Browser* browser); Browser* browser);
// Create and run |function| with |args|. The caller retains ownership of // Create and run |function| with |args|. Works with both synchronous and async
// |function|. // functions.
// //
// TODO(aa): It would be nice if |args| could be validated against the schema // TODO(aa): It would be nice if |args| could be validated against the schema
// that |function| expects. That way, we know that we are testing something // that |function| expects. That way, we know that we are testing something
// close to what the bindings would actually send. // close to what the bindings would actually send.
// //
// TODO(aa): I'm concerned that this style won't scale to all the bits and bobs // TODO(aa): I'm concerned that this style won't scale to all the bits and bobs
// we're going to need to frob for all the different extension functions. But we // we're going to need to frob for all the different extension functions. But
// can refactor when we see what is needed. // we can refactor when we see what is needed.
void RunFunction(UIThreadExtensionFunction* function, bool RunFunction(UIThreadExtensionFunction* function,
const std::string& args, const std::string& args,
Browser* browser, Browser* browser,
RunFunctionFlags flags); RunFunctionFlags flags);
// Similar to RunFunction, but doesn't return until |function| calls
// SendResponse. Returns the value |function| passed to SendResponse.
bool RunAsyncFunction(AsyncExtensionFunction* function,
const std::string& args,
Browser* browser,
RunFunctionFlags flags);
} // namespace extension_function_test_utils } // namespace extension_function_test_utils
#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_FUNCTION_TEST_UTILS_H_ #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_FUNCTION_TEST_UTILS_H_
...@@ -82,7 +82,7 @@ class ExtensionManagementApiEscalationTest : public ExtensionBrowserTest { ...@@ -82,7 +82,7 @@ class ExtensionManagementApiEscalationTest : public ExtensionBrowserTest {
scoped_refptr<SetEnabledFunction> function(new SetEnabledFunction); scoped_refptr<SetEnabledFunction> function(new SetEnabledFunction);
if (user_gesture) if (user_gesture)
function->set_user_gesture(true); function->set_user_gesture(true);
bool response = util::RunAsyncFunction( bool response = util::RunFunction(
function.get(), function.get(),
base::StringPrintf("[\"%s\", true]", kId), base::StringPrintf("[\"%s\", true]", kId),
browser(), browser(),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment