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.
5 #include "gin/modules/module_registry.h"
8 #include "gin/modules/module_registry_observer.h"
9 #include "gin/modules/module_runner_delegate.h"
10 #include "gin/public/context_holder.h"
11 #include "gin/public/isolate_holder.h"
12 #include "gin/shell_runner.h"
13 #include "gin/test/v8_test.h"
14 #include "v8/include/v8.h"
21 TestHelper(v8::Isolate
* isolate
)
22 : delegate(std::vector
<base::FilePath
>()),
23 runner(new ShellRunner(&delegate
, isolate
)),
27 ModuleRunnerDelegate delegate
;
28 scoped_ptr
<ShellRunner
> runner
;
32 class ModuleRegistryObserverImpl
: public ModuleRegistryObserver
{
34 ModuleRegistryObserverImpl() : did_add_count_(0) {}
36 void OnDidAddPendingModule(
37 const std::string
& id
,
38 const std::vector
<std::string
>& dependencies
) override
{
41 dependencies_
= dependencies
;
44 int did_add_count() { return did_add_count_
; }
45 const std::string
& id() const { return id_
; }
46 const std::vector
<std::string
>& dependencies() const { return dependencies_
; }
51 std::vector
<std::string
> dependencies_
;
53 DISALLOW_COPY_AND_ASSIGN(ModuleRegistryObserverImpl
);
56 void NestedCallback(v8::Local
<v8::Value
> value
) {
57 FAIL() << "Should not be called";
60 void OnModuleLoaded(TestHelper
* helper
,
63 v8::Local
<v8::Value
> value
) {
64 ASSERT_TRUE(value
->IsNumber());
65 v8::Local
<v8::Integer
> int_value
= v8::Local
<v8::Integer
>::Cast(value
);
66 *counter
+= int_value
->Value();
67 ModuleRegistry::From(helper
->runner
->GetContextHolder()->context())
68 ->LoadModule(isolate
, "two", base::Bind(NestedCallback
));
71 void OnModuleLoadedNoOp(v8::Local
<v8::Value
> value
) {
72 ASSERT_TRUE(value
->IsNumber());
77 typedef V8Test ModuleRegistryTest
;
79 // Verifies ModuleRegistry is not available after ContextHolder has been
81 TEST_F(ModuleRegistryTest
, DestroyedWithContext
) {
82 v8::Isolate::Scope
isolate_scope(instance_
->isolate());
83 v8::HandleScope
handle_scope(instance_
->isolate());
84 v8::Local
<v8::Context
> context
= v8::Context::New(
85 instance_
->isolate(), NULL
, v8::Local
<v8::ObjectTemplate
>());
87 ContextHolder
context_holder(instance_
->isolate());
88 context_holder
.SetContext(context
);
89 ModuleRegistry
* registry
= ModuleRegistry::From(context
);
90 EXPECT_TRUE(registry
!= NULL
);
92 ModuleRegistry
* registry
= ModuleRegistry::From(context
);
93 EXPECT_TRUE(registry
== NULL
);
96 // Verifies ModuleRegistryObserver is notified appropriately.
97 TEST_F(ModuleRegistryTest
, ModuleRegistryObserverTest
) {
98 TestHelper
helper(instance_
->isolate());
100 "define('id', ['dep1', 'dep2'], function() {"
101 " return function() {};"
104 ModuleRegistryObserverImpl observer
;
105 ModuleRegistry::From(helper
.runner
->GetContextHolder()->context())->
106 AddObserver(&observer
);
107 helper
.runner
->Run(source
, "script");
108 ModuleRegistry::From(helper
.runner
->GetContextHolder()->context())->
109 RemoveObserver(&observer
);
110 EXPECT_EQ(1, observer
.did_add_count());
111 EXPECT_EQ("id", observer
.id());
112 ASSERT_EQ(2u, observer
.dependencies().size());
113 EXPECT_EQ("dep1", observer
.dependencies()[0]);
114 EXPECT_EQ("dep2", observer
.dependencies()[1]);
117 // Verifies that multiple LoadModule calls for the same module are handled
119 TEST_F(ModuleRegistryTest
, LoadModuleTest
) {
120 TestHelper
helper(instance_
->isolate());
123 "define('one', [], function() {"
127 ModuleRegistry::LoadModuleCallback callback
=
128 base::Bind(OnModuleLoaded
, &helper
, instance_
->isolate(), &counter
);
129 for (int i
= 0; i
< 3; i
++) {
130 ModuleRegistry::From(helper
.runner
->GetContextHolder()->context())
131 ->LoadModule(instance_
->isolate(), "one", callback
);
133 EXPECT_EQ(0, counter
);
134 helper
.runner
->Run(source
, "script");
135 EXPECT_EQ(3, counter
);
138 // Verifies that explicitly loading a module that's already pending does
139 // not cause the ModuleRegistry's unsatisfied_dependency set to grow.
140 TEST_F(ModuleRegistryTest
, UnsatisfiedDependenciesTest
) {
141 TestHelper
helper(instance_
->isolate());
143 "define('one', ['no_such_module'], function(nsm) {"
146 ModuleRegistry
* registry
=
147 ModuleRegistry::From(helper
.runner
->GetContextHolder()->context());
149 std::set
<std::string
> no_such_module_set
;
150 no_such_module_set
.insert("no_such_module");
152 // Adds one unsatisfied dependency on "no-such-module".
153 helper
.runner
->Run(source
, "script");
154 EXPECT_EQ(no_such_module_set
, registry
->unsatisfied_dependencies());
156 // Should have no effect on the unsatisfied_dependencies set.
157 ModuleRegistry::LoadModuleCallback callback
= base::Bind(OnModuleLoadedNoOp
);
158 registry
->LoadModule(instance_
->isolate(), "one", callback
);
159 EXPECT_EQ(no_such_module_set
, registry
->unsatisfied_dependencies());