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 "base/message_loop/message_loop.h"
9 #include "gin/modules/module_registry_observer.h"
10 #include "gin/modules/module_runner_delegate.h"
11 #include "gin/public/context_holder.h"
12 #include "gin/public/isolate_holder.h"
13 #include "gin/shell_runner.h"
14 #include "gin/test/v8_test.h"
15 #include "v8/include/v8.h"
22 TestHelper(v8::Isolate
* isolate
)
23 : delegate(std::vector
<base::FilePath
>()),
24 runner(new ShellRunner(&delegate
, isolate
)),
28 base::MessageLoop message_loop
;
29 ModuleRunnerDelegate delegate
;
30 scoped_ptr
<ShellRunner
> runner
;
34 class ModuleRegistryObserverImpl
: public ModuleRegistryObserver
{
36 ModuleRegistryObserverImpl() : did_add_count_(0) {}
38 virtual void OnDidAddPendingModule(
39 const std::string
& id
,
40 const std::vector
<std::string
>& dependencies
) OVERRIDE
{
43 dependencies_
= dependencies
;
46 int did_add_count() { return did_add_count_
; }
47 const std::string
& id() const { return id_
; }
48 const std::vector
<std::string
>& dependencies() const { return dependencies_
; }
53 std::vector
<std::string
> dependencies_
;
55 DISALLOW_COPY_AND_ASSIGN(ModuleRegistryObserverImpl
);
58 void NestedCallback(v8::Handle
<v8::Value
> value
) {
59 FAIL() << "Should not be called";
62 void OnModuleLoaded(TestHelper
* helper
,
65 v8::Handle
<v8::Value
> value
) {
66 ASSERT_TRUE(value
->IsNumber());
67 v8::Handle
<v8::Integer
> int_value
= v8::Handle
<v8::Integer
>::Cast(value
);
68 *counter
+= int_value
->Value();
69 ModuleRegistry::From(helper
->runner
->GetContextHolder()->context())
70 ->LoadModule(isolate
, "two", base::Bind(NestedCallback
));
75 typedef V8Test ModuleRegistryTest
;
77 // Verifies ModuleRegistry is not available after ContextHolder has been
79 TEST_F(ModuleRegistryTest
, DestroyedWithContext
) {
80 v8::Isolate::Scope
isolate_scope(instance_
->isolate());
81 v8::HandleScope
handle_scope(instance_
->isolate());
82 v8::Handle
<v8::Context
> context
= v8::Context::New(
83 instance_
->isolate(), NULL
, v8::Handle
<v8::ObjectTemplate
>());
85 ContextHolder
context_holder(instance_
->isolate());
86 context_holder
.SetContext(context
);
87 ModuleRegistry
* registry
= ModuleRegistry::From(context
);
88 EXPECT_TRUE(registry
!= NULL
);
90 ModuleRegistry
* registry
= ModuleRegistry::From(context
);
91 EXPECT_TRUE(registry
== NULL
);
94 // Verifies ModuleRegistryObserver is notified appropriately.
95 TEST_F(ModuleRegistryTest
, ModuleRegistryObserverTest
) {
96 TestHelper
helper(instance_
->isolate());
98 "define('id', ['dep1', 'dep2'], function() {"
99 " return function() {};"
102 ModuleRegistryObserverImpl observer
;
103 ModuleRegistry::From(helper
.runner
->GetContextHolder()->context())->
104 AddObserver(&observer
);
105 helper
.runner
->Run(source
, "script");
106 ModuleRegistry::From(helper
.runner
->GetContextHolder()->context())->
107 RemoveObserver(&observer
);
108 EXPECT_EQ(1, observer
.did_add_count());
109 EXPECT_EQ("id", observer
.id());
110 ASSERT_EQ(2u, observer
.dependencies().size());
111 EXPECT_EQ("dep1", observer
.dependencies()[0]);
112 EXPECT_EQ("dep2", observer
.dependencies()[1]);
115 // Verifies that multiple LoadModule calls for the same module are handled
117 TEST_F(ModuleRegistryTest
, LoadModuleTest
) {
118 TestHelper
helper(instance_
->isolate());
121 "define('one', [], function() {"
125 ModuleRegistry::LoadModuleCallback callback
=
126 base::Bind(OnModuleLoaded
, &helper
, instance_
->isolate(), &counter
);
127 for (int i
= 0; i
< 3; i
++) {
128 ModuleRegistry::From(helper
.runner
->GetContextHolder()->context())
129 ->LoadModule(instance_
->isolate(), "one", callback
);
131 EXPECT_EQ(0, counter
);
132 helper
.runner
->Run(source
, "script");
133 EXPECT_EQ(3, counter
);