Chromium Code Reviews| Index: gin/wrappable_unittest.cc |
| diff --git a/gin/wrappable_unittest.cc b/gin/wrappable_unittest.cc |
| index 70cb22458840e4ff09a8af1ddda2b7f6a273f788..a8c30f62523a5dd387dcff4be20d48c5a0041efe 100644 |
| --- a/gin/wrappable_unittest.cc |
| +++ b/gin/wrappable_unittest.cc |
| @@ -15,19 +15,7 @@ |
| namespace gin { |
| -class BaseClass { |
| - public: |
| - BaseClass() : value_(23) {} |
| - virtual ~BaseClass() {} |
| - |
| - private: |
| - int value_; |
| - |
| - DISALLOW_COPY_AND_ASSIGN(BaseClass); |
| -}; |
| - |
| -class MyObject : public BaseClass, |
| - public Wrappable<MyObject> { |
| +class MyObject : public Wrappable<MyObject> { |
| public: |
| static WrapperInfo kWrapperInfo; |
| @@ -40,19 +28,40 @@ class MyObject : public BaseClass, |
| protected: |
| MyObject() : value_(0) {} |
| - ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate) override; |
| + ObjectTemplateBuilder GetObjectTemplateBuilder( |
| + v8::Isolate* isolate) override { |
| + return Wrappable<MyObject>::GetObjectTemplateBuilder(isolate) |
| + .SetProperty("value", &MyObject::value, &MyObject::set_value); |
| + } |
| ~MyObject() override {} |
| private: |
| int value_; |
| }; |
| -class MyObjectSubclass : public MyObject { |
| +class SpacerClass { |
| + public: |
| + SpacerClass() : value_(23) {} |
| + virtual ~SpacerClass() {} |
| + |
| + private: |
| + int value_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(SpacerClass); |
| +}; |
| + |
| +class MyObjectSubclass : public SpacerClass, public MyObject { |
| public: |
| + static WrapperInfo kWrapperInfo; |
| + |
| static gin::Handle<MyObjectSubclass> Create(v8::Isolate* isolate) { |
| return CreateHandle(isolate, new MyObjectSubclass()); |
| } |
| + WrapperInfo* GetWrapperInfo() override { |
| + return &MyObjectSubclass::kWrapperInfo; |
| + } |
| + |
| void SayHello(const std::string& name) { |
| result = std::string("Hello, ") + name; |
| } |
| @@ -104,25 +113,9 @@ class MyCallableObject : public Wrappable<MyCallableObject> { |
| int result_; |
| }; |
| -class MyObject2 : public Wrappable<MyObject2> { |
| - public: |
| - static WrapperInfo kWrapperInfo; |
| -}; |
| - |
| -class MyObjectBlink : public Wrappable<MyObjectBlink> { |
| - public: |
| - static WrapperInfo kWrapperInfo; |
| -}; |
| - |
| WrapperInfo MyObject::kWrapperInfo = { kEmbedderNativeGin }; |
| -ObjectTemplateBuilder MyObject::GetObjectTemplateBuilder(v8::Isolate* isolate) { |
| - return Wrappable<MyObject>::GetObjectTemplateBuilder(isolate) |
| - .SetProperty("value", &MyObject::value, &MyObject::set_value); |
| -} |
| - |
| +WrapperInfo MyObjectSubclass::kWrapperInfo = { kEmbedderNativeGin }; |
| WrapperInfo MyCallableObject::kWrapperInfo = { kEmbedderNativeGin }; |
| -WrapperInfo MyObject2::kWrapperInfo = { kEmbedderNativeGin }; |
| -WrapperInfo MyObjectBlink::kWrapperInfo = { kEmbedderNativeGin }; |
| typedef V8Test WrappableTest; |
| @@ -154,18 +147,6 @@ TEST_F(WrappableTest, UnwrapFailures) { |
| thing = v8::Object::New(isolate); |
| EXPECT_FALSE(ConvertFromV8(isolate, thing, &unwrapped)); |
| EXPECT_FALSE(unwrapped); |
| - |
| - // An object that's wrapping a C++ object from Blink. |
| - thing.Clear(); |
| - thing = ConvertToV8(isolate, new MyObjectBlink()); |
| - EXPECT_FALSE(ConvertFromV8(isolate, thing, &unwrapped)); |
| - EXPECT_FALSE(unwrapped); |
| - |
| - // An object that's wrapping a C++ object of the wrong type. |
| - thing.Clear(); |
| - thing = ConvertToV8(isolate, new MyObject2()); |
| - EXPECT_FALSE(ConvertFromV8(isolate, thing, &unwrapped)); |
| - EXPECT_FALSE(unwrapped); |
| } |
| TEST_F(WrappableTest, GetAndSetProperty) { |
| @@ -204,11 +185,34 @@ TEST_F(WrappableTest, WrappableSubclass) { |
| v8::Isolate* isolate = instance_->isolate(); |
| v8::HandleScope handle_scope(isolate); |
| + // Create a base class first to ensure that MyObjectSubclass instances can |
| + // co-exist and be distinguished from the base class. This will fail if |
| + // the subclass doesn't provide an overridden GetWrapperInfo(). |
| + gin::Handle<MyObject> base_class_instance = MyObject::Create(isolate); |
|
tommycli
2015/06/02 22:01:23
This test tickles the problem that caused those my
|
| + base_class_instance->set_value(42); |
| + |
| gin::Handle<MyObjectSubclass> object(MyObjectSubclass::Create(isolate)); |
| v8::Local<v8::String> source = StringToV8(isolate, |
| "(function(obj) {" |
| "obj.sayHello('Lily');" |
| "})"); |
| + |
| + v8::Local<v8::Value> wrapper = ConvertToV8(isolate, object.get()); |
| + EXPECT_FALSE(wrapper.IsEmpty()); |
| + |
| + // Ensure wrap and unwrap works for the subclass. |
| + MyObjectSubclass* unwrapped = nullptr; |
| + EXPECT_TRUE(ConvertFromV8(isolate, wrapper, &unwrapped)); |
| + EXPECT_EQ(object.get(), unwrapped); |
| + |
| + // Ensure wrap and unwrap to the base class correctly adjusts the pointer. |
| + // The static_cast is strictly speaking unnecessary, as MyObjectSubclass* |
| + // pointers are transparently adjusted when compared to MyObject* pointers. |
| + // MyObject* unwrapped_base = nullptr; |
| + // EXPECT_TRUE(ConvertFromV8(isolate, wrapper, &unwrapped_base)); |
| + // EXPECT_EQ(static_cast<MyObject*>(object.get()), unwrapped_base); |
| + |
| + // Ensure subclass-defined Javascript calls work. |
| gin::TryCatch try_catch(isolate); |
| v8::Local<v8::Script> script = v8::Script::Compile(source); |
| v8::Local<v8::Value> val = script->Run(); |