module_registry_unittest.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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#include "gin/modules/module_registry.h" 6 7#include "base/bind.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" 16 17namespace gin { 18 19namespace { 20 21struct TestHelper { 22 TestHelper(v8::Isolate* isolate) 23 : delegate(std::vector<base::FilePath>()), 24 runner(new ShellRunner(&delegate, isolate)), 25 scope(runner.get()) { 26 } 27 28 base::MessageLoop message_loop; 29 ModuleRunnerDelegate delegate; 30 scoped_ptr<ShellRunner> runner; 31 Runner::Scope scope; 32}; 33 34class ModuleRegistryObserverImpl : public ModuleRegistryObserver { 35 public: 36 ModuleRegistryObserverImpl() : did_add_count_(0) {} 37 38 virtual void OnDidAddPendingModule( 39 const std::string& id, 40 const std::vector<std::string>& dependencies) OVERRIDE { 41 did_add_count_++; 42 id_ = id; 43 dependencies_ = dependencies; 44 } 45 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_; } 49 50 private: 51 int did_add_count_; 52 std::string id_; 53 std::vector<std::string> dependencies_; 54 55 DISALLOW_COPY_AND_ASSIGN(ModuleRegistryObserverImpl); 56}; 57 58void NestedCallback(v8::Handle<v8::Value> value) { 59 FAIL() << "Should not be called"; 60} 61 62void OnModuleLoaded(TestHelper* helper, 63 v8::Isolate* isolate, 64 int64_t* counter, 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)); 71} 72 73} // namespace 74 75typedef V8Test ModuleRegistryTest; 76 77// Verifies ModuleRegistry is not available after ContextHolder has been 78// deleted. 79TEST_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>()); 84 { 85 ContextHolder context_holder(instance_->isolate()); 86 context_holder.SetContext(context); 87 ModuleRegistry* registry = ModuleRegistry::From(context); 88 EXPECT_TRUE(registry != NULL); 89 } 90 ModuleRegistry* registry = ModuleRegistry::From(context); 91 EXPECT_TRUE(registry == NULL); 92} 93 94// Verifies ModuleRegistryObserver is notified appropriately. 95TEST_F(ModuleRegistryTest, ModuleRegistryObserverTest) { 96 TestHelper helper(instance_->isolate()); 97 std::string source = 98 "define('id', ['dep1', 'dep2'], function() {" 99 " return function() {};" 100 "});"; 101 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]); 113} 114 115// Verifies that multiple LoadModule calls for the same module are handled 116// correctly. 117TEST_F(ModuleRegistryTest, LoadModuleTest) { 118 TestHelper helper(instance_->isolate()); 119 int64_t counter = 0; 120 std::string source = 121 "define('one', [], function() {" 122 " return 1;" 123 "});"; 124 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); 130 } 131 EXPECT_EQ(0, counter); 132 helper.runner->Run(source, "script"); 133 EXPECT_EQ(3, counter); 134} 135 136} // namespace gin 137