| Index: mojo/examples/apptest/example_apptest.cc
|
| diff --git a/mojo/examples/apptest/example_apptest.cc b/mojo/examples/apptest/example_apptest.cc
|
| index 7288608edb3692bad0325e6beaf1a8bf5689fdab..dba00e0f539d380ef916cf35767c46e9c1cf1113 100644
|
| --- a/mojo/examples/apptest/example_apptest.cc
|
| +++ b/mojo/examples/apptest/example_apptest.cc
|
| @@ -18,32 +18,83 @@
|
| #include "mojo/public/cpp/utility/run_loop.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| +namespace mojo {
|
| +
|
| namespace {
|
|
|
| -// TODO(msw): Remove this once we can get ApplicationImpl from TLS.
|
| -mojo::ApplicationImpl* g_application_impl_hack = NULL;
|
| +// This global shell handle is needed for repeated use by test applications.
|
| +MessagePipeHandle g_shell_message_pipe_handle_hack;
|
|
|
| -} // namespace
|
| +// Apptest is a GTEST base class for application testing executed in mojo_shell.
|
| +class Apptest : public testing::Test {
|
| + public:
|
| + explicit Apptest(Array<String> args)
|
| + : args_(args.Pass()),
|
| + application_impl_(nullptr) {
|
| + }
|
| + virtual ~Apptest() override {}
|
|
|
| -namespace mojo {
|
| + protected:
|
| + ApplicationImpl* application_impl() { return application_impl_; }
|
|
|
| -namespace {
|
| + // Get the ApplicationDelegate for the application to be tested.
|
| + virtual ApplicationDelegate* GetApplicationDelegate() = 0;
|
|
|
| -class ExampleApptest : public testing::Test {
|
| - public:
|
| - ExampleApptest() {
|
| - g_application_impl_hack->ConnectToService("mojo:mojo_example_service",
|
| - &example_service_);
|
| - example_service_.set_client(&example_client_);
|
| + // testing::Test:
|
| + virtual void SetUp() override {
|
| + // New applications are constructed for each test to avoid persisting state.
|
| + MOJO_CHECK(g_shell_message_pipe_handle_hack.is_valid());
|
| + application_impl_ = new ApplicationImpl(
|
| + GetApplicationDelegate(),
|
| + MakeScopedHandle(g_shell_message_pipe_handle_hack));
|
| +
|
| + // Fake application initialization with the given command line arguments.
|
| + application_impl_->Initialize(args_.Clone());
|
| }
|
| + virtual void TearDown() override {
|
| + g_shell_message_pipe_handle_hack =
|
| + application_impl_->UnbindShell().release();
|
| + 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_;
|
| +
|
| + // A run loop is needed for ApplicationImpl initialization and communication.
|
| + RunLoop run_loop_;
|
| +
|
| + MOJO_DISALLOW_COPY_AND_ASSIGN(Apptest);
|
| +};
|
| +
|
| +// ExampleApptest exemplifies 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:
|
| + ExampleClientApplication example_client_application_;
|
| +
|
| MOJO_DISALLOW_COPY_AND_ASSIGN(ExampleApptest);
|
| };
|
|
|
| @@ -64,9 +115,9 @@ TEST_F(ExampleApptest, PingServiceToPongClient) {
|
| }
|
|
|
| template <typename T>
|
| -struct SetAndQuit : public Callback<void()>::Runnable {
|
| - SetAndQuit(T* val, T result) : val_(val), result_(result) {}
|
| - virtual ~SetAndQuit() {}
|
| +struct SetCallback : public Callback<void()>::Runnable {
|
| + SetCallback(T* val, T result) : val_(val), result_(result) {}
|
| + virtual ~SetCallback() {}
|
| virtual void Run() const override { *val_ = result_; }
|
| T* val_;
|
| T result_;
|
| @@ -75,7 +126,7 @@ struct SetAndQuit : public Callback<void()>::Runnable {
|
| TEST_F(ExampleApptest, RunCallbackViaService) {
|
| // Test ExampleService callback functionality.
|
| bool was_run = false;
|
| - example_service_->RunCallback(SetAndQuit<bool>(&was_run, true));
|
| + example_service_->RunCallback(SetCallback<bool>(&was_run, true));
|
| EXPECT_TRUE(example_service_.WaitForIncomingMethodCall());
|
| EXPECT_TRUE(was_run);
|
| }
|
| @@ -85,18 +136,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 std::vector<std::string>& args = app.args();
|
| MOJO_CHECK(args.size() < INT_MAX);
|
| int argc = static_cast<int>(args.size());
|
| @@ -105,10 +160,14 @@ MojoResult MojoMain(MojoHandle shell_handle) {
|
| argv[i] = const_cast<char*>(args[i].data());
|
| argv[argc] = NULL;
|
| testing::InitGoogleTest(&argc, &argv[0]);
|
| + mojo::g_shell_message_pipe_handle_hack = app.UnbindShell().release();
|
| }
|
|
|
| mojo_ignore_result(RUN_ALL_TESTS());
|
|
|
| - delete delegate;
|
| + MojoResult result = MojoClose(mojo::g_shell_message_pipe_handle_hack.value());
|
| + MOJO_ALLOW_UNUSED_LOCAL(result);
|
| + assert(result == MOJO_RESULT_OK);
|
| +
|
| return MOJO_RESULT_OK;
|
| }
|
|
|