1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file. 4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "gin/modules/module_registry.h" 6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/bind.h" 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/message_loop/message_loop.h" 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "gin/modules/module_registry_observer.h" 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "gin/modules/module_runner_delegate.h" 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "gin/public/context_holder.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "gin/public/isolate_holder.h" 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "gin/shell_runner.h" 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "gin/test/v8_test.h" 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "v8/include/v8.h" 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace gin { 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace { 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)struct TestHelper { 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TestHelper(v8::Isolate* isolate) 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : delegate(std::vector<base::FilePath>()), 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) runner(new ShellRunner(&delegate, isolate)), 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scope(runner.get()) { 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::MessageLoop message_loop; 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ModuleRunnerDelegate delegate; 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<ShellRunner> runner; 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Runner::Scope scope; 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class ModuleRegistryObserverImpl : public ModuleRegistryObserver { 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public: 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ModuleRegistryObserverImpl() : did_add_count_(0) {} 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void OnDidAddPendingModule( 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& id, 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::vector<std::string>& dependencies) OVERRIDE { 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) did_add_count_++; 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) id_ = id; 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) dependencies_ = dependencies; 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int did_add_count() { return did_add_count_; } 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& id() const { return id_; } 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::vector<std::string>& dependencies() const { return dependencies_; } 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private: 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int did_add_count_; 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string id_; 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<std::string> dependencies_; 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ModuleRegistryObserverImpl); 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid NestedCallback(v8::Handle<v8::Value> value) { 59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FAIL() << "Should not be called"; 60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 62116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid OnModuleLoaded(TestHelper* helper, 63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch v8::Isolate* isolate, 64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int64_t* counter, 65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch v8::Handle<v8::Value> value) { 66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ASSERT_TRUE(value->IsNumber()); 67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch v8::Handle<v8::Integer> int_value = v8::Handle<v8::Integer>::Cast(value); 68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *counter += int_value->Value(); 69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ModuleRegistry::From(helper->runner->GetContextHolder()->context()) 70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ->LoadModule(isolate, "two", base::Bind(NestedCallback)); 71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)typedef V8Test ModuleRegistryTest; 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Verifies ModuleRegistry is not available after ContextHolder has been 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// deleted. 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(ModuleRegistryTest, DestroyedWithContext) { 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Isolate::Scope isolate_scope(instance_->isolate()); 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::HandleScope handle_scope(instance_->isolate()); 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Handle<v8::Context> context = v8::Context::New( 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) instance_->isolate(), NULL, v8::Handle<v8::ObjectTemplate>()); 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) { 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ContextHolder context_holder(instance_->isolate()); 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) context_holder.SetContext(context); 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ModuleRegistry* registry = ModuleRegistry::From(context); 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(registry != NULL); 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ModuleRegistry* registry = ModuleRegistry::From(context); 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(registry == NULL); 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Verifies ModuleRegistryObserver is notified appropriately. 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(ModuleRegistryTest, ModuleRegistryObserverTest) { 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TestHelper helper(instance_->isolate()); 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string source = 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "define('id', ['dep1', 'dep2'], function() {" 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) " return function() {};" 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "});"; 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ModuleRegistryObserverImpl observer; 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ModuleRegistry::From(helper.runner->GetContextHolder()->context())-> 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AddObserver(&observer); 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) helper.runner->Run(source, "script"); 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ModuleRegistry::From(helper.runner->GetContextHolder()->context())-> 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RemoveObserver(&observer); 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(1, observer.did_add_count()); 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ("id", observer.id()); 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_EQ(2u, observer.dependencies().size()); 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ("dep1", observer.dependencies()[0]); 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ("dep2", observer.dependencies()[1]); 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Verifies that multiple LoadModule calls for the same module are handled 116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// correctly. 117116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(ModuleRegistryTest, LoadModuleTest) { 118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch TestHelper helper(instance_->isolate()); 119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int64_t counter = 0; 120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::string source = 121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "define('one', [], function() {" 122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch " return 1;" 123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "});"; 124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ModuleRegistry::LoadModuleCallback callback = 126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(OnModuleLoaded, &helper, instance_->isolate(), &counter); 127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (int i = 0; i < 3; i++) { 128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ModuleRegistry::From(helper.runner->GetContextHolder()->context()) 129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ->LoadModule(instance_->isolate(), "one", callback); 130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(0, counter); 132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch helper.runner->Run(source, "script"); 133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(3, counter); 134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace gin 137