arguments_unittest.cc 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. // Copyright 2017 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 "gin/arguments.h"
  5. #include "base/bind.h"
  6. #include "gin/converter.h"
  7. #include "gin/object_template_builder.h"
  8. #include "gin/public/isolate_holder.h"
  9. #include "gin/test/v8_test.h"
  10. #include "v8/include/v8-context.h"
  11. #include "v8/include/v8-forward.h"
  12. #include "v8/include/v8-function.h"
  13. #include "v8/include/v8-object.h"
  14. #include "v8/include/v8-primitive.h"
  15. #include "v8/include/v8-script.h"
  16. #include "v8/include/v8-template.h"
  17. namespace gin {
  18. using ArgumentsTest = V8Test;
  19. // Test that Arguments::GetHolderCreationContext returns the proper context.
  20. TEST_F(ArgumentsTest, TestArgumentsHolderCreationContext) {
  21. v8::Isolate* isolate = instance_->isolate();
  22. v8::HandleScope handle_scope(isolate);
  23. v8::Local<v8::Context> creation_context = context_.Get(instance_->isolate());
  24. auto check_creation_context = [](v8::Local<v8::Context> expected_context,
  25. gin::Arguments* arguments) {
  26. EXPECT_EQ(expected_context, arguments->GetHolderCreationContext());
  27. };
  28. // Create an object that will compare GetHolderCreationContext() with
  29. // |creation_context|.
  30. v8::Local<v8::ObjectTemplate> object_template =
  31. ObjectTemplateBuilder(isolate)
  32. .SetMethod(
  33. "checkCreationContext",
  34. base::BindRepeating(check_creation_context, creation_context))
  35. .Build();
  36. v8::Local<v8::Object> object =
  37. object_template->NewInstance(creation_context).ToLocalChecked();
  38. // Call checkCreationContext() on the generated object using the passed-in
  39. // context as the current context.
  40. auto test_context = [object, isolate](v8::Local<v8::Context> context) {
  41. v8::Context::Scope context_scope(context);
  42. const char kCallFunction[] = "(function(o) { o.checkCreationContext(); })";
  43. v8::Local<v8::Script> script =
  44. v8::Script::Compile(context, StringToV8(isolate, kCallFunction))
  45. .ToLocalChecked();
  46. v8::Local<v8::Function> function;
  47. ASSERT_TRUE(ConvertFromV8(isolate, script->Run(context).ToLocalChecked(),
  48. &function));
  49. v8::Local<v8::Value> args[] = {object};
  50. function->Call(context, v8::Undefined(isolate), std::size(args), args)
  51. .ToLocalChecked();
  52. };
  53. // Test calling in the creation context.
  54. test_context(creation_context);
  55. {
  56. // Create a second context, and test calling in that. The creation context
  57. // should be the same (even though the current context has changed).
  58. v8::Local<v8::Context> second_context =
  59. v8::Context::New(isolate, nullptr, v8::Local<v8::ObjectTemplate>());
  60. test_context(second_context);
  61. }
  62. }
  63. TEST_F(ArgumentsTest, TestGetAll) {
  64. v8::Isolate* isolate = instance_->isolate();
  65. v8::HandleScope handle_scope(isolate);
  66. v8::Local<v8::Context> context = context_.Get(instance_->isolate());
  67. using V8List = std::vector<v8::Local<v8::Value>>;
  68. V8List list1 = {
  69. gin::ConvertToV8(isolate, 1), gin::StringToV8(isolate, "some string"),
  70. gin::ConvertToV8(isolate, std::vector<double>({2.0, 3.0})),
  71. };
  72. bool called1 = false;
  73. V8List list2 = {
  74. gin::StringToV8(isolate, "some other string"),
  75. gin::ConvertToV8(isolate, 42),
  76. };
  77. bool called2 = false;
  78. V8List list3; // Empty list.
  79. bool called3 = false;
  80. auto check_arguments = [](V8List* expected, bool* called,
  81. gin::Arguments* arguments) {
  82. *called = true;
  83. V8List actual = arguments->GetAll();
  84. ASSERT_EQ(expected->size(), actual.size());
  85. for (size_t i = 0; i < expected->size(); ++i)
  86. EXPECT_EQ(expected->at(i), actual[i]) << i;
  87. };
  88. // Create an object that will compare GetHolderCreationContext() with
  89. // |creation_context|.
  90. v8::Local<v8::ObjectTemplate> object_template =
  91. ObjectTemplateBuilder(isolate)
  92. .SetMethod("check1",
  93. base::BindRepeating(check_arguments, &list1, &called1))
  94. .SetMethod("check2",
  95. base::BindRepeating(check_arguments, &list2, &called2))
  96. .SetMethod("check3",
  97. base::BindRepeating(check_arguments, &list3, &called3))
  98. .Build();
  99. v8::Local<v8::Object> object =
  100. object_template->NewInstance(context).ToLocalChecked();
  101. auto do_check = [object, context](V8List& args, base::StringPiece key) {
  102. v8::Local<v8::Value> val;
  103. ASSERT_TRUE(
  104. object->Get(context, gin::StringToSymbol(context->GetIsolate(), key))
  105. .ToLocal(&val));
  106. ASSERT_TRUE(val->IsFunction());
  107. val.As<v8::Function>()
  108. ->Call(context, object, static_cast<int>(args.size()), args.data())
  109. .ToLocalChecked();
  110. };
  111. do_check(list1, "check1");
  112. EXPECT_TRUE(called1);
  113. do_check(list2, "check2");
  114. EXPECT_TRUE(called2);
  115. do_check(list3, "check3");
  116. EXPECT_TRUE(called3);
  117. }
  118. } // namespace gin