| // Copyright 2015 Google Inc. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include "cobalt/bindings/testing/arbitrary_interface.h" |
| #include "cobalt/bindings/testing/bindings_test_base.h" |
| #include "cobalt/bindings/testing/no_interface_object_interface.h" |
| |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| using ::testing::Return; |
| |
| namespace cobalt { |
| namespace bindings { |
| namespace testing { |
| |
| namespace { |
| typedef InterfaceBindingsTest<ArbitraryInterface> InterfaceObjectTest; |
| typedef InterfaceBindingsTest<NoInterfaceObjectInterface> NoInterfaceObjectTest; |
| } // namespace |
| |
| // Spec for interface object: https://www.w3.org/TR/WebIDL/#interface-object |
| // Spec for interface prototype object: |
| // https://www.w3.org/TR/WebIDL/#interface-prototype-object |
| |
| // Interface object for non-callback interface is a global property. |
| TEST_F(InterfaceObjectTest, InterfaceObjectIsGlobalProperty) { |
| std::string result; |
| EXPECT_TRUE(EvaluateScript( |
| "this.hasOwnProperty(\"ArbitraryInterface\");", &result)); |
| EXPECT_STREQ("true", result.c_str()); |
| } |
| |
| // Interface object for non-callback interface is a function object. |
| TEST_F(InterfaceObjectTest, InterfaceObjectIsFunctionObject) { |
| std::string result; |
| EXPECT_TRUE(EvaluateScript( |
| "ArbitraryInterface instanceof Function;", &result)); |
| EXPECT_STREQ("true", result.c_str()); |
| } |
| |
| // The value of the "prototype" property must be the |
| // 'interface prototype object'. |
| TEST_F(InterfaceObjectTest, PrototypePropertyIsSet) { |
| std::string result; |
| EXPECT_TRUE(EvaluateScript( |
| "ArbitraryInterface.hasOwnProperty(\"prototype\");", &result)); |
| EXPECT_STREQ("true", result.c_str()); |
| |
| EXPECT_TRUE(EvaluateScript( |
| "ArbitraryInterface.prototype == Object.getPrototypeOf(test);", |
| &result)); |
| EXPECT_STREQ("true", result.c_str()); |
| } |
| |
| // The value of the "name" property must be the identifier of the interface. |
| TEST_F(InterfaceObjectTest, NamePropertyIsSet) { |
| std::string result; |
| EXPECT_TRUE(EvaluateScript("ArbitraryInterface.name;", &result)); |
| EXPECT_STREQ("ArbitraryInterface", result.c_str()); |
| } |
| |
| // The interface prototype object must have a property named "constructor" whose |
| // value is a reference the the interface object. |
| TEST_F(InterfaceObjectTest, ConstructorPropertyExists) { |
| std::string result; |
| EXPECT_TRUE(EvaluateScript("test.hasOwnProperty(\"constructor\");", &result)); |
| EXPECT_STREQ("false", result.c_str()); |
| |
| EXPECT_TRUE(EvaluateScript( |
| "Object.getPrototypeOf(test).hasOwnProperty(\"constructor\");", &result)); |
| EXPECT_STREQ("true", result.c_str()); |
| } |
| |
| // The interface prototype object must have a property named "constructor" whose |
| // value is a reference the the interface object. |
| TEST_F(InterfaceObjectTest, ConstructorPropertyIsInterfaceObject) { |
| std::string result; |
| EXPECT_TRUE(EvaluateScript( |
| "Object.getPrototypeOf(test).constructor === ArbitraryInterface;", |
| &result)); |
| EXPECT_STREQ("true", result.c_str()); |
| } |
| |
| // If [NoInterfaceObject] extended attribute is specified, there should be no |
| // constructor property on the prototype. |
| TEST_F(NoInterfaceObjectTest, NoConstructorProperty) { |
| std::string result; |
| EXPECT_TRUE(EvaluateScript( |
| "Object.getPrototypeOf(test).hasOwnProperty(\"constructor\");", &result)); |
| EXPECT_STREQ("false", result.c_str()); |
| } |
| |
| // Interface object for non-callback interface is a function object. |
| TEST_F(NoInterfaceObjectTest, NoInterfaceObjectGlobalProperty) { |
| std::string result; |
| EXPECT_TRUE(EvaluateScript( |
| "this.hasOwnProperty(\"NoInterfaceObjectInterface\");", &result)); |
| EXPECT_STREQ("false", result.c_str()); |
| } |
| |
| TEST_F(InterfaceObjectTest, FunctionCanHandleAllJavaScriptValueTypes) { |
| const char* script = R"EOF( |
| const f = ArbitraryInterface.prototype.ArbitraryFunction; |
| [null, undefined, false, 0, "", {}, Symbol("")] |
| .map(value => { |
| try { f.call(value); } |
| catch (ex) { return ex.toString().startsWith("TypeError"); } |
| return false; |
| }) |
| .every(result => result); |
| )EOF"; |
| std::string result; |
| EXPECT_TRUE(EvaluateScript(script, &result)); |
| EXPECT_STREQ("true", result.c_str()); |
| } |
| |
| } // namespace testing |
| } // namespace bindings |
| } // namespace cobalt |