Index: mojo/public/cpp/application/lib/application_test_base.cc |
diff --git a/mojo/public/cpp/application/lib/application_test_base.cc b/mojo/public/cpp/application/lib/application_test_base.cc |
index 9130c827cafba5c3c111bd998193c5e94d668a8b..72058a40f35a1b86a088054ee9f428938de51550 100644 |
--- a/mojo/public/cpp/application/lib/application_test_base.cc |
+++ b/mojo/public/cpp/application/lib/application_test_base.cc |
@@ -4,42 +4,54 @@ |
#include "mojo/public/cpp/application/application_test_base.h" |
-#include "mojo/public/cpp/application/application_delegate.h" |
#include "mojo/public/cpp/application/application_impl.h" |
+#include "mojo/public/cpp/bindings/binding.h" |
#include "mojo/public/cpp/environment/environment.h" |
#include "mojo/public/cpp/system/message_pipe.h" |
+#include "mojo/public/interfaces/application/application.mojom.h" |
namespace mojo { |
namespace test { |
namespace { |
- |
-// This shell handle is shared by multiple test application instances. |
-ShellPtr g_shell; |
// Share the application command-line arguments with multiple application tests. |
Array<String> g_args; |
-class ArgumentGrabber : public InterfaceImpl<Application> { |
- public: |
- ArgumentGrabber(Array<String>* args, ShellPtr shell) |
- : args_(args), shell_(shell.Pass()) { |
- shell_.set_client(this); |
+// Application request handle passed from the shell in MojoMain, stored in |
+// between SetUp()/TearDown() so we can (re-)intialize new ApplicationImpls. |
+InterfaceRequest<Application> g_application_request; |
+ |
+// Shell pointer passed in the initial mojo.Application.Initialize() call, |
+// stored in between initial setup and the first test and between SetUp/TearDown |
+// calls so we can (re-)initialize new ApplicationImpls. |
+ShellPtr g_shell; |
+ |
+void InitializeArgs(int argc, std::vector<const char*> argv) { |
+ MOJO_CHECK(g_args.is_null()); |
+ for (const char* arg : argv) { |
+ if (arg) |
+ g_args.push_back(arg); |
} |
+} |
+ |
+class ShellAndArgumentGrabber : public Application { |
+ public: |
+ ShellAndArgumentGrabber(Array<String>* args, |
+ InterfaceRequest<Application> application_request) |
+ : args_(args), binding_(this, application_request.Pass()) {} |
void WaitForInitialize() { |
// Initialize is always the first call made on Application. |
- shell_.WaitForIncomingMethodCall(); |
- } |
- |
- ShellPtr UnbindShell() { |
- ShellPtr unbound_shell; |
- unbound_shell.Bind(shell_.PassMessagePipe()); |
- return unbound_shell.Pass(); |
+ binding_.WaitForIncomingMethodCall(); |
} |
private: |
// Application implementation. |
- void Initialize(Array<String> args) override { *args_ = args.Pass(); } |
+ void Initialize(ShellPtr shell, Array<String> args) override { |
+ *args_ = args.Pass(); |
+ g_application_request = binding_.Unbind(); |
+ g_shell = shell.Pass(); |
+ } |
void AcceptConnection(const String& requestor_url, |
InterfaceRequest<ServiceProvider> services, |
@@ -50,42 +62,31 @@ class ArgumentGrabber : public InterfaceImpl<Application> { |
void RequestQuit() override { MOJO_CHECK(false); } |
Array<String>* args_; |
- ShellPtr shell_; |
+ Binding<Application> binding_; |
}; |
-ShellPtr PassShellHandle() { |
- MOJO_CHECK(g_shell); |
- return g_shell.Pass(); |
-} |
- |
-void SetShellHandle(ShellPtr shell) { |
- MOJO_CHECK(shell); |
- MOJO_CHECK(!g_shell); |
- g_shell = shell.Pass(); |
-} |
- |
-void InitializeArgs(int argc, std::vector<const char*> argv) { |
- MOJO_CHECK(g_args.is_null()); |
- for (const char* arg : argv) { |
- if (arg) |
- g_args.push_back(arg); |
- } |
-} |
- |
} // namespace |
const Array<String>& Args() { |
return g_args; |
} |
-MojoResult RunAllTests(ShellPtr shell) { |
+MojoResult RunAllTests(MojoHandle application_request_handle) { |
{ |
// This loop is used for init, and then destroyed before running tests. |
Environment::InstantiateDefaultRunLoop(); |
+ // Grab the shell handle and GTEST commandline arguments. |
+ // GTEST command line arguments are supported amid application arguments: |
+ // $ mojo_shell mojo:example_apptests |
+ // --args-for='mojo:example_apptests arg1 --gtest_filter=foo arg2' |
Array<String> args; |
- ArgumentGrabber grab(&args, shell.Pass()); |
- grab.WaitForInitialize(); |
+ ShellAndArgumentGrabber grabber( |
+ &args, MakeRequest<Application>(MakeScopedHandle( |
+ MessagePipeHandle(application_request_handle)))); |
+ grabber.WaitForInitialize(); |
+ MOJO_CHECK(g_shell); |
+ MOJO_CHECK(g_application_request.is_pending()); |
// InitGoogleTest expects (argc + 1) elements, including a terminating null. |
// It also removes GTEST arguments from |argv| and updates the |argc| count. |
@@ -98,7 +99,6 @@ MojoResult RunAllTests(ShellPtr shell) { |
argv[argc] = nullptr; |
testing::InitGoogleTest(&argc, const_cast<char**>(&(argv[0]))); |
- SetShellHandle(grab.UnbindShell()); |
InitializeArgs(argc, argv); |
Environment::DestroyDefaultRunLoop(); |
@@ -106,8 +106,9 @@ MojoResult RunAllTests(ShellPtr shell) { |
int result = RUN_ALL_TESTS(); |
- shell = mojo::test::PassShellHandle(); |
- shell.reset(); |
+ // Shut down our message pipes before exiting. |
+ (void)g_application_request.PassMessagePipe(); |
+ (void)g_shell.PassMessagePipe(); |
return (result == 0) ? MOJO_RESULT_OK : MOJO_RESULT_UNKNOWN; |
} |
@@ -122,26 +123,28 @@ ApplicationDelegate* ApplicationTestBase::GetApplicationDelegate() { |
return &default_application_delegate_; |
} |
-void ApplicationTestBase::SetUpWithArgs(const Array<String>& args) { |
+void ApplicationTestBase::SetUp() { |
// A run loop is recommended for ApplicationImpl initialization and |
// communication. |
if (ShouldCreateDefaultRunLoop()) |
Environment::InstantiateDefaultRunLoop(); |
+ MOJO_CHECK(g_application_request.is_pending()); |
+ MOJO_CHECK(g_shell); |
+ |
// New applications are constructed for each test to avoid persisting state. |
application_impl_ = new ApplicationImpl(GetApplicationDelegate(), |
- PassShellHandle()); |
+ g_application_request.Pass()); |
// Fake application initialization with the given command line arguments. |
- application_impl_->Initialize(args.Clone()); |
-} |
- |
-void ApplicationTestBase::SetUp() { |
- SetUpWithArgs(Args()); |
+ application_impl_->Initialize(g_shell.Pass(), g_args.Clone()); |
} |
void ApplicationTestBase::TearDown() { |
- SetShellHandle(application_impl_->UnbindShell()); |
+ MOJO_CHECK(!g_application_request.is_pending()); |
+ MOJO_CHECK(!g_shell); |
+ |
+ application_impl_->UnbindConnections(&g_application_request, &g_shell); |
delete application_impl_; |
if (ShouldCreateDefaultRunLoop()) |
Environment::DestroyDefaultRunLoop(); |