LCOV - code coverage report
Current view: top level - test/unittests - test-utils.h (source / functions) Hit Total Coverage
Test: app.info Lines: 59 61 96.7 %
Date: 2019-01-20 Functions: 61 83 73.5 %

          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      800988 :   static v8::Isolate* isolate() { return isolate_wrapper_->isolate(); }
      46             : 
      47        1246 :   static void CreateIsolate() {
      48        1246 :     CHECK_NULL(isolate_wrapper_);
      49        1246 :     isolate_wrapper_ = new IsolateWrapper();
      50        1246 :   }
      51             : 
      52        1246 :   static void DeleteIsolate() {
      53        1246 :     CHECK_NOT_NULL(isolate_wrapper_);
      54        1246 :     delete isolate_wrapper_;
      55        1246 :     isolate_wrapper_ = nullptr;
      56        1246 :   }
      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           7 :   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        1246 : class WithSharedIsolateMixin : public TMixin {
      86             :  public:
      87        1246 :   WithSharedIsolateMixin() = default;
      88             : 
      89             :   v8::Isolate* v8_isolate() const { return SharedIsolateHolder::isolate(); }
      90             : 
      91             :   static void SetUpTestCase() {
      92             :     TMixin::SetUpTestCase();
      93        1246 :     SharedIsolateHolder::CreateIsolate();
      94             :   }
      95             : 
      96             :   static void TearDownTestCase() {
      97        1246 :     SharedIsolateHolder::DeleteIsolate();
      98             :     TMixin::TearDownTestCase();
      99             :   }
     100             : 
     101             :  private:
     102             :   DISALLOW_COPY_AND_ASSIGN(WithSharedIsolateMixin);
     103             : };
     104             : 
     105             : template <typename TMixin>
     106           1 : class WithPointerCompressionIsolateMixin
     107             :     : public WithPrivateIsolateMixin<TMixin> {
     108             :  public:
     109           1 :   WithPointerCompressionIsolateMixin()
     110           1 :       : WithPrivateIsolateMixin<TMixin>(true) {}
     111             : 
     112             :  private:
     113             :   DISALLOW_COPY_AND_ASSIGN(WithPointerCompressionIsolateMixin);
     114             : };
     115             : 
     116             : template <typename TMixin>
     117        2494 : class WithIsolateScopeMixin : public TMixin {
     118             :  public:
     119        1247 :   WithIsolateScopeMixin()
     120        2494 :       : 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        1650 : class WithContextMixin : public TMixin {
     141             :  public:
     142         825 :   WithContextMixin()
     143        2475 :       : 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             :   const Local<Context>& v8_context() const { return context_; }
     149             : 
     150          39 :   Local<Value> RunJS(const char* source) {
     151             :     return RunJS(v8::String::NewFromUtf8(v8_isolate(), source,
     152             :                                          v8::NewStringType::kNormal)
     153          78 :                      .ToLocalChecked());
     154             :   }
     155             : 
     156           6 :   Local<Value> RunJS(v8::String::ExternalOneByteStringResource* source) {
     157             :     return RunJS(
     158          12 :         v8::String::NewExternalOneByte(v8_isolate(), source).ToLocalChecked());
     159             :   }
     160             : 
     161           4 :   v8::Local<v8::String> NewString(const char* string) {
     162             :     return v8::String::NewFromUtf8(v8_isolate(), string,
     163             :                                    v8::NewStringType::kNormal)
     164           8 :         .ToLocalChecked();
     165             :   }
     166             : 
     167           3 :   void SetGlobalProperty(const char* name, v8::Local<v8::Value> value) {
     168          15 :     CHECK(v8_context()
     169             :               ->Global()
     170             :               ->Set(v8_context(), NewString(name), value)
     171             :               .FromJust());
     172           3 :   }
     173             : 
     174          65 :   static void SetUpTestCase() { TMixin::SetUpTestCase(); }
     175          65 :   static void TearDownTestCase() { TMixin::TearDownTestCase(); }
     176             : 
     177             :  private:
     178          45 :   Local<Value> RunJS(Local<String> source) {
     179          45 :     auto context = v8_isolate()->GetCurrentContext();
     180             :     Local<Script> script =
     181          45 :         v8::Script::Compile(context, source).ToLocalChecked();
     182          90 :     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        1909 : class WithInternalIsolateMixin : public TMixin {
     219             :  public:
     220        1117 :   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           9 :     return isolate()->native_context();
     227             :   }
     228             : 
     229             :   template <typename T = Object>
     230          38 :   Handle<T> RunJS(const char* source) {
     231          38 :     return Handle<T>::cast(RunJSInternal(source));
     232             :   }
     233             : 
     234             :   Handle<Object> RunJSInternal(const char* source) {
     235          76 :     return Utils::OpenHandle(*TMixin::RunJS(source));
     236             :   }
     237             : 
     238             :   template <typename T = Object>
     239           6 :   Handle<T> RunJS(::v8::String::ExternalOneByteStringResource* source) {
     240           6 :     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         644 :   static void SetUpTestCase() { TMixin::SetUpTestCase(); }
     253         644 :   static void TearDownTestCase() { TMixin::TearDownTestCase(); }
     254             : 
     255             :  private:
     256             :   DISALLOW_COPY_AND_ASSIGN(WithInternalIsolateMixin);
     257             : };
     258             : 
     259             : template <typename TMixin>
     260        1982 : class WithZoneMixin : public TMixin {
     261             :  public:
     262        2730 :   WithZoneMixin() : zone_(&allocator_, ZONE_NAME) {}
     263             : 
     264             :   Zone* zone() { return &zone_; }
     265             : 
     266        2435 :   static void SetUpTestCase() { TMixin::SetUpTestCase(); }
     267        2435 :   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             :   std::vector<const char*>* non_default_flags_;
     313             : 
     314             :   DISALLOW_COPY_AND_ASSIGN(SaveFlags);
     315             : };
     316             : 
     317             : // For GTest.
     318             : inline void PrintTo(Object o, ::std::ostream* os) {
     319           0 :   *os << reinterpret_cast<void*>(o.ptr());
     320             : }
     321             : inline void PrintTo(Smi o, ::std::ostream* os) {
     322           0 :   *os << reinterpret_cast<void*>(o.ptr());
     323             : }
     324             : 
     325             : }  // namespace internal
     326             : }  // namespace v8
     327             : 
     328             : #endif  // V8_UNITTESTS_TEST_UTILS_H_

Generated by: LCOV version 1.10