// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/message_loop/message_loop.h"
-#include "mojo/public/bindings/lib/remote_ptr.h"
+#include "mojo/public/bindings/allocation_scope.h"
+#include "mojo/public/bindings/remote_ptr.h"
+#include "mojo/public/environment/environment.h"
+#include "mojo/public/shell/application.h"
+#include "mojo/public/utility/run_loop.h"
#include "mojo/shell/service_manager.h"
#include "mojom/shell.h"
#include "mojom/test.h"
namespace shell {
namespace {
-class TestApp : public ShellClient {
+const char kTestURLString[] = "test:testService";
+
+struct TestContext {
+ TestContext() : num_impls(0) {}
+ std::string last_test_string;
+ int num_impls;
+};
+
+class TestServiceImpl :
+ public Service<TestService, TestServiceImpl, TestContext> {
public:
- TestApp(ScopedMessagePipeHandle shell_handle)
- : shell_(shell_handle.Pass(), this) {
- }
- virtual ~TestApp() {
- }
- virtual void AcceptConnection(ScopedMessagePipeHandle client_handle)
- MOJO_OVERRIDE {
- service_.reset(new TestServiceImpl(this, client_handle.Pass()));
+ TestServiceImpl() {}
+
+ virtual ~TestServiceImpl() {
+ --context()->num_impls;
}
- std::string GetLastTestString() {
- return service_->last_test_string_;
+
+ virtual void Test(const mojo::String& test_string) OVERRIDE {
+ context()->last_test_string = test_string.To<std::string>();
+ client()->AckTest();
}
- private:
- class TestServiceImpl : public TestService {
- public:
- TestServiceImpl(TestApp* service, ScopedMessagePipeHandle client_handle)
- : service_(service),
- client_(client_handle.Pass(), this) {
- }
- virtual ~TestServiceImpl() {
- }
- virtual void Test(const mojo::String& test_string) OVERRIDE {
- last_test_string_ = test_string.To<std::string>();
- client_->AckTest();
- }
- TestApp* service_;
- RemotePtr<TestClient> client_;
- std::string last_test_string_;
- };
- RemotePtr<Shell> shell_;
- scoped_ptr<TestServiceImpl> service_;
+ void Initialize(ServiceFactory<TestServiceImpl, TestContext>* service_factory,
+ ScopedMessagePipeHandle client_handle) {
+ Service<TestService, TestServiceImpl, TestContext>::Initialize(
+ service_factory, client_handle.Pass());
+ ++context()->num_impls;
+ }
};
class TestClientImpl : public TestClient {
public:
- explicit TestClientImpl(ScopedMessagePipeHandle service_handle)
+ explicit TestClientImpl(ScopedTestServiceHandle service_handle)
: service_(service_handle.Pass(), this),
quit_after_ack_(false) {
}
- virtual ~TestClientImpl() {
- }
+
+ virtual ~TestClientImpl() {}
+
virtual void AckTest() OVERRIDE {
if (quit_after_ack_)
- base::MessageLoop::current()->QuitNow();
+ mojo::RunLoop::current()->Quit();
}
+
void Test(std::string test_string) {
AllocationScope scope;
quit_after_ack_ = true;
service_->Test(mojo::String(test_string));
}
+
+ private:
RemotePtr<TestService> service_;
bool quit_after_ack_;
+ DISALLOW_COPY_AND_ASSIGN(TestClientImpl);
};
+} // namespace
class ServiceManagerTest : public testing::Test,
- public ServiceManager::Loader {
+ public ServiceManager::Loader {
public:
- ServiceManagerTest() {
- }
+ ServiceManagerTest() {}
- virtual ~ServiceManagerTest() {
- }
+ virtual ~ServiceManagerTest() {}
virtual void SetUp() OVERRIDE {
- GURL test_url("test:testService");
+ GURL test_url(kTestURLString);
service_manager_.reset(new ServiceManager);
service_manager_->SetLoaderForURL(this, test_url);
- MessagePipe pipe;
- test_client_.reset(new TestClientImpl(pipe.handle0.Pass()));
- service_manager_->Connect(test_url, pipe.handle1.Pass());
+
+ InterfacePipe<TestService, AnyInterface> pipe;
+ test_client_.reset(new TestClientImpl(pipe.handle_to_self.Pass()));
+ service_manager_->Connect(test_url, pipe.handle_to_peer.Pass());
}
virtual void TearDown() OVERRIDE {
}
virtual void Load(const GURL& url,
- ScopedMessagePipeHandle shell_handle) OVERRIDE {
- test_app_.reset(new TestApp(shell_handle.Pass()));
+ ScopedShellHandle shell_handle) OVERRIDE {
+ test_app_.reset(new Application(shell_handle.Pass()));
+ test_app_->AddServiceFactory(
+ new ServiceFactory<TestServiceImpl, TestContext>(&context_));
+ }
+
+ bool HasFactoryForTestURL() {
+ ServiceManager::TestAPI manager_test_api(service_manager_.get());
+ return manager_test_api.HasFactoryForURL(GURL(kTestURLString));
}
protected:
- base::MessageLoop loop_;
- scoped_ptr<TestApp> test_app_;
+ mojo::Environment env_;
+ mojo::RunLoop loop_;
+ TestContext context_;
+ scoped_ptr<Application> test_app_;
scoped_ptr<TestClientImpl> test_client_;
scoped_ptr<ServiceManager> service_manager_;
DISALLOW_COPY_AND_ASSIGN(ServiceManagerTest);
TEST_F(ServiceManagerTest, Basic) {
test_client_->Test("test");
loop_.Run();
- EXPECT_EQ(std::string("test"), test_app_->GetLastTestString());
+ EXPECT_EQ(std::string("test"), context_.last_test_string);
}
-} // namespace
+TEST_F(ServiceManagerTest, ClientError) {
+ test_client_->Test("test");
+ EXPECT_TRUE(HasFactoryForTestURL());
+ loop_.Run();
+ EXPECT_EQ(1, context_.num_impls);
+ test_client_.reset(NULL);
+ loop_.Run();
+ EXPECT_EQ(0, context_.num_impls);
+ EXPECT_FALSE(HasFactoryForTestURL());
+}
} // namespace shell
} // namespace mojo