LCOV - code coverage report
Current view: top level - test/unittests - test-utils.h (source / functions) Hit Total Coverage
Test: app.info Lines: 57 59 96.6 %
Date: 2019-03-21 Functions: 56 61 91.8 %

          Line data    Source code
       1             : // Copyright 2014 the V8 project 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             : 
       5             : #ifndef V8_UNITTESTS_TEST_UTILS_H_
       6             : #define V8_UNITTESTS_TEST_UTILS_H_
       7             : 
       8             : #include <vector>
       9             : 
      10             : #include "include/v8.h"
      11             : #include "src/api-inl.h"
      12             : #include "src/base/macros.h"
      13             : #include "src/base/utils/random-number-generator.h"
      14             : #include "src/handles.h"
      15             : #include "src/objects-inl.h"
      16             : #include "src/objects.h"
      17             : #include "src/zone/accounting-allocator.h"
      18             : #include "src/zone/zone.h"
      19             : #include "testing/gtest-support.h"
      20             : 
      21             : namespace v8 {
      22             : 
      23             : class ArrayBufferAllocator;
      24             : 
      25             : // RAII-like Isolate instance wrapper.
      26             : class IsolateWrapper final {
      27             :  public:
      28             :   // When enforce_pointer_compression is true the Isolate is created with
      29             :   // enabled pointer compression. When it's false then the Isolate is created
      30             :   // with the default pointer compression state for current build.
      31             :   explicit IsolateWrapper(bool enforce_pointer_compression = false);
      32             :   ~IsolateWrapper();
      33             : 
      34             :   v8::Isolate* isolate() const { return isolate_; }
      35             : 
      36             :  private:
      37             :   v8::ArrayBuffer::Allocator* array_buffer_allocator_;
      38             :   v8::Isolate* isolate_;
      39             : 
      40             :   DISALLOW_COPY_AND_ASSIGN(IsolateWrapper);
      41             : };
      42             : 
      43             : class SharedIsolateHolder final {
      44             :  public:
      45      735868 :   static v8::Isolate* isolate() { return isolate_wrapper_->isolate(); }
      46             : 
      47        1257 :   static void CreateIsolate() {
      48        1257 :     CHECK_NULL(isolate_wrapper_);
      49        1257 :     isolate_wrapper_ = new IsolateWrapper();
      50        1257 :   }
      51             : 
      52        1257 :   static void DeleteIsolate() {
      53        1257 :     CHECK_NOT_NULL(isolate_wrapper_);
      54        1257 :     delete isolate_wrapper_;
      55        1257 :     isolate_wrapper_ = nullptr;
      56        1257 :   }
      57             : 
      58             :  private:
      59             :   static v8::IsolateWrapper* isolate_wrapper_;
      60             : 
      61             :   DISALLOW_IMPLICIT_CONSTRUCTORS(SharedIsolateHolder);
      62             : };
      63             : 
      64             : //
      65             : // A set of mixins from which the test fixtures will be constructed.
      66             : //
      67             : template <typename TMixin>
      68           1 : class WithPrivateIsolateMixin : public TMixin {
      69             :  public:
      70             :   explicit WithPrivateIsolateMixin(bool enforce_pointer_compression = false)
      71           1 :       : isolate_wrapper_(enforce_pointer_compression) {}
      72             : 
      73             :   v8::Isolate* v8_isolate() const { return isolate_wrapper_.isolate(); }
      74             : 
      75             :   static void SetUpTestCase() { TMixin::SetUpTestCase(); }
      76             :   static void TearDownTestCase() { TMixin::TearDownTestCase(); }
      77             : 
      78             :  private:
      79             :   v8::IsolateWrapper isolate_wrapper_;
      80             : 
      81             :   DISALLOW_COPY_AND_ASSIGN(WithPrivateIsolateMixin);
      82             : };
      83             : 
      84             : template <typename TMixin>
      85        1257 : class WithSharedIsolateMixin : public TMixin {
      86             :  public:
      87        1257 :   WithSharedIsolateMixin() = default;
      88             : 
      89             :   v8::Isolate* v8_isolate() const { return SharedIsolateHolder::isolate(); }
      90             : 
      91             :   static void SetUpTestCase() {
      92             :     TMixin::SetUpTestCase();
      93        1257 :     SharedIsolateHolder::CreateIsolate();
      94             :   }
      95             : 
      96             :   static void TearDownTestCase() {
      97        1257 :     SharedIsolateHolder::DeleteIsolate();
      98             :     TMixin::TearDownTestCase();
      99             :   }
     100             : 
     101             :  private:
     102             :   DISALLOW_COPY_AND_ASSIGN(WithSharedIsolateMixin);
     103             : };
     104             : 
     105             : template <typename TMixin>
     106           2 : class WithPointerCompressionIsolateMixin
     107             :     : public WithPrivateIsolateMixin<TMixin> {
     108             :  public:
     109             :   WithPointerCompressionIsolateMixin()
     110           1 :       : WithPrivateIsolateMixin<TMixin>(true) {}
     111             : 
     112             :  private:
     113             :   DISALLOW_COPY_AND_ASSIGN(WithPointerCompressionIsolateMixin);
     114             : };
     115             : 
     116             : template <typename TMixin>
     117        2516 : class WithIsolateScopeMixin : public TMixin {
     118             :  public:
     119        1258 :   WithIsolateScopeMixin()
     120        2516 :       : isolate_scope_(v8_isolate()), handle_scope_(v8_isolate()) {}
     121             : 
     122             :   v8::Isolate* isolate() const { return v8_isolate(); }
     123             :   v8::Isolate* v8_isolate() const { return TMixin::v8_isolate(); }
     124             : 
     125             :   v8::internal::Isolate* i_isolate() const {
     126             :     return reinterpret_cast<v8::internal::Isolate*>(v8_isolate());
     127             :   }
     128             : 
     129         162 :   static void SetUpTestCase() { TMixin::SetUpTestCase(); }
     130         162 :   static void TearDownTestCase() { TMixin::TearDownTestCase(); }
     131             : 
     132             :  private:
     133             :   v8::Isolate::Scope isolate_scope_;
     134             :   v8::HandleScope handle_scope_;
     135             : 
     136             :   DISALLOW_COPY_AND_ASSIGN(WithIsolateScopeMixin);
     137             : };
     138             : 
     139             : template <typename TMixin>
     140        1670 : class WithContextMixin : public TMixin {
     141             :  public:
     142         835 :   WithContextMixin()
     143        2505 :       : context_(Context::New(v8_isolate())), context_scope_(context_) {}
     144             : 
     145             :   v8::Isolate* v8_isolate() const { return TMixin::v8_isolate(); }
     146             : 
     147             :   const Local<Context>& context() const { return v8_context(); }
     148          16 :   const Local<Context>& v8_context() const { return context_; }
     149             : 
     150          56 :   Local<Value> RunJS(const char* source) {
     151          56 :     return RunJS(v8::String::NewFromUtf8(v8_isolate(), source,
     152             :                                          v8::NewStringType::kNormal)
     153          56 :                      .ToLocalChecked());
     154             :   }
     155             : 
     156           6 :   Local<Value> RunJS(v8::String::ExternalOneByteStringResource* source) {
     157           6 :     return RunJS(
     158           6 :         v8::String::NewExternalOneByte(v8_isolate(), source).ToLocalChecked());
     159             :   }
     160             : 
     161          14 :   v8::Local<v8::String> NewString(const char* string) {
     162             :     return v8::String::NewFromUtf8(v8_isolate(), string,
     163             :                                    v8::NewStringType::kNormal)
     164          28 :         .ToLocalChecked();
     165             :   }
     166             : 
     167          11 :   void SetGlobalProperty(const char* name, v8::Local<v8::Value> value) {
     168          44 :     CHECK(v8_context()
     169             :               ->Global()
     170             :               ->Set(v8_context(), NewString(name), value)
     171             :               .FromJust());
     172          11 :   }
     173             : 
     174          75 :   static void SetUpTestCase() { TMixin::SetUpTestCase(); }
     175          75 :   static void TearDownTestCase() { TMixin::TearDownTestCase(); }
     176             : 
     177             :  private:
     178          62 :   Local<Value> RunJS(Local<String> source) {
     179          62 :     auto context = v8_isolate()->GetCurrentContext();
     180             :     Local<Script> script =
     181          62 :         v8::Script::Compile(context, source).ToLocalChecked();
     182         124 :     return script->Run(context).ToLocalChecked();
     183             :   }
     184             : 
     185             :   v8::Local<v8::Context> context_;
     186             :   v8::Context::Scope context_scope_;
     187             : 
     188             :   DISALLOW_COPY_AND_ASSIGN(WithContextMixin);
     189             : };
     190             : 
     191             : // Use v8::internal::TestWithIsolate if you are testing internals,
     192             : // aka. directly work with Handles.
     193             : using TestWithIsolate =          //
     194             :     WithIsolateScopeMixin<       //
     195             :         WithSharedIsolateMixin<  //
     196             :             ::testing::Test>>;
     197             : 
     198             : // Use v8::internal::TestWithNativeContext if you are testing internals,
     199             : // aka. directly work with Handles.
     200             : using TestWithContext =              //
     201             :     WithContextMixin<                //
     202             :         WithIsolateScopeMixin<       //
     203             :             WithSharedIsolateMixin<  //
     204             :                 ::testing::Test>>>;
     205             : 
     206             : using TestWithIsolateAndPointerCompression =     //
     207             :     WithContextMixin<                            //
     208             :         WithIsolateScopeMixin<                   //
     209             :             WithPointerCompressionIsolateMixin<  //
     210             :                 ::testing::Test>>>;
     211             : 
     212             : namespace internal {
     213             : 
     214             : // Forward declarations.
     215             : class Factory;
     216             : 
     217             : template <typename TMixin>
     218        1930 : class WithInternalIsolateMixin : public TMixin {
     219             :  public:
     220        1127 :   WithInternalIsolateMixin() = default;
     221             : 
     222             :   Factory* factory() const { return isolate()->factory(); }
     223             :   Isolate* isolate() const { return TMixin::i_isolate(); }
     224             : 
     225             :   Handle<NativeContext> native_context() const {
     226          16 :     return isolate()->native_context();
     227             :   }
     228             : 
     229             :   template <typename T = Object>
     230             :   Handle<T> RunJS(const char* source) {
     231             :     return Handle<T>::cast(RunJSInternal(source));
     232             :   }
     233             : 
     234             :   Handle<Object> RunJSInternal(const char* source) {
     235          66 :     return Utils::OpenHandle(*TMixin::RunJS(source));
     236             :   }
     237             : 
     238             :   template <typename T = Object>
     239             :   Handle<T> RunJS(::v8::String::ExternalOneByteStringResource* source) {
     240             :     return Handle<T>::cast(RunJSInternal(source));
     241             :   }
     242             : 
     243             :   Handle<Object> RunJSInternal(
     244             :       ::v8::String::ExternalOneByteStringResource* source) {
     245          12 :     return Utils::OpenHandle(*TMixin::RunJS(source));
     246             :   }
     247             : 
     248             :   base::RandomNumberGenerator* random_number_generator() const {
     249         319 :     return isolate()->random_number_generator();
     250             :   }
     251             : 
     252         658 :   static void SetUpTestCase() { TMixin::SetUpTestCase(); }
     253         658 :   static void TearDownTestCase() { TMixin::TearDownTestCase(); }
     254             : 
     255             :  private:
     256             :   DISALLOW_COPY_AND_ASSIGN(WithInternalIsolateMixin);
     257             : };
     258             : 
     259             : template <typename TMixin>
     260        2750 : class WithZoneMixin : public TMixin {
     261             :  public:
     262        4748 :   WithZoneMixin() : zone_(&allocator_, ZONE_NAME) {}
     263             : 
     264      265253 :   Zone* zone() { return &zone_; }
     265             : 
     266        2454 :   static void SetUpTestCase() { TMixin::SetUpTestCase(); }
     267        2454 :   static void TearDownTestCase() { TMixin::TearDownTestCase(); }
     268             : 
     269             :  private:
     270             :   v8::internal::AccountingAllocator allocator_;
     271             :   Zone zone_;
     272             : 
     273             :   DISALLOW_COPY_AND_ASSIGN(WithZoneMixin);
     274             : };
     275             : 
     276             : using TestWithIsolate =              //
     277             :     WithInternalIsolateMixin<        //
     278             :         WithIsolateScopeMixin<       //
     279             :             WithSharedIsolateMixin<  //
     280             :                 ::testing::Test>>>;
     281             : 
     282             : using TestWithZone = WithZoneMixin<::testing::Test>;
     283             : 
     284             : using TestWithIsolateAndZone =       //
     285             :     WithInternalIsolateMixin<        //
     286             :         WithIsolateScopeMixin<       //
     287             :             WithSharedIsolateMixin<  //
     288             :                 WithZoneMixin<       //
     289             :                     ::testing::Test>>>>;
     290             : 
     291             : using TestWithNativeContext =            //
     292             :     WithInternalIsolateMixin<            //
     293             :         WithContextMixin<                //
     294             :             WithIsolateScopeMixin<       //
     295             :                 WithSharedIsolateMixin<  //
     296             :                     ::testing::Test>>>>;
     297             : 
     298             : using TestWithNativeContextAndZone =         //
     299             :     WithZoneMixin<                           //
     300             :         WithInternalIsolateMixin<            //
     301             :             WithContextMixin<                //
     302             :                 WithIsolateScopeMixin<       //
     303             :                     WithSharedIsolateMixin<  //
     304             :                         ::testing::Test>>>>>;
     305             : 
     306             : class SaveFlags {
     307             :  public:
     308             :   SaveFlags();
     309             :   ~SaveFlags();
     310             : 
     311             :  private:
     312             : #define FLAG_MODE_APPLY(ftype, ctype, nam, def, cmt) ctype SAVED_##nam;
     313             : #include "src/flag-definitions.h"  // NOLINT
     314             : #undef FLAG_MODE_APPLY
     315             : 
     316             :   DISALLOW_COPY_AND_ASSIGN(SaveFlags);
     317             : };
     318             : 
     319             : // For GTest.
     320             : inline void PrintTo(Object o, ::std::ostream* os) {
     321           0 :   *os << reinterpret_cast<void*>(o.ptr());
     322             : }
     323             : inline void PrintTo(Smi o, ::std::ostream* os) {
     324           0 :   *os << reinterpret_cast<void*>(o.ptr());
     325             : }
     326             : 
     327             : }  // namespace internal
     328             : }  // namespace v8
     329             : 
     330             : #endif  // V8_UNITTESTS_TEST_UTILS_H_

Generated by: LCOV version 1.10