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