Index: mojo/examples/test/example_apptest.cc |
diff --git a/mojo/examples/test/example_apptest.cc b/mojo/examples/test/example_apptest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..830b9fef597f61f1e992363146f80faf44cd7eca |
--- /dev/null |
+++ b/mojo/examples/test/example_apptest.cc |
@@ -0,0 +1,159 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+// README: To run these tests from out/<Debug|Release>/, run: |
+// ./mojo_shell --origin=file://`pwd` --disable-cache mojo:mojo_example_apptests |
+ |
+// TODO(msw): Use mojo_main_chromium.cc mojo_environment_chromium for base/ |
+// not mojo_main_standalone.cc and mojo_environment_standalone ??? |
+// (a mojo_main_chromium app can test standalone services and apps) |
+ |
+#include "mojo/examples/test/example_service.mojom.h" |
+#include "mojo/public/cpp/application/application_delegate.h" |
+#include "mojo/public/cpp/application/application_impl.h" |
+#include "mojo/public/cpp/bindings/callback.h" |
+#include "mojo/public/cpp/environment/environment.h" |
+#include "mojo/public/cpp/system/macros.h" |
+#include "mojo/public/cpp/utility/run_loop.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace { |
+ |
+// TODO(msw): Remove these once we can get ApplicationImpl from TLS. ??? |
+mojo::ApplicationImpl* g_application_impl_hack = NULL; |
+mojo::RunLoop* g_run_loop_hack = NULL; |
+ |
+} // namespace |
+ |
+namespace mojo { |
+ |
+namespace { |
+ |
+// TODO(msw): Split example_service_apptest and example_client_apptest ??? |
+class ExampleClientImpl : public InterfaceImpl<ExampleClient> { |
+ public: |
+ explicit ExampleClientImpl() : last_pong_value_(0) {} |
+ virtual ~ExampleClientImpl() {} |
+ |
+ int16_t last_pong_value() const { return last_pong_value_; } |
+ |
+ private: |
+ // InterfaceImpl<ExampleClient> overrides. |
+ virtual void Pong(uint16_t pong_value) MOJO_OVERRIDE { |
+ last_pong_value_ = pong_value; |
+ g_run_loop_hack->Quit(); |
+ } |
+ |
+ int16_t last_pong_value_; |
+ MOJO_DISALLOW_COPY_AND_ASSIGN(ExampleClientImpl); |
+}; |
+ |
+// TODO(msw): Split example_service_apptest and example_client_apptest ??? |
+class ExampleServiceTest : public testing::Test { |
+ public: |
+ ExampleServiceTest() { |
+ g_application_impl_hack->ConnectToService("mojo:mojo_example_service", |
+ &example_service_); |
+ example_service_.set_client(&example_client_); |
+ } |
+ |
+ virtual ~ExampleServiceTest() MOJO_OVERRIDE { |
+ example_service_.reset(); |
+ } |
+ |
+ protected: |
+ ExampleServicePtr example_service_; |
+ ExampleClientImpl example_client_; |
+ |
+ private: |
+ MOJO_DISALLOW_COPY_AND_ASSIGN(ExampleServiceTest); |
+}; |
+ |
+TEST_F(ExampleServiceTest, Ping) { |
+ EXPECT_EQ(0, example_client_.last_pong_value()); |
+ example_service_->Ping(1); |
+ g_run_loop_hack->Run(); |
+ EXPECT_EQ(1, example_client_.last_pong_value()); |
+} |
+ |
+// TODO(msw): Attempt mojo::Callbacks without base::Bind ??? |
+template <typename T> |
+struct SetAndQuit : public Callback<void()>::Runnable { |
+ SetAndQuit(T* val, T result) : val_(val), result_(result) {} |
+ virtual ~SetAndQuit() {} |
+ virtual void Run() const MOJO_OVERRIDE{ |
+ *val_ = result_; |
+ g_run_loop_hack->Quit(); |
+ } |
+ T* val_; |
+ T result_; |
+}; |
+ |
+TEST_F(ExampleServiceTest, RunCallback) { |
+ bool was_run = false; |
+ example_service_->RunCallback(SetAndQuit<bool>(&was_run, true)); |
+ g_run_loop_hack->Run(); |
+ EXPECT_TRUE(was_run); |
+} |
+ |
+// TODO(msw): Attempt mojo::Callbacks without base::Bind ??? |
+struct RunAllTests : public Callback<void()>::Runnable { |
+ RunAllTests() {} |
+ virtual ~RunAllTests() {} |
+ virtual void Run() const MOJO_OVERRIDE { |
+ int success = RUN_ALL_TESTS(); |
+ printf("RUN_ALL_TESTS returned %d.\n", success); |
+ } |
+}; |
+ |
+// TODO(msw): Generalize a base class like this for ShellHooks help, etc. ??? |
+class TestApp : public ApplicationDelegate { |
+ public: |
+ TestApp() {} |
+ virtual ~TestApp() {} |
+ |
+ virtual void Initialize(ApplicationImpl* app) MOJO_OVERRIDE { |
+ printf("Running TestApp::Initialize() from example_apptest.cc\n"); |
+ // TODO(msw): Get actual commandline arguments ... |
+ int argc = 0; |
+ char** argv = NULL; |
+ testing::InitGoogleTest(&argc, argv); |
+ |
+ // TODO(msw): Calling RUN_ALL_TESTS here yields "Bus error: 10" ... |
+ MojoTimeTicks run_all_tests_delay = 0; |
+ g_run_loop_hack->PostDelayedTask(RunAllTests(), run_all_tests_delay); |
+ } |
+ |
+ private: |
+ MOJO_DISALLOW_COPY_AND_ASSIGN(TestApp); |
+}; |
+ |
+} // namespace |
+ |
+// TODO(msw): Move this and TestApp to a common mojo test helper ... |
+// static |
+ApplicationDelegate* ApplicationDelegate::Create() { |
+ return new TestApp(); |
+} |
+ |
+} // namespace mojo |
+ |
+extern "C" APPLICATION_EXPORT MojoResult CDECL MojoMain( |
+ MojoHandle shell_handle) { |
+ mojo::Environment env; |
+ // TODO(msw): Don't run a loop here, only within tests as needed ??? |
+ mojo::RunLoop loop; |
+ g_run_loop_hack = &loop; |
+ |
+ mojo::ApplicationDelegate* delegate = mojo::ApplicationDelegate::Create(); |
+ mojo::ApplicationImpl app(delegate); |
+ app.BindShell(shell_handle); |
+ g_application_impl_hack = &app; |
+ g_run_loop_hack->RunUntilIdle(); |
+ |
+ printf("Exiting MojoMain.\n"); |
+ |
+ delete delegate; |
+ return MOJO_RESULT_OK; |
+} |