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_MODULE_SYSTEM_TEST_H_
6#define EXTENSIONS_RENDERER_MODULE_SYSTEM_TEST_H_
7
8#include "extensions/renderer/module_system.h"
9#include "extensions/renderer/scoped_persistent.h"
10#include "extensions/renderer/script_context.h"
11#include "gin/public/context_holder.h"
12#include "testing/gtest/include/gtest/gtest.h"
13#include "v8/include/v8.h"
14
15namespace extensions {
16
17class ModuleSystemTestEnvironment {
18 public:
19  class AssertNatives;
20  class StringSourceMap;
21
22  explicit ModuleSystemTestEnvironment(v8::Isolate* isolate);
23  ~ModuleSystemTestEnvironment();
24
25  // Register a named JS module in the module system.
26  void RegisterModule(const std::string& name, const std::string& code);
27
28  // Register a named JS module with source retrieved from a ResourceBundle.
29  void RegisterModule(const std::string& name, int resource_id);
30
31  // Register a named JS module in the module system and tell the module system
32  // to use it to handle any requireNative() calls for native modules with that
33  // name.
34  void OverrideNativeHandler(const std::string& name, const std::string& code);
35
36  // Registers |file_name| from chrome/test/data/extensions as a module name
37  // |module_name|.
38  void RegisterTestFile(const std::string& module_name,
39                        const std::string& file_name);
40
41  // Create an empty object in the global scope with name |name|.
42  v8::Handle<v8::Object> CreateGlobal(const std::string& name);
43
44  void ShutdownGin();
45
46  void ShutdownModuleSystem();
47
48  ModuleSystem* module_system() { return context_->module_system(); }
49
50  ScriptContext* context() { return context_.get(); }
51
52  v8::Isolate* isolate() { return isolate_; }
53
54  AssertNatives* assert_natives() { return assert_natives_; }
55
56 private:
57  v8::Isolate* isolate_;
58  scoped_ptr<gin::ContextHolder> context_holder_;
59  v8::HandleScope handle_scope_;
60  scoped_ptr<ScriptContext> context_;
61  AssertNatives* assert_natives_;
62  scoped_ptr<StringSourceMap> source_map_;
63
64  DISALLOW_COPY_AND_ASSIGN(ModuleSystemTestEnvironment);
65};
66
67// Test fixture for testing JS that makes use of the module system.
68//
69// Typically tests will look like:
70//
71// TEST_F(MyModuleSystemTest, TestStuff) {
72//   ModuleSystem::NativesEnabledScope natives_enabled(module_system_.get());
73//   RegisterModule("test", "requireNative('assert').AssertTrue(true);");
74//   module_system_->Require("test");
75// }
76//
77// By default a test will fail if no method in the native module 'assert' is
78// called. This behaviour can be overridden by calling ExpectNoAssertionsMade().
79class ModuleSystemTest : public testing::Test {
80 public:
81  ModuleSystemTest();
82  virtual ~ModuleSystemTest();
83
84  virtual void SetUp() OVERRIDE;
85  virtual void TearDown() OVERRIDE;
86
87 protected:
88  ModuleSystemTestEnvironment* env() { return env_.get(); }
89
90  scoped_ptr<ModuleSystemTestEnvironment> CreateEnvironment();
91
92  // Make the test fail if any asserts are called. By default a test will fail
93  // if no asserts are called.
94  void ExpectNoAssertionsMade();
95
96  // Runs promises that have been resolved. Resolved promises will not run
97  // until this is called.
98  void RunResolvedPromises();
99
100 private:
101  v8::Isolate* isolate_;
102  scoped_ptr<ModuleSystemTestEnvironment> env_;
103  bool should_assertions_be_made_;
104
105 private:
106  DISALLOW_COPY_AND_ASSIGN(ModuleSystemTest);
107};
108
109}  // namespace extensions
110
111#endif  // EXTENSIONS_RENDERER_MODULE_SYSTEM_TEST_H_
112