| /* |
| * Copyright 2014 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. |
| */ |
| |
| #ifndef COBALT_DOM_TESTING_HTML_COLLECTION_TESTING_H_ |
| #define COBALT_DOM_TESTING_HTML_COLLECTION_TESTING_H_ |
| |
| #include "cobalt/dom/document.h" |
| #include "cobalt/dom/element.h" |
| #include "cobalt/dom/html_collection.h" |
| #include "cobalt/dom/html_element.h" |
| #include "cobalt/dom/html_element_factory.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace cobalt { |
| namespace dom { |
| namespace testing { |
| |
| // Given an empty node of a type T, test the functionality of |
| // T::GetElementsByClassName. |
| template <typename T> |
| void TestGetElementsByClassName(const scoped_refptr<T>& node); |
| |
| // Given an empty node of a type T, test the functionality of |
| // T::GetElementsByTagName. |
| template <typename T> |
| void TestGetElementsByTagName(const scoped_refptr<T>& node); |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // Implementation |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| template <typename T> |
| void TestGetElementsByClassName(const scoped_refptr<T>& node) { |
| const scoped_refptr<Node> kNullNode; |
| const scoped_refptr<HTMLCollection> kNullCollection; |
| |
| Document* document = node->node_document(); |
| |
| if (!document) { |
| document = node->AsDocument(); |
| DCHECK(document); |
| } |
| |
| // Construct a tree: |
| // node |
| // a1 |
| // b1 |
| // c1 |
| // a2 |
| // d1 |
| // d2 |
| scoped_refptr<Node> a1 = |
| node->AppendChild(new Element(document, base::Token("a1"))); |
| scoped_refptr<Node> a2 = |
| node->AppendChild(new Element(document, base::Token("a2"))); |
| scoped_refptr<Node> b1 = |
| a1->AppendChild(new Element(document, base::Token("b1"))); |
| scoped_refptr<Node> c1 = |
| b1->AppendChild(new Element(document, base::Token("c1"))); |
| scoped_refptr<Node> d1 = |
| a2->AppendChild(new Element(document, base::Token("d1"))); |
| scoped_refptr<Node> d2 = |
| a2->AppendChild(new Element(document, base::Token("d2"))); |
| |
| scoped_refptr<HTMLCollection> collection = |
| node->GetElementsByClassName("class"); |
| |
| // Start with an empty class. |
| EXPECT_EQ(0, collection->length()); |
| |
| // Set the matching class on all elements. |
| a1->AsElement()->set_class_name("class"); |
| a2->AsElement()->set_class_name("class"); |
| b1->AsElement()->set_class_name("class"); |
| c1->AsElement()->set_class_name("class"); |
| d1->AsElement()->set_class_name("class"); |
| d2->AsElement()->set_class_name("class"); |
| |
| EXPECT_EQ(6, collection->length()); |
| EXPECT_EQ(a1, collection->Item(0)); |
| EXPECT_EQ(b1, collection->Item(1)); |
| EXPECT_EQ(c1, collection->Item(2)); |
| EXPECT_EQ(a2, collection->Item(3)); |
| EXPECT_EQ(d1, collection->Item(4)); |
| EXPECT_EQ(d2, collection->Item(5)); |
| EXPECT_EQ(kNullNode, collection->Item(6)); |
| EXPECT_EQ(a1, collection->Item(0)); |
| |
| // Modify the class name on some elements. |
| a1->AsElement()->set_class_name("other_class"); |
| a2->AsElement()->set_class_name("other_class"); |
| b1->AsElement()->set_class_name("other_class"); |
| d1->AsElement()->set_class_name("other_class"); |
| |
| EXPECT_EQ(2, collection->length()); |
| EXPECT_EQ(c1, collection->Item(0)); |
| EXPECT_EQ(d2, collection->Item(1)); |
| EXPECT_EQ(kNullNode, collection->Item(2)); |
| EXPECT_EQ(c1, collection->Item(0)); |
| |
| // d1 is not matched by the collection so adding the id shouldn't change |
| // anything. |
| d1->AsElement()->set_id("id"); |
| EXPECT_EQ(kNullNode, collection->NamedItem("id")); |
| |
| // d2 is matched by the collection so adding the id should work. |
| d2->AsElement()->set_id("id"); |
| EXPECT_EQ(d2, collection->NamedItem("id")); |
| |
| // Removing a2 should also remove its children from the collection, including |
| // d2. |
| node->RemoveChild(a2); |
| EXPECT_EQ(1, collection->length()); |
| EXPECT_EQ(c1, collection->Item(0)); |
| EXPECT_EQ(kNullNode, collection->Item(1)); |
| EXPECT_EQ(kNullNode, collection->NamedItem("id")); |
| |
| c1->AsElement()->set_class_name("other_class"); |
| EXPECT_EQ(0, collection->length()); |
| EXPECT_EQ(kNullNode, collection->Item(0)); |
| |
| // Test elements with multiple classes |
| a1->AsElement()->set_class_name("class other_class"); |
| b1->AsElement()->set_class_name("class yet_another_class"); |
| c1->AsElement()->set_class_name("other_class yet_another_class"); |
| EXPECT_EQ(2, collection->length()); |
| EXPECT_EQ(a1, collection->Item(0)); |
| EXPECT_EQ(b1, collection->Item(1)); |
| } |
| |
| template <typename T> |
| void TestGetElementsByTagName(const scoped_refptr<T>& node) { |
| const scoped_refptr<Node> kNullNode; |
| const scoped_refptr<HTMLCollection> kNullCollection; |
| Document* document = node->node_document(); |
| |
| if (!document) { |
| document = node->AsDocument(); |
| DCHECK(document); |
| } |
| |
| // Construct a tree: |
| // node |
| // a1 |
| // b1 |
| // c1 |
| // a3 |
| // d1 |
| HTMLElementFactory html_element_factory; |
| html_element_factory.CreateHTMLElement(document, base::Token("a1")); |
| |
| scoped_refptr<Node> a1 = node->AppendChild( |
| html_element_factory.CreateHTMLElement(document, base::Token("a1"))); |
| |
| scoped_refptr<Node> a3 = node->AppendChild( |
| html_element_factory.CreateHTMLElement(document, base::Token("a2"))); |
| scoped_refptr<Node> b1 = a1->AppendChild( |
| html_element_factory.CreateHTMLElement(document, base::Token("b1"))); |
| scoped_refptr<Node> c1 = b1->AppendChild( |
| html_element_factory.CreateHTMLElement(document, base::Token("tag"))); |
| scoped_refptr<Node> d1 = a3->AppendChild( |
| html_element_factory.CreateHTMLElement(document, base::Token("tag"))); |
| |
| // GetElementsByTagName should return all elements when provided with |
| // parameter "*". |
| scoped_refptr<HTMLCollection> collection = node->GetElementsByTagName("*"); |
| EXPECT_EQ(5, collection->length()); |
| EXPECT_EQ(a1, collection->Item(0)); |
| EXPECT_EQ(b1, collection->Item(1)); |
| EXPECT_EQ(c1, collection->Item(2)); |
| EXPECT_EQ(a3, collection->Item(3)); |
| EXPECT_EQ(d1, collection->Item(4)); |
| EXPECT_EQ(kNullNode, collection->Item(5)); |
| |
| // GetElementsByTagName should only return elements with the specific tag name |
| // when that is provided. |
| collection = node->GetElementsByTagName("tag"); |
| EXPECT_EQ(2, collection->length()); |
| EXPECT_EQ(c1, collection->Item(0)); |
| EXPECT_EQ(d1, collection->Item(1)); |
| EXPECT_EQ(kNullNode, collection->Item(2)); |
| |
| // a3 is not matched by the collection so adding the id shouldn't change |
| // anything. |
| a3->AsElement()->set_id("id"); |
| EXPECT_EQ(kNullNode, collection->NamedItem("id")); |
| |
| // d1 is matched by the collection so adding the id should work. |
| d1->AsElement()->set_id("id"); |
| EXPECT_EQ(d1, collection->NamedItem("id")); |
| |
| // Add a new node with a matching tag. |
| scoped_refptr<Node> a2 = node->InsertBefore( |
| html_element_factory.CreateHTMLElement(document, base::Token("tag")), a3); |
| EXPECT_EQ(3, collection->length()); |
| EXPECT_EQ(c1, collection->Item(0)); |
| EXPECT_EQ(a2, collection->Item(1)); |
| EXPECT_EQ(d1, collection->Item(2)); |
| EXPECT_EQ(kNullNode, collection->Item(3)); |
| |
| // Removing a3 should also remove its children from the collection. |
| node->RemoveChild(a3); |
| EXPECT_EQ(2, collection->length()); |
| EXPECT_EQ(c1, collection->Item(0)); |
| EXPECT_EQ(a2, collection->Item(1)); |
| EXPECT_EQ(kNullNode, collection->Item(2)); |
| EXPECT_EQ(kNullNode, collection->NamedItem("id")); |
| } |
| |
| } // namespace testing |
| } // namespace dom |
| } // namespace cobalt |
| |
| #endif // COBALT_DOM_TESTING_HTML_COLLECTION_TESTING_H_ |