LCOV - code coverage report
Current view: top level - test/unittests/api - interceptor-unittest.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 91 110 82.7 %
Date: 2019-04-17 Functions: 26 32 81.2 %

          Line data    Source code
       1             : // Copyright 2017 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             : #include "include/v8.h"
       6             : #include "test/unittests/test-utils.h"
       7             : #include "testing/gtest/include/gtest/gtest.h"
       8             : 
       9             : namespace v8 {
      10             : namespace {
      11             : 
      12             : using InterceptorTest = TestWithContext;
      13             : 
      14           0 : void NamedGetter(Local<Name> property,
      15           0 :                  const PropertyCallbackInfo<Value>& info) {}
      16             : 
      17       15444 : TEST_F(InterceptorTest, FreezeApiObjectWithInterceptor) {
      18           2 :   TryCatch try_catch(isolate());
      19             : 
      20           1 :   Local<FunctionTemplate> tmpl = FunctionTemplate::New(isolate());
      21           2 :   tmpl->InstanceTemplate()->SetHandler(
      22           1 :       NamedPropertyHandlerConfiguration(NamedGetter));
      23             : 
      24           1 :   Local<Function> ctor = tmpl->GetFunction(context()).ToLocalChecked();
      25             :   Local<Object> obj = ctor->NewInstance(context()).ToLocalChecked();
      26           2 :   ASSERT_TRUE(
      27             :       obj->SetIntegrityLevel(context(), IntegrityLevel::kFrozen).IsNothing());
      28           2 :   ASSERT_TRUE(try_catch.HasCaught());
      29             : }
      30             : 
      31             : }  // namespace
      32             : 
      33             : namespace internal {
      34             : namespace {
      35             : 
      36           2 : class InterceptorLoggingTest : public TestWithNativeContext {
      37             :  public:
      38           2 :   InterceptorLoggingTest() = default;
      39             : 
      40             :   static const int kTestIndex = 0;
      41             : 
      42           1 :   static void NamedPropertyGetter(Local<v8::Name> name,
      43             :                                   const v8::PropertyCallbackInfo<Value>& info) {
      44           1 :     LogCallback(info, "named getter");
      45           1 :   }
      46             : 
      47           2 :   static void NamedPropertySetter(Local<v8::Name> name, Local<v8::Value> value,
      48             :                                   const v8::PropertyCallbackInfo<Value>& info) {
      49           2 :     LogCallback(info, "named setter");
      50           2 :   }
      51             : 
      52           2 :   static void NamedPropertyQuery(
      53             :       Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Integer>& info) {
      54           2 :     LogCallback(info, "named query");
      55           2 :   }
      56             : 
      57           0 :   static void NamedPropertyDeleter(
      58             :       Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Boolean>& info) {
      59           0 :     LogCallback(info, "named deleter");
      60           0 :   }
      61             : 
      62           2 :   static void NamedPropertyEnumerator(
      63             :       const v8::PropertyCallbackInfo<Array>& info) {
      64           2 :     LogCallback(info, "named enumerator");
      65           2 :   }
      66             : 
      67           4 :   static void NamedPropertyDefiner(
      68             :       Local<v8::Name> name, const v8::PropertyDescriptor& desc,
      69             :       const v8::PropertyCallbackInfo<Value>& info) {
      70           4 :     LogCallback(info, "named definer");
      71           4 :   }
      72             : 
      73           5 :   static void NamedPropertyDescriptor(
      74             :       Local<v8::Name> name, const v8::PropertyCallbackInfo<Value>& info) {
      75           5 :     LogCallback(info, "named descriptor");
      76           5 :   }
      77             : 
      78           1 :   static void IndexedPropertyGetter(
      79             :       uint32_t index, const v8::PropertyCallbackInfo<Value>& info) {
      80           1 :     LogCallback(info, "indexed getter");
      81           1 :   }
      82             : 
      83           2 :   static void IndexedPropertySetter(
      84             :       uint32_t index, Local<v8::Value> value,
      85             :       const v8::PropertyCallbackInfo<Value>& info) {
      86           2 :     LogCallback(info, "indexed setter");
      87           2 :   }
      88             : 
      89           1 :   static void IndexedPropertyQuery(
      90             :       uint32_t index, const v8::PropertyCallbackInfo<v8::Integer>& info) {
      91           1 :     LogCallback(info, "indexed query");
      92           1 :   }
      93             : 
      94           0 :   static void IndexedPropertyDeleter(
      95             :       uint32_t index, const v8::PropertyCallbackInfo<v8::Boolean>& info) {
      96           0 :     LogCallback(info, "indexed deleter");
      97           0 :   }
      98             : 
      99           2 :   static void IndexedPropertyEnumerator(
     100             :       const v8::PropertyCallbackInfo<Array>& info) {
     101           2 :     LogCallback(info, "indexed enumerator");
     102           2 :   }
     103             : 
     104           1 :   static void IndexedPropertyDefiner(
     105             :       uint32_t index, const v8::PropertyDescriptor& desc,
     106             :       const v8::PropertyCallbackInfo<Value>& info) {
     107           1 :     LogCallback(info, "indexed definer");
     108           1 :   }
     109             : 
     110           2 :   static void IndexedPropertyDescriptor(
     111             :       uint32_t index, const v8::PropertyCallbackInfo<Value>& info) {
     112           2 :     LogCallback(info, "indexed descriptor");
     113           2 :   }
     114             : 
     115             :   template <class T>
     116          25 :   static void LogCallback(const v8::PropertyCallbackInfo<T>& info,
     117             :                           const char* callback_name) {
     118             :     InterceptorLoggingTest* test = reinterpret_cast<InterceptorLoggingTest*>(
     119             :         info.This()->GetAlignedPointerFromInternalField(kTestIndex));
     120          25 :     test->Log(callback_name);
     121          25 :   }
     122             : 
     123          25 :   void Log(const char* callback_name) {
     124          25 :     if (log_is_empty_) {
     125          16 :       log_is_empty_ = false;
     126             :     } else {
     127           9 :       log_ << ", ";
     128             :     }
     129          25 :     log_ << callback_name;
     130          25 :   }
     131             : 
     132             :  protected:
     133           1 :   void SetUp() override {
     134             :     // Set up the object that supports full interceptors.
     135           1 :     v8::Local<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(v8_isolate());
     136           1 :     templ->SetInternalFieldCount(1);
     137           1 :     templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
     138             :         NamedPropertyGetter, NamedPropertySetter, NamedPropertyQuery,
     139             :         NamedPropertyDeleter, NamedPropertyEnumerator, NamedPropertyDefiner,
     140           1 :         NamedPropertyDescriptor));
     141           1 :     templ->SetHandler(v8::IndexedPropertyHandlerConfiguration(
     142             :         IndexedPropertyGetter, IndexedPropertySetter, IndexedPropertyQuery,
     143             :         IndexedPropertyDeleter, IndexedPropertyEnumerator,
     144           1 :         IndexedPropertyDefiner, IndexedPropertyDescriptor));
     145             :     v8::Local<v8::Object> instance =
     146           1 :         templ->NewInstance(context()).ToLocalChecked();
     147           1 :     instance->SetAlignedPointerInInternalField(kTestIndex, this);
     148           1 :     SetGlobalProperty("obj", instance);
     149           1 :   }
     150             : 
     151          17 :   std::string Run(const char* script) {
     152          17 :     log_is_empty_ = true;
     153          17 :     log_.str(std::string());
     154          17 :     log_.clear();
     155             : 
     156             :     RunJS(script);
     157          17 :     return log_.str();
     158             :   }
     159             : 
     160             :  private:
     161             :   bool log_is_empty_ = false;
     162             :   std::stringstream log_;
     163             : };
     164             : 
     165       15443 : TEST_F(InterceptorLoggingTest, DispatchTest) {
     166           2 :   EXPECT_EQ(Run("for (var p in obj) {}"),
     167           0 :             "indexed enumerator, named enumerator");
     168           2 :   EXPECT_EQ(Run("Object.keys(obj)"), "indexed enumerator, named enumerator");
     169             : 
     170           2 :   EXPECT_EQ(Run("obj.foo"), "named getter");
     171           2 :   EXPECT_EQ(Run("obj[42]"), "indexed getter");
     172             : 
     173           2 :   EXPECT_EQ(Run("obj.foo = null"), "named setter");
     174           2 :   EXPECT_EQ(Run("obj[42] = null"), "indexed setter");
     175             : 
     176           2 :   EXPECT_EQ(Run("Object.getOwnPropertyDescriptor(obj, 'foo')"),
     177           0 :             "named descriptor");
     178             : 
     179           2 :   EXPECT_EQ(Run("Object.getOwnPropertyDescriptor(obj, 42)"),
     180           0 :             "indexed descriptor");
     181             : 
     182           2 :   EXPECT_EQ(Run("Object.defineProperty(obj, 'foo', {value: 42})"),
     183           0 :             "named descriptor, named definer, named setter");
     184           2 :   EXPECT_EQ(Run("Object.defineProperty(obj, 'foo', {get(){} })"),
     185           0 :             "named descriptor, named definer");
     186           2 :   EXPECT_EQ(Run("Object.defineProperty(obj, 'foo', {set(value){}})"),
     187           0 :             "named descriptor, named definer");
     188           2 :   EXPECT_EQ(Run("Object.defineProperty(obj, 'foo', {get(){}, set(value){}})"),
     189           0 :             "named descriptor, named definer");
     190             : 
     191           2 :   EXPECT_EQ(Run("Object.defineProperty(obj, 42, {value: 'foo'})"),
     192             :             "indexed descriptor, "
     193             :             // then attempt definer first and fallback to setter.
     194           0 :             "indexed definer, indexed setter");
     195             : 
     196           2 :   EXPECT_EQ(Run("Object.prototype.propertyIsEnumerable.call(obj, 'a')"),
     197           0 :             "named query");
     198           2 :   EXPECT_EQ(Run("Object.prototype.propertyIsEnumerable.call(obj, 42)"),
     199           0 :             "indexed query");
     200             : 
     201           2 :   EXPECT_EQ(Run("Object.prototype.hasOwnProperty.call(obj, 'a')"),
     202           0 :             "named query");
     203             :   // TODO(cbruni): Fix once hasOnwProperty is fixed (https://crbug.com/872628)
     204           2 :   EXPECT_EQ(Run("Object.prototype.hasOwnProperty.call(obj, '42')"), "");
     205           1 : }
     206             : }  // namespace
     207             : }  // namespace internal
     208        9264 : }  // namespace v8

Generated by: LCOV version 1.10