api_binding_test_util.cc 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. // Copyright 2016 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/bindings/api_binding_test_util.h"
  5. #include "base/json/json_reader.h"
  6. #include "base/json/json_writer.h"
  7. #include "base/strings/string_piece.h"
  8. #include "base/strings/string_util.h"
  9. #include "base/values.h"
  10. #include "content/public/renderer/v8_value_converter.h"
  11. #include "gin/converter.h"
  12. namespace extensions {
  13. namespace {
  14. // Common call function implementation. Calls the given |function| with the
  15. // specified |receiver| and arguments. If the call succeeds (doesn't throw an
  16. // error), populates |out_value| with the returned result. If the call does
  17. // throw, populates |out_error| with the thrown error.
  18. // Returns true if the function runs without throwing an error.
  19. bool RunFunctionImpl(v8::Local<v8::Function> function,
  20. v8::Local<v8::Context> context,
  21. v8::Local<v8::Value> receiver,
  22. int argc,
  23. v8::Local<v8::Value> argv[],
  24. v8::Local<v8::Value>* out_value,
  25. std::string* out_error) {
  26. v8::TryCatch try_catch(context->GetIsolate());
  27. v8::MaybeLocal<v8::Value> maybe_result =
  28. function->Call(context, receiver, argc, argv);
  29. if (try_catch.HasCaught()) {
  30. *out_error =
  31. gin::V8ToString(context->GetIsolate(), try_catch.Message()->Get());
  32. return false;
  33. }
  34. v8::Local<v8::Value> result;
  35. if (!maybe_result.ToLocal(&result)) {
  36. *out_error = "Could not convert result to v8::Local.";
  37. return false;
  38. }
  39. *out_value = result;
  40. return true;
  41. }
  42. } // namespace
  43. std::string ReplaceSingleQuotes(base::StringPiece str) {
  44. std::string result;
  45. base::ReplaceChars(str, "'", "\"", &result);
  46. return result;
  47. }
  48. base::Value ValueFromString(base::StringPiece str) {
  49. absl::optional<base::Value> value =
  50. base::JSONReader::Read(ReplaceSingleQuotes(str));
  51. if (!value) {
  52. ADD_FAILURE() << "Failed to parse " << str;
  53. return base::Value();
  54. }
  55. return std::move(value.value());
  56. }
  57. base::Value::List ListValueFromString(base::StringPiece str) {
  58. base::Value value = ValueFromString(str);
  59. if (value.is_none()) {
  60. return base::Value::List();
  61. }
  62. if (!value.is_list()) {
  63. ADD_FAILURE() << "Not a list: " << str;
  64. return base::Value::List();
  65. }
  66. return std::move(value.GetList());
  67. }
  68. base::Value::Dict DictValueFromString(base::StringPiece str) {
  69. base::Value value = ValueFromString(str);
  70. if (value.is_none()) {
  71. return base::Value::Dict();
  72. }
  73. if (!value.is_dict()) {
  74. ADD_FAILURE() << "Not a dict: " << str;
  75. return base::Value::Dict();
  76. }
  77. return std::move(value.GetDict());
  78. }
  79. std::unique_ptr<base::Value> DeprecatedValueFromString(base::StringPiece str) {
  80. std::unique_ptr<base::Value> value =
  81. base::JSONReader::ReadDeprecated(ReplaceSingleQuotes(str));
  82. EXPECT_TRUE(value) << str;
  83. return value;
  84. }
  85. std::unique_ptr<base::ListValue> DeprecatedListValueFromString(
  86. base::StringPiece str) {
  87. return base::ListValue::From(DeprecatedValueFromString(str));
  88. }
  89. std::unique_ptr<base::DictionaryValue> DeprecatedDictionaryValueFromString(
  90. base::StringPiece str) {
  91. return base::DictionaryValue::From(DeprecatedValueFromString(str));
  92. }
  93. std::string ValueToString(const base::Value& value) {
  94. std::string json;
  95. EXPECT_TRUE(base::JSONWriter::Write(value, &json));
  96. return json;
  97. }
  98. std::string V8ToString(v8::Local<v8::Value> value,
  99. v8::Local<v8::Context> context) {
  100. if (value.IsEmpty())
  101. return "empty";
  102. if (value->IsNull())
  103. return "null";
  104. if (value->IsUndefined())
  105. return "undefined";
  106. if (value->IsFunction())
  107. return "function";
  108. std::unique_ptr<base::Value> json = V8ToBaseValue(value, context);
  109. if (!json)
  110. return "unserializable";
  111. return ValueToString(*json);
  112. }
  113. v8::Local<v8::Value> V8ValueFromScriptSource(v8::Local<v8::Context> context,
  114. base::StringPiece source) {
  115. v8::MaybeLocal<v8::Script> maybe_script = v8::Script::Compile(
  116. context, gin::StringToV8(context->GetIsolate(), source));
  117. v8::Local<v8::Script> script;
  118. if (!maybe_script.ToLocal(&script))
  119. return v8::Local<v8::Value>();
  120. return script->Run(context).ToLocalChecked();
  121. }
  122. v8::Local<v8::Function> FunctionFromString(v8::Local<v8::Context> context,
  123. base::StringPiece source) {
  124. v8::Local<v8::Value> value = V8ValueFromScriptSource(context, source);
  125. v8::Local<v8::Function> function;
  126. EXPECT_TRUE(gin::ConvertFromV8(context->GetIsolate(), value, &function));
  127. return function;
  128. }
  129. std::unique_ptr<base::Value> V8ToBaseValue(v8::Local<v8::Value> value,
  130. v8::Local<v8::Context> context) {
  131. return content::V8ValueConverter::Create()->FromV8Value(value, context);
  132. }
  133. v8::Local<v8::Value> RunFunction(v8::Local<v8::Function> function,
  134. v8::Local<v8::Context> context,
  135. v8::Local<v8::Value> receiver,
  136. int argc,
  137. v8::Local<v8::Value> argv[]) {
  138. std::string error;
  139. v8::Local<v8::Value> result;
  140. EXPECT_TRUE(
  141. RunFunctionImpl(function, context, receiver, argc, argv, &result, &error))
  142. << error;
  143. EXPECT_FALSE(result.IsEmpty());
  144. return result;
  145. }
  146. v8::Local<v8::Value> RunFunction(v8::Local<v8::Function> function,
  147. v8::Local<v8::Context> context,
  148. int argc,
  149. v8::Local<v8::Value> argv[]) {
  150. return RunFunction(function, context, v8::Undefined(context->GetIsolate()),
  151. argc, argv);
  152. }
  153. v8::Local<v8::Value> RunFunctionOnGlobal(v8::Local<v8::Function> function,
  154. v8::Local<v8::Context> context,
  155. int argc,
  156. v8::Local<v8::Value> argv[]) {
  157. return RunFunction(function, context, context->Global(), argc, argv);
  158. }
  159. void RunFunctionOnGlobalAndIgnoreResult(v8::Local<v8::Function> function,
  160. v8::Local<v8::Context> context,
  161. int argc,
  162. v8::Local<v8::Value> argv[]) {
  163. RunFunction(function, context, context->Global(), argc, argv);
  164. }
  165. v8::Global<v8::Value> RunFunctionOnGlobalAndReturnHandle(
  166. v8::Local<v8::Function> function,
  167. v8::Local<v8::Context> context,
  168. int argc,
  169. v8::Local<v8::Value> argv[]) {
  170. return v8::Global<v8::Value>(
  171. context->GetIsolate(),
  172. RunFunction(function, context, context->Global(), argc, argv));
  173. }
  174. void RunFunctionAndExpectError(v8::Local<v8::Function> function,
  175. v8::Local<v8::Context> context,
  176. v8::Local<v8::Value> receiver,
  177. int argc,
  178. v8::Local<v8::Value> argv[],
  179. const std::string& expected_error) {
  180. std::string error;
  181. v8::Local<v8::Value> result;
  182. EXPECT_FALSE(RunFunctionImpl(function, context, receiver, argc, argv, &result,
  183. &error));
  184. EXPECT_TRUE(result.IsEmpty());
  185. EXPECT_EQ(expected_error, error);
  186. }
  187. void RunFunctionAndExpectError(v8::Local<v8::Function> function,
  188. v8::Local<v8::Context> context,
  189. int argc,
  190. v8::Local<v8::Value> argv[],
  191. const std::string& expected_error) {
  192. RunFunctionAndExpectError(function, context,
  193. v8::Undefined(context->GetIsolate()), argc, argv,
  194. expected_error);
  195. }
  196. v8::Local<v8::Value> GetPropertyFromObject(v8::Local<v8::Object> object,
  197. v8::Local<v8::Context> context,
  198. base::StringPiece key) {
  199. v8::Local<v8::Value> result;
  200. EXPECT_TRUE(object->Get(context, gin::StringToV8(context->GetIsolate(), key))
  201. .ToLocal(&result));
  202. return result;
  203. }
  204. std::unique_ptr<base::Value> GetBaseValuePropertyFromObject(
  205. v8::Local<v8::Object> object,
  206. v8::Local<v8::Context> context,
  207. base::StringPiece key) {
  208. return V8ToBaseValue(GetPropertyFromObject(object, context, key), context);
  209. }
  210. std::string GetStringPropertyFromObject(v8::Local<v8::Object> object,
  211. v8::Local<v8::Context> context,
  212. base::StringPiece key) {
  213. return V8ToString(GetPropertyFromObject(object, context, key), context);
  214. }
  215. bool ValueTypeChecker<v8::Function>::IsType(v8::Local<v8::Value> value) {
  216. return value->IsFunction();
  217. }
  218. bool ValueTypeChecker<v8::Object>::IsType(v8::Local<v8::Value> value) {
  219. return value->IsObject();
  220. }
  221. bool ValueTypeChecker<v8::Promise>::IsType(v8::Local<v8::Value> value) {
  222. return value->IsPromise();
  223. }
  224. bool ValueTypeChecker<v8::Array>::IsType(v8::Local<v8::Value> value) {
  225. return value->IsArray();
  226. }
  227. } // namespace extensions