Index: mojo/examples/apptest/example_apptest.cc |
diff --git a/mojo/examples/apptest/example_apptest.cc b/mojo/examples/apptest/example_apptest.cc |
index c754c85e3b7b56dc959a8a357fe54dc7531593e7..014c12e01a7db5fef93062660793028946e40955 100644 |
--- a/mojo/examples/apptest/example_apptest.cc |
+++ b/mojo/examples/apptest/example_apptest.cc |
@@ -18,32 +18,81 @@ |
#include "mojo/public/cpp/utility/run_loop.h" |
#include "testing/gtest/include/gtest/gtest.h" |
-namespace { |
- |
-// TODO(msw): Remove this once we can get ApplicationImpl from TLS. |
-mojo::ApplicationImpl* g_application_impl_hack = NULL; |
- |
-} // namespace |
- |
namespace mojo { |
namespace { |
-class ExampleApptest : public testing::Test { |
+// TODO(msw): Revise this shell handle hack used for multiple test applications. |
+ScopedMessagePipeHandle g_shell_scoped_message_pipe_handle_hack; |
+ |
+// A GTEST base class for application testing executed within mojo_shell. |
+class Apptest : public testing::Test { |
public: |
- ExampleApptest() { |
- g_application_impl_hack->ConnectToService("mojo:mojo_example_service", |
- &example_service_); |
- example_service_.set_client(&example_client_); |
+ explicit Apptest(Array<String> args) |
+ : args_(args.Pass()), |
+ application_impl_(NULL) { |
viettrungluu
2014/10/16 02:22:23
nit: nullptr instead of NULL
msw
2014/10/16 19:40:59
Done.
|
} |
+ virtual ~Apptest() override {} |
+ |
+ protected: |
+ ApplicationImpl* application_impl() { return application_impl_; } |
+ |
+ // Get the ApplicationDelegate used for application construction. |
+ virtual ApplicationDelegate* GetApplicationDelegate() = 0; |
+ |
+ // testing::Test: |
+ virtual void SetUp() override { |
+ // TODO(msw): Base classes shouldn't need to provide a RunLoop for this. |
+ // New applications are constructed for each test to avoid persisting state. |
+ MOJO_CHECK(g_shell_scoped_message_pipe_handle_hack.is_valid()); |
+ application_impl_ = new ApplicationImpl( |
+ GetApplicationDelegate(), |
+ g_shell_scoped_message_pipe_handle_hack.Pass()); |
+ |
+ // Fake application initialization with the given command line arguments. |
+ application_impl_->Initialize(args_.Clone()); |
+ } |
+ virtual void TearDown() override { |
+ g_shell_scoped_message_pipe_handle_hack = application_impl_->UnbindShell(); |
+ delete application_impl_; |
+ } |
+ |
+ private: |
+ // The command line arguments supplied to each test application instance. |
+ Array<String> args_; |
+ // The application implementation instance, reconstructed for each test. |
+ ApplicationImpl* application_impl_; |
+ |
+ MOJO_DISALLOW_COPY_AND_ASSIGN(Apptest); |
+}; |
+ |
+// A GTEST class exemplifying Apptest's application testing pattern. |
+class ExampleApptest : public Apptest { |
+ public: |
+ // TODO(msw): Exemplify the use of actual command line arguments. |
+ ExampleApptest() : Apptest(Array<String>()) {} |
virtual ~ExampleApptest() override {} |
protected: |
+ // Apptest: |
+ virtual ApplicationDelegate* GetApplicationDelegate() override { |
+ return &example_client_application_; |
+ } |
+ virtual void SetUp() override { |
+ Apptest::SetUp(); |
+ application_impl()->ConnectToService("mojo:mojo_example_service", |
+ &example_service_); |
+ example_service_.set_client(&example_client_); |
+ } |
+ |
ExampleServicePtr example_service_; |
ExampleClientImpl example_client_; |
private: |
+ RunLoop run_loop_; |
+ ExampleClientApplication example_client_application_; |
+ |
MOJO_DISALLOW_COPY_AND_ASSIGN(ExampleApptest); |
}; |
@@ -85,18 +134,22 @@ TEST_F(ExampleApptest, RunCallbackViaService) { |
} // namespace mojo |
MojoResult MojoMain(MojoHandle shell_handle) { |
- mojo::Environment env; |
- // TODO(msw): Destroy this ambient RunLoop before running tests. |
- // Need to CancelWait() / PassMessagePipe() from the ShellPtr? |
- mojo::RunLoop loop; |
- mojo::ApplicationDelegate* delegate = new mojo::ExampleClientApplication(); |
- mojo::ApplicationImpl app(delegate, shell_handle); |
- g_application_impl_hack = &app; |
- MOJO_CHECK(app.WaitForInitialize()); |
+ mojo::Environment environment; |
{ |
+ // This RunLoop is used for init, and then destroyed before running tests. |
+ mojo::RunLoop run_loop; |
+ |
+ // Construct an ApplicationImpl just for the GTEST commandline arguments. |
+ // GTEST command line arguments are supported amid application arguments: |
+ // mojo_shell 'mojo:mojo_example_apptest arg1 --gtest_filter=foo arg2' |
+ mojo::ApplicationDelegate dummy_application_delegate; |
+ mojo::ApplicationImpl app(&dummy_application_delegate, shell_handle); |
+ MOJO_CHECK(app.WaitForInitialize()); |
+ |
// InitGoogleTest expects (argc + 1) elements, including a terminating NULL. |
// It also removes GTEST arguments from |argv| and updates the |argc| count. |
+ // TODO(msw): Provide tests access to these actual command line arguments. |
const mojo::Array<mojo::String>& args = app.args(); |
MOJO_CHECK(args.size() < INT_MAX); |
int argc = static_cast<int>(args.size()); |
@@ -105,10 +158,9 @@ MojoResult MojoMain(MojoHandle shell_handle) { |
argv[i] = const_cast<char*>(args[i].data()); |
argv[argc] = NULL; |
testing::InitGoogleTest(&argc, &argv[0]); |
+ mojo::g_shell_scoped_message_pipe_handle_hack = app.UnbindShell(); |
} |
mojo_ignore_result(RUN_ALL_TESTS()); |
- |
- delete delegate; |
return MOJO_RESULT_OK; |
} |