1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// found in the LICENSE file.
4116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/memory/scoped_ptr.h"
6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/renderer/module_system.h"
7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/renderer/module_system_test.h"
8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "gin/modules/module_registry.h"
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
10116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace extensions {
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass CounterNatives : public ObjectBackedNativeHandler {
13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public:
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  explicit CounterNatives(ScriptContext* context)
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      : ObjectBackedNativeHandler(context), counter_(0) {
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    RouteFunction("Get",
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                  base::Bind(&CounterNatives::Get, base::Unretained(this)));
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    RouteFunction(
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        "Increment",
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        base::Bind(&CounterNatives::Increment, base::Unretained(this)));
21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void Get(const v8::FunctionCallbackInfo<v8::Value>& args) {
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    args.GetReturnValue().Set(static_cast<int32_t>(counter_));
25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void Increment(const v8::FunctionCallbackInfo<v8::Value>& args) {
28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    counter_++;
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  int counter_;
33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass TestExceptionHandler : public ModuleSystem::ExceptionHandler {
36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public:
37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TestExceptionHandler() : handled_exception_(false) {}
38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void HandleUncaughtException(const v8::TryCatch& try_catch) OVERRIDE {
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    handled_exception_ = true;
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool handled_exception() const { return handled_exception_; }
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool handled_exception_;
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
49116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(ModuleSystemTest, TestExceptionHandling) {
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ModuleSystem::NativesEnabledScope natives_enabled_scope(
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      env()->module_system());
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TestExceptionHandler* handler = new TestExceptionHandler;
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<ModuleSystem::ExceptionHandler> scoped_handler(handler);
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_FALSE(handler->handled_exception());
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->SetExceptionHandlerForTest(scoped_handler.Pass());
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("test", "throw 'hi';");
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->Require("test");
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_TRUE(handler->handled_exception());
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ExpectNoAssertionsMade();
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
64116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(ModuleSystemTest, TestRequire) {
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ModuleSystem::NativesEnabledScope natives_enabled_scope(
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      env()->module_system());
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("add",
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "exports.Add = function(x, y) { return x + y; };");
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("test",
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "var Add = require('add').Add;"
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "requireNative('assert').AssertTrue(Add(3, 5) == 8);");
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->Require("test");
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
75116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(ModuleSystemTest, TestNestedRequire) {
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ModuleSystem::NativesEnabledScope natives_enabled_scope(
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      env()->module_system());
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("add",
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "exports.Add = function(x, y) { return x + y; };");
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("double",
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "var Add = require('add').Add;"
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "exports.Double = function(x) { return Add(x, x); };");
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("test",
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "var Double = require('double').Double;"
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "requireNative('assert').AssertTrue(Double(3) == 6);");
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->Require("test");
87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
89116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(ModuleSystemTest, TestModuleInsulation) {
90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ModuleSystem::NativesEnabledScope natives_enabled_scope(
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      env()->module_system());
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("x",
93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "var x = 10;"
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "exports.X = function() { return x; };");
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("y",
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "var x = 15;"
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "require('x');"
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "exports.Y = function() { return x; };");
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("test",
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "var Y = require('y').Y;"
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "var X = require('x').X;"
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "var assert = requireNative('assert');"
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "assert.AssertTrue(!this.hasOwnProperty('x'));"
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "assert.AssertTrue(Y() == 15);"
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "assert.AssertTrue(X() == 10);");
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->Require("test");
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
109116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(ModuleSystemTest, TestNativesAreDisabledOutsideANativesEnabledScope) {
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("test",
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "var assert;"
112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "try {"
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "  assert = requireNative('assert');"
114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "} catch (e) {"
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "  var caught = true;"
116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "}"
117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "if (assert) {"
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "  assert.AssertTrue(true);"
119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "}");
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->Require("test");
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ExpectNoAssertionsMade();
122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
124116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(ModuleSystemTest, TestNativesAreEnabledWithinANativesEnabledScope) {
125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("test",
126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "var assert = requireNative('assert');"
127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "assert.AssertTrue(true);");
128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  {
130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ModuleSystem::NativesEnabledScope natives_enabled(env()->module_system());
131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    {
132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ModuleSystem::NativesEnabledScope natives_enabled_inner(
133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          env()->module_system());
134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    env()->module_system()->Require("test");
136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
139116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(ModuleSystemTest, TestLazyField) {
140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ModuleSystem::NativesEnabledScope natives_enabled_scope(
141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      env()->module_system());
142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("lazy", "exports.x = 5;");
143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  v8::Handle<v8::Object> object = env()->CreateGlobal("object");
145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->SetLazyField(object, "blah", "lazy", "x");
147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("test",
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "var assert = requireNative('assert');"
150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "assert.AssertTrue(object.blah == 5);");
151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->Require("test");
152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
154116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(ModuleSystemTest, TestLazyFieldYieldingObject) {
155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ModuleSystem::NativesEnabledScope natives_enabled_scope(
156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      env()->module_system());
157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule(
158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "lazy",
159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "var object = {};"
160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "object.__defineGetter__('z', function() { return 1; });"
161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "object.x = 5;"
162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "object.y = function() { return 10; };"
163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "exports.object = object;");
164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  v8::Handle<v8::Object> object = env()->CreateGlobal("object");
166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->SetLazyField(object, "thing", "lazy", "object");
168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("test",
170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "var assert = requireNative('assert');"
171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "assert.AssertTrue(object.thing.x == 5);"
172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "assert.AssertTrue(object.thing.y() == 10);"
173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "assert.AssertTrue(object.thing.z == 1);");
174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->Require("test");
175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
177116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(ModuleSystemTest, TestLazyFieldIsOnlyEvaledOnce) {
178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ModuleSystem::NativesEnabledScope natives_enabled_scope(
179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      env()->module_system());
180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->RegisterNativeHandler(
181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "counter",
182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      scoped_ptr<NativeHandler>(new CounterNatives(env()->context())));
183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("lazy",
184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "requireNative('counter').Increment();"
185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "exports.x = 5;");
186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  v8::Handle<v8::Object> object = env()->CreateGlobal("object");
188116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->SetLazyField(object, "x", "lazy", "x");
190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("test",
192116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "var assert = requireNative('assert');"
193116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "var counter = requireNative('counter');"
194116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "assert.AssertTrue(counter.Get() == 0);"
195116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "object.x;"
196116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "assert.AssertTrue(counter.Get() == 1);"
197116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "object.x;"
198116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "assert.AssertTrue(counter.Get() == 1);");
199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->Require("test");
200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
202116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(ModuleSystemTest, TestRequireNativesAfterLazyEvaluation) {
203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ModuleSystem::NativesEnabledScope natives_enabled_scope(
204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      env()->module_system());
205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("lazy", "exports.x = 5;");
206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  v8::Handle<v8::Object> object = env()->CreateGlobal("object");
207116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->SetLazyField(object, "x", "lazy", "x");
209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("test",
210116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "object.x;"
211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "requireNative('assert').AssertTrue(true);");
212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->Require("test");
213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
215116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(ModuleSystemTest, TestTransitiveRequire) {
216116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ModuleSystem::NativesEnabledScope natives_enabled_scope(
217116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      env()->module_system());
218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("dependency", "exports.x = 5;");
219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("lazy", "exports.output = require('dependency');");
220116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  v8::Handle<v8::Object> object = env()->CreateGlobal("object");
222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->SetLazyField(object, "thing", "lazy", "output");
224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("test",
226116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "var assert = requireNative('assert');"
227116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "assert.AssertTrue(object.thing.x == 5);");
228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->Require("test");
229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
230116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
231116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(ModuleSystemTest, TestModulesOnlyGetEvaledOnce) {
232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ModuleSystem::NativesEnabledScope natives_enabled_scope(
233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      env()->module_system());
234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->RegisterNativeHandler(
235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "counter",
236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      scoped_ptr<NativeHandler>(new CounterNatives(env()->context())));
237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("incrementsWhenEvaled",
239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "requireNative('counter').Increment();");
240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("test",
241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "var assert = requireNative('assert');"
242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "var counter = requireNative('counter');"
243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "assert.AssertTrue(counter.Get() == 0);"
244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "require('incrementsWhenEvaled');"
245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "assert.AssertTrue(counter.Get() == 1);"
246116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "require('incrementsWhenEvaled');"
247116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "assert.AssertTrue(counter.Get() == 1);");
248116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
249116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->Require("test");
250116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
251116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
252116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(ModuleSystemTest, TestOverrideNativeHandler) {
253116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ModuleSystem::NativesEnabledScope natives_enabled_scope(
254116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      env()->module_system());
255116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->OverrideNativeHandler("assert", "exports.AssertTrue = function() {};");
256116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("test", "requireNative('assert').AssertTrue(true);");
257116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ExpectNoAssertionsMade();
258116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->Require("test");
259116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
260116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
261116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(ModuleSystemTest, TestOverrideNonExistentNativeHandler) {
262116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ModuleSystem::NativesEnabledScope natives_enabled_scope(
263116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      env()->module_system());
264116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->OverrideNativeHandler("thing", "exports.x = 5;");
265116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("test",
266116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "var assert = requireNative('assert');"
267116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "assert.AssertTrue(requireNative('thing').x == 5);");
268116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->Require("test");
269116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
270116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
271116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(ModuleSystemTest, TestRequireAsync) {
272116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ModuleSystem::NativesEnabledScope natives_enabled_scope(
273116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      env()->module_system());
274116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("add",
275116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "define('add', [], function() {"
276116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "  return { Add: function(x, y) { return x + y; } };"
277116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "});");
278116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("math",
279116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "define('math', ['add'], function(add) {"
280116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "  return { Add: add.Add };"
281116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "});");
282116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule(
283116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "test",
284116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "requireAsync('math').then(function(math) {"
285116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "  requireNative('assert').AssertTrue(math.Add(3, 5) == 8);"
286116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "});");
287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->Require("test");
288116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RunResolvedPromises();
289116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
290116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
291116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(ModuleSystemTest, TestRequireAsyncInParallel) {
292116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ModuleSystem::NativesEnabledScope natives_enabled_scope(
293116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      env()->module_system());
294116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("add",
295116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "define('add', [], function() {"
296116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "  return { Add: function(x, y) { return x + y; } };"
297116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "});");
298116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule(
299116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "subtract",
300116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "define('subtract', [], function() {"
301116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "  return { Subtract: function(x, y) { return x - y; } };"
302116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "});");
303116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule(
304116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "math",
305116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "exports.AddAndSubtract = function(x, y, z) {"
306116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "  return Promise.all([requireAsync('add'),"
307116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "                      requireAsync('subtract')"
308116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "  ]).then(function(modules) {"
309116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "    return modules[1].Subtract(modules[0].Add(x, y), z);"
310116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "  });"
311116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "};");
312116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("test",
313116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "var AddAndSubtract = require('math').AddAndSubtract;"
314116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "AddAndSubtract(3, 5, 2).then(function(result) {"
315116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "  requireNative('assert').AssertTrue(result == 6);"
316116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "});");
317116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->Require("test");
318116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RunResolvedPromises();
319116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
320116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
321116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(ModuleSystemTest, TestNestedRequireAsyncs) {
322116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ModuleSystem::NativesEnabledScope natives_enabled_scope(
323116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      env()->module_system());
324116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("first",
325116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "define('first', [], function() {"
326116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "  return { next: 'second' };"
327116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "});");
328116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("second",
329116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "define('second', [], function() {"
330116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "  return { next: '' };"
331116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "});");
332116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule(
333116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "test",
334116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "requireAsync('first').then(function(module) {"
335116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "  return requireAsync(module.next)"
336116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "}).then(function(module) {"
337116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "  requireNative('assert').AssertTrue(module.next === '');"
338116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "});");
339116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->Require("test");
340116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RunResolvedPromises();
341116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
342116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
343116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(ModuleSystemTest, TestRequireFromAMDModule) {
344116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ModuleSystem::NativesEnabledScope natives_enabled_scope(
345116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      env()->module_system());
346116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("add",
347116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "exports.Add = function(x, y) { return x + y; };");
348116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("math",
349116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "define('math', [], function() {"
350116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "  var add = require('add');"
351116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "  return { Add: add.Add };"
352116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "});");
353116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule(
354116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "test",
355116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "requireAsync('math').then(function(math) {"
356116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "  requireNative('assert').AssertTrue(math.Add(3, 5) == 8);"
357116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "});");
358116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->Require("test");
359116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RunResolvedPromises();
360116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
361116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
362116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(ModuleSystemTest, TestRequireAsyncFromAMDModule) {
363116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ModuleSystem::NativesEnabledScope natives_enabled_scope(
364116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      env()->module_system());
365116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("add",
366116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "define('add', [], function() {"
367116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "  return { Add: function(x, y) { return x + y; } };"
368116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "});");
369116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("math",
370116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "define('math', [], function() {"
371116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "  function Add(x, y) {"
372116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "    return requireAsync('add').then(function(add) {"
373116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "      return add.Add(x, y);"
374116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "    });"
375116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "  }"
376116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "  return { Add: Add };"
377116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "});");
378116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("test",
379116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "requireAsync('math').then(function(math) {"
380116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "  return math.Add(3, 6);"
381116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "}).then(function(result) {"
382116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "  requireNative('assert').AssertTrue(result == 9);"
383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "});");
384116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->Require("test");
385116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RunResolvedPromises();
386116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
387116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
388116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(ModuleSystemTest, TestRequireAsyncFromAnotherContext) {
389116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ModuleSystem::NativesEnabledScope natives_enabled_scope(
390116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      env()->module_system());
391116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule(
392116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "test",
393116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "requireAsync('natives').then(function(natives) {"
394116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "  natives.requireAsync('ping').then(function(ping) {"
395116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "    return ping();"
396116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "  }).then(function(result) {"
397116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "    requireNative('assert').AssertTrue(result == 'pong');"
398116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "  });"
399116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "});");
400116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<ModuleSystemTestEnvironment> other_env = CreateEnvironment();
401116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  other_env->RegisterModule("ping",
402116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            "define('ping', ['natives'], function(natives) {"
403116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            "  return function() {"
404116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            "    return 'pong';"
405116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            "  }"
406116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            "});");
407116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  gin::ModuleRegistry::From(env()->context()->v8_context())->AddBuiltinModule(
408116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      env()->isolate(), "natives", other_env->module_system()->NewInstance());
409116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  gin::ModuleRegistry::From(other_env->context()->v8_context())
410116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ->AddBuiltinModule(
411116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          env()->isolate(), "natives", env()->module_system()->NewInstance());
412116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->Require("test");
413116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RunResolvedPromises();
414116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
415116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
416116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(ModuleSystemTest, TestRequireAsyncBetweenContexts) {
417116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ModuleSystem::NativesEnabledScope natives_enabled_scope(
418116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      env()->module_system());
419116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("pong",
420116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "define('pong', [], function() {"
421116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "  return function() { return 'done'; };"
422116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "});");
423116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule(
424116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "test",
425116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "requireAsync('natives').then(function(natives) {"
426116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "  natives.requireAsync('ping').then(function(ping) {"
427116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "    return ping();"
428116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "  }).then(function(pong) {"
429116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "    return pong();"
430116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "  }).then(function(result) {"
431116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "    requireNative('assert').AssertTrue(result == 'done');"
432116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "  });"
433116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "});");
434116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<ModuleSystemTestEnvironment> other_env = CreateEnvironment();
435116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  other_env->RegisterModule("ping",
436116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            "define('ping', ['natives'], function(natives) {"
437116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            "  return function() {"
438116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            "    return natives.requireAsync('pong');"
439116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            "  }"
440116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            "});");
441116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  gin::ModuleRegistry::From(env()->context()->v8_context())->AddBuiltinModule(
442116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      env()->isolate(), "natives", other_env->module_system()->NewInstance());
443116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  gin::ModuleRegistry::From(other_env->context()->v8_context())
444116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ->AddBuiltinModule(
445116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          env()->isolate(), "natives", env()->module_system()->NewInstance());
446116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->Require("test");
447116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RunResolvedPromises();
448116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
449116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
450116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(ModuleSystemTest, TestRequireAsyncFromContextWithNoModuleRegistry) {
451116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ModuleSystem::NativesEnabledScope natives_enabled_scope(
452116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      env()->module_system());
453116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("test",
454116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "requireAsync('natives').then(function(natives) {"
455116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "  var AssertTrue = requireNative('assert').AssertTrue;"
456116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "  natives.requireAsync('foo').then(function() {"
457116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "    AssertTrue(false);"
458116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "  }).catch(function(error) {"
459116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "    AssertTrue(error.message == "
460116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "               'Extension view no longer exists');"
461116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "  });"
462116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "});");
463116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<ModuleSystemTestEnvironment> other_env = CreateEnvironment();
464116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  gin::ModuleRegistry::From(env()->context()->v8_context())->AddBuiltinModule(
465116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      env()->isolate(), "natives", other_env->module_system()->NewInstance());
466116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  other_env->ShutdownGin();
467116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->Require("test");
468116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RunResolvedPromises();
469116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
470116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
471116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(ModuleSystemTest, TestRequireAsyncFromContextWithNoModuleSystem) {
472116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ModuleSystem::NativesEnabledScope natives_enabled_scope(
473116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      env()->module_system());
474116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->RegisterModule("test",
475116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "requireAsync('natives').then(function(natives) {"
476116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "  requireNative('assert').AssertTrue("
477116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "      natives.requireAsync('foo') === undefined);"
478116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        "});");
479116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<ModuleSystemTestEnvironment> other_env = CreateEnvironment();
480116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  gin::ModuleRegistry::From(env()->context()->v8_context())->AddBuiltinModule(
481116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      env()->isolate(), "natives", other_env->module_system()->NewInstance());
482116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  other_env->ShutdownModuleSystem();
483116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  env()->module_system()->Require("test");
484116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RunResolvedPromises();
485116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
486116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
487116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace extensions
488