module_system_unittest.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  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. #include "extensions/renderer/module_system.h"
  5. #include <stdint.h>
  6. #include <memory>
  7. #include <utility>
  8. #include "base/bind.h"
  9. #include "extensions/renderer/module_system_test.h"
  10. namespace extensions {
  11. class CounterNatives : public ObjectBackedNativeHandler {
  12. public:
  13. explicit CounterNatives(ScriptContext* context)
  14. : ObjectBackedNativeHandler(context), counter_(0) {}
  15. // ObjectBackedNativeHandler:
  16. void AddRoutes() override {
  17. RouteHandlerFunction("Get", base::BindRepeating(&CounterNatives::Get,
  18. base::Unretained(this)));
  19. RouteHandlerFunction("Increment",
  20. base::BindRepeating(&CounterNatives::Increment,
  21. base::Unretained(this)));
  22. }
  23. void Get(const v8::FunctionCallbackInfo<v8::Value>& args) {
  24. args.GetReturnValue().Set(static_cast<int32_t>(counter_));
  25. }
  26. void Increment(const v8::FunctionCallbackInfo<v8::Value>& args) {
  27. counter_++;
  28. }
  29. private:
  30. int counter_;
  31. };
  32. class TestExceptionHandler : public ModuleSystem::ExceptionHandler {
  33. public:
  34. TestExceptionHandler()
  35. : ModuleSystem::ExceptionHandler(nullptr), handled_exception_(false) {}
  36. void HandleUncaughtException(const v8::TryCatch& try_catch) override {
  37. handled_exception_ = true;
  38. }
  39. bool handled_exception() const { return handled_exception_; }
  40. private:
  41. bool handled_exception_;
  42. };
  43. TEST_F(ModuleSystemTest, TestExceptionHandling) {
  44. ModuleSystem::NativesEnabledScope natives_enabled_scope(
  45. env()->module_system());
  46. TestExceptionHandler* handler = new TestExceptionHandler;
  47. std::unique_ptr<ModuleSystem::ExceptionHandler> scoped_handler(handler);
  48. ASSERT_FALSE(handler->handled_exception());
  49. env()->module_system()->SetExceptionHandlerForTest(std::move(scoped_handler));
  50. env()->RegisterModule("test", "throw 'hi';");
  51. env()->module_system()->Require("test");
  52. ASSERT_TRUE(handler->handled_exception());
  53. ExpectNoAssertionsMade();
  54. }
  55. TEST_F(ModuleSystemTest, TestRequire) {
  56. ModuleSystem::NativesEnabledScope natives_enabled_scope(
  57. env()->module_system());
  58. env()->RegisterModule("add",
  59. "exports.$set('Add',"
  60. "function(x, y) { return x + y; });");
  61. env()->RegisterModule("test",
  62. "var Add = require('add').Add;"
  63. "requireNative('assert').AssertTrue(Add(3, 5) == 8);");
  64. env()->module_system()->Require("test");
  65. }
  66. TEST_F(ModuleSystemTest, TestNestedRequire) {
  67. ModuleSystem::NativesEnabledScope natives_enabled_scope(
  68. env()->module_system());
  69. env()->RegisterModule("add",
  70. "exports.$set('Add',"
  71. "function(x, y) { return x + y; });");
  72. env()->RegisterModule("double",
  73. "var Add = require('add').Add;"
  74. "exports.$set('Double',"
  75. "function(x) { return Add(x, x); });");
  76. env()->RegisterModule("test",
  77. "var Double = require('double').Double;"
  78. "requireNative('assert').AssertTrue(Double(3) == 6);");
  79. env()->module_system()->Require("test");
  80. }
  81. TEST_F(ModuleSystemTest, TestModuleInsulation) {
  82. ModuleSystem::NativesEnabledScope natives_enabled_scope(
  83. env()->module_system());
  84. env()->RegisterModule("x",
  85. "var x = 10;"
  86. "exports.$set('X', function() { return x; });");
  87. env()->RegisterModule("y",
  88. "var x = 15;"
  89. "require('x');"
  90. "exports.$set('Y', function() { return x; });");
  91. env()->RegisterModule("test",
  92. "var Y = require('y').Y;"
  93. "var X = require('x').X;"
  94. "var assert = requireNative('assert');"
  95. "assert.AssertTrue(!this.hasOwnProperty('x'));"
  96. "assert.AssertTrue(Y() == 15);"
  97. "assert.AssertTrue(X() == 10);");
  98. env()->module_system()->Require("test");
  99. }
  100. TEST_F(ModuleSystemTest, TestNativesAreDisabledOutsideANativesEnabledScope) {
  101. env()->RegisterModule("test",
  102. "var assert;"
  103. "try {"
  104. " assert = requireNative('assert');"
  105. "} catch (e) {"
  106. " var caught = true;"
  107. "}"
  108. "if (assert) {"
  109. " assert.AssertTrue(true);"
  110. "}");
  111. env()->module_system()->Require("test");
  112. ExpectNoAssertionsMade();
  113. }
  114. TEST_F(ModuleSystemTest, TestNativesAreEnabledWithinANativesEnabledScope) {
  115. env()->RegisterModule("test",
  116. "var assert = requireNative('assert');"
  117. "assert.AssertTrue(true);");
  118. {
  119. ModuleSystem::NativesEnabledScope natives_enabled(env()->module_system());
  120. {
  121. ModuleSystem::NativesEnabledScope natives_enabled_inner(
  122. env()->module_system());
  123. }
  124. env()->module_system()->Require("test");
  125. }
  126. }
  127. TEST_F(ModuleSystemTest, TestLazyField) {
  128. ModuleSystem::NativesEnabledScope natives_enabled_scope(
  129. env()->module_system());
  130. env()->RegisterModule("lazy", "exports.$set('x', 5);");
  131. v8::Local<v8::Object> object = env()->CreateGlobal("object");
  132. env()->SetLazyField(object, "blah", "lazy", "x");
  133. env()->RegisterModule("test",
  134. "var assert = requireNative('assert');"
  135. "assert.AssertTrue(object.blah == 5);");
  136. env()->module_system()->Require("test");
  137. }
  138. TEST_F(ModuleSystemTest, TestLazyFieldYieldingObject) {
  139. ModuleSystem::NativesEnabledScope natives_enabled_scope(
  140. env()->module_system());
  141. env()->RegisterModule(
  142. "lazy",
  143. "var object = {};"
  144. "object.__defineGetter__('z', function() { return 1; });"
  145. "object.x = 5;"
  146. "object.y = function() { return 10; };"
  147. "exports.$set('object', object);");
  148. v8::Local<v8::Object> object = env()->CreateGlobal("object");
  149. env()->SetLazyField(object, "thing", "lazy", "object");
  150. env()->RegisterModule("test",
  151. "var assert = requireNative('assert');"
  152. "assert.AssertTrue(object.thing.x == 5);"
  153. "assert.AssertTrue(object.thing.y() == 10);"
  154. "assert.AssertTrue(object.thing.z == 1);");
  155. env()->module_system()->Require("test");
  156. }
  157. TEST_F(ModuleSystemTest, TestLazyFieldIsOnlyEvaledOnce) {
  158. ModuleSystem::NativesEnabledScope natives_enabled_scope(
  159. env()->module_system());
  160. env()->module_system()->RegisterNativeHandler(
  161. "counter",
  162. std::unique_ptr<NativeHandler>(new CounterNatives(env()->context())));
  163. env()->RegisterModule("lazy",
  164. "requireNative('counter').Increment();"
  165. "exports.$set('x', 5);");
  166. v8::Local<v8::Object> object = env()->CreateGlobal("object");
  167. env()->SetLazyField(object, "x", "lazy", "x");
  168. env()->RegisterModule("test",
  169. "var assert = requireNative('assert');"
  170. "var counter = requireNative('counter');"
  171. "assert.AssertTrue(counter.Get() == 0);"
  172. "object.x;"
  173. "assert.AssertTrue(counter.Get() == 1);"
  174. "object.x;"
  175. "assert.AssertTrue(counter.Get() == 1);");
  176. env()->module_system()->Require("test");
  177. }
  178. TEST_F(ModuleSystemTest, TestRequireNativesAfterLazyEvaluation) {
  179. ModuleSystem::NativesEnabledScope natives_enabled_scope(
  180. env()->module_system());
  181. env()->RegisterModule("lazy", "exports.$set('x', 5);");
  182. v8::Local<v8::Object> object = env()->CreateGlobal("object");
  183. env()->SetLazyField(object, "x", "lazy", "x");
  184. env()->RegisterModule("test",
  185. "object.x;"
  186. "requireNative('assert').AssertTrue(true);");
  187. env()->module_system()->Require("test");
  188. }
  189. TEST_F(ModuleSystemTest, TestTransitiveRequire) {
  190. ModuleSystem::NativesEnabledScope natives_enabled_scope(
  191. env()->module_system());
  192. env()->RegisterModule("dependency", "exports.$set('x', 5);");
  193. env()->RegisterModule("lazy",
  194. "exports.$set('output', require('dependency'));");
  195. v8::Local<v8::Object> object = env()->CreateGlobal("object");
  196. env()->SetLazyField(object, "thing", "lazy", "output");
  197. env()->RegisterModule("test",
  198. "var assert = requireNative('assert');"
  199. "assert.AssertTrue(object.thing.x == 5);");
  200. env()->module_system()->Require("test");
  201. }
  202. TEST_F(ModuleSystemTest, TestModulesOnlyGetEvaledOnce) {
  203. ModuleSystem::NativesEnabledScope natives_enabled_scope(
  204. env()->module_system());
  205. env()->module_system()->RegisterNativeHandler(
  206. "counter",
  207. std::unique_ptr<NativeHandler>(new CounterNatives(env()->context())));
  208. env()->RegisterModule("incrementsWhenEvaled",
  209. "requireNative('counter').Increment();");
  210. env()->RegisterModule("test",
  211. "var assert = requireNative('assert');"
  212. "var counter = requireNative('counter');"
  213. "assert.AssertTrue(counter.Get() == 0);"
  214. "require('incrementsWhenEvaled');"
  215. "assert.AssertTrue(counter.Get() == 1);"
  216. "require('incrementsWhenEvaled');"
  217. "assert.AssertTrue(counter.Get() == 1);");
  218. env()->module_system()->Require("test");
  219. }
  220. TEST_F(ModuleSystemTest, TestOverrideNativeHandler) {
  221. ModuleSystem::NativesEnabledScope natives_enabled_scope(
  222. env()->module_system());
  223. env()->OverrideNativeHandler("assert",
  224. "exports.$set('AssertTrue', function() {});");
  225. env()->RegisterModule("test", "requireNative('assert').AssertTrue(true);");
  226. ExpectNoAssertionsMade();
  227. env()->module_system()->Require("test");
  228. }
  229. TEST_F(ModuleSystemTest, TestOverrideNonExistentNativeHandler) {
  230. ModuleSystem::NativesEnabledScope natives_enabled_scope(
  231. env()->module_system());
  232. env()->OverrideNativeHandler("thing", "exports.$set('x', 5);");
  233. env()->RegisterModule("test",
  234. "var assert = requireNative('assert');"
  235. "assert.AssertTrue(requireNative('thing').x == 5);");
  236. env()->module_system()->Require("test");
  237. }
  238. TEST_F(ModuleSystemTest, TestPrivatesIsPrivate) {
  239. ModuleSystem::NativesEnabledScope natives_enabled_scope(
  240. env()->module_system());
  241. env()->RegisterModule(
  242. "test",
  243. "var v = privates({});"
  244. "requireNative('assert').AssertFalse(v instanceof Object);");
  245. env()->module_system()->Require("test");
  246. }
  247. TEST_F(ModuleSystemTest, TestLoadScript) {
  248. ModuleSystem::NativesEnabledScope natives_enabled_scope(
  249. env()->module_system());
  250. env()->RegisterModule("add",
  251. "var addFunction = function(x, y) { return x + y; };");
  252. env()->RegisterModule(
  253. "test",
  254. "loadScript('add');"
  255. "requireNative('assert').AssertTrue(addFunction(3, 5) == 8);");
  256. env()->module_system()->Require("test");
  257. RunResolvedPromises();
  258. }
  259. } // namespace extensions