1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef EXTENSIONS_RENDERER_API_TEST_BASE_H_
6#define EXTENSIONS_RENDERER_API_TEST_BASE_H_
7
8#include <map>
9#include <string>
10#include <utility>
11
12#include "base/message_loop/message_loop.h"
13#include "base/run_loop.h"
14#include "extensions/renderer/module_system_test.h"
15#include "extensions/renderer/v8_schema_registry.h"
16#include "gin/handle.h"
17#include "gin/modules/module_registry.h"
18#include "gin/object_template_builder.h"
19#include "gin/wrappable.h"
20#include "mojo/bindings/js/handle.h"
21#include "mojo/public/cpp/bindings/interface_request.h"
22#include "mojo/public/cpp/system/core.h"
23
24namespace extensions {
25
26class V8SchemaRegistry;
27
28// A ServiceProvider that provides access from JS modules to services registered
29// by AddService() calls.
30class TestServiceProvider : public gin::Wrappable<TestServiceProvider> {
31 public:
32  static gin::Handle<TestServiceProvider> Create(v8::Isolate* isolate);
33  virtual ~TestServiceProvider();
34
35  virtual gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
36      v8::Isolate* isolate) OVERRIDE;
37
38  template <typename Interface>
39  void AddService(const base::Callback<void(mojo::InterfaceRequest<Interface>)>
40                      service_factory) {
41    service_factories_.insert(std::make_pair(
42        Interface::Name_,
43        base::Bind(ForwardToServiceFactory<Interface>, service_factory)));
44  }
45
46  static gin::WrapperInfo kWrapperInfo;
47
48 private:
49  TestServiceProvider();
50
51  mojo::Handle ConnectToService(const std::string& service_name);
52
53  template <typename Interface>
54  static void ForwardToServiceFactory(
55      const base::Callback<void(mojo::InterfaceRequest<Interface>)>
56          service_factory,
57      mojo::ScopedMessagePipeHandle handle) {
58    service_factory.Run(mojo::MakeRequest<Interface>(handle.Pass()));
59  }
60  std::map<std::string, base::Callback<void(mojo::ScopedMessagePipeHandle)> >
61      service_factories_;
62};
63
64// A base class for unit testing apps/extensions API custom bindings implemented
65// on Mojo services. To use:
66// 1. Register test Mojo service implementations on service_provider().
67// 2. Write JS tests in extensions/test/data/test_file.js.
68// 3. Write one C++ test function for each JS test containing
69//    RunTest("test_file.js", "testFunctionName").
70// See extensions/renderer/api_test_base_unittest.cc and
71// extensions/test/data/api_test_base_unittest.js for sample usage.
72class ApiTestBase : public ModuleSystemTest {
73 protected:
74  ApiTestBase();
75  virtual ~ApiTestBase();
76  virtual void SetUp() OVERRIDE;
77  void RunTest(const std::string& file_name, const std::string& test_name);
78  TestServiceProvider* service_provider() { return service_provider_; }
79
80 private:
81  void RegisterModules();
82  void InitializeEnvironment();
83  void RunTestInner(const std::string& test_name,
84                    const base::Closure& quit_closure);
85  void RunPromisesAgain();
86
87  base::MessageLoop message_loop_;
88  TestServiceProvider* service_provider_;
89  scoped_ptr<V8SchemaRegistry> v8_schema_registry_;
90};
91
92}  // namespace extensions
93
94#endif  // EXTENSIONS_RENDERER_API_TEST_BASE_H_
95