1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include "tinyxml_layout_parser.h"
17 
18 #include "gtest/gtest.h"
19 
20 using startop::CanCompileLayout;
21 using std::string;
22 
23 namespace {
ValidateXmlText(const string & xml,bool expected)24 void ValidateXmlText(const string& xml, bool expected) {
25   tinyxml2::XMLDocument doc;
26   doc.Parse(xml.c_str());
27   EXPECT_EQ(CanCompileLayout(doc), expected);
28 }
29 }  // namespace
30 
TEST(LayoutValidationTest,SingleButtonLayout)31 TEST(LayoutValidationTest, SingleButtonLayout) {
32   const string xml = R"(<?xml version="1.0" encoding="utf-8"?>
33 <Button xmlns:android="http://schemas.android.com/apk/res/android"
34     android:layout_width="match_parent"
35     android:layout_height="match_parent"
36     android:text="Hello, World!">
37 
38 </Button>)";
39   ValidateXmlText(xml, /*expected=*/true);
40 }
41 
42 TEST(LayoutValidationTest, SmallConstraintLayout) {
43   const string xml = R"(<?xml version="1.0" encoding="utf-8"?>
44 <android.support.constraint.ConstraintLayout
45     xmlns:android="http://schemas.android.com/apk/res/android"
46     xmlns:app="http://schemas.android.com/apk/res-auto"
47     xmlns:tools="http://schemas.android.com/tools"
48     android:layout_width="match_parent"
49     android:layout_height="match_parent">
50 
51     <Button
52         android:id="@+id/button6"
53         android:layout_width="wrap_content"
54         android:layout_height="wrap_content"
55         android:layout_marginEnd="16dp"
56         android:layout_marginBottom="16dp"
57         android:text="Button"
58         app:layout_constraintBottom_toBottomOf="parent"
59         app:layout_constraintEnd_toEndOf="parent" />
60 
61     <Button
62         android:id="@+id/button7"
63         android:layout_width="wrap_content"
64         android:layout_height="wrap_content"
65         android:layout_marginEnd="8dp"
66         android:layout_marginBottom="16dp"
67         android:text="Button2"
68         app:layout_constraintBottom_toBottomOf="parent"
69         app:layout_constraintEnd_toStartOf="@+id/button6" />
70 
71     <Button
72         android:id="@+id/button8"
73         android:layout_width="wrap_content"
74         android:layout_height="wrap_content"
75         android:layout_marginEnd="8dp"
76         android:layout_marginBottom="16dp"
77         android:text="Button1"
78         app:layout_constraintBottom_toBottomOf="parent"
79         app:layout_constraintEnd_toStartOf="@+id/button7" />
80 </android.support.constraint.ConstraintLayout>)";
81   ValidateXmlText(xml, /*expected=*/true);
82 }
83 
84 TEST(LayoutValidationTest, MergeNode) {
85   const string xml = R"(<?xml version="1.0" encoding="utf-8"?>
86 <merge xmlns:android="http://schemas.android.com/apk/res/android">
87 
88     <TextView
89         android:id="@+id/textView3"
90         android:layout_width="wrap_content"
91         android:layout_height="wrap_content"
92         android:text="TextView" />
93 
94     <Button
95         android:id="@+id/button9"
96         android:layout_width="wrap_content"
97         android:layout_height="wrap_content"
98         android:text="Button" />
99 </merge>)";
100   ValidateXmlText(xml, /*expected=*/false);
101 }
102 
103 TEST(LayoutValidationTest, IncludeLayout) {
104   const string xml = R"(<?xml version="1.0" encoding="utf-8"?>
105 <android.support.constraint.ConstraintLayout
106     xmlns:android="http://schemas.android.com/apk/res/android"
107     xmlns:app="http://schemas.android.com/apk/res-auto"
108     android:layout_width="match_parent"
109     android:layout_height="match_parent">
110 
111     <include
112         layout="@layout/single_button_layout"
113         android:layout_width="wrap_content"
114         android:layout_height="wrap_content"
115         app:layout_constraintBottom_toBottomOf="parent"
116         app:layout_constraintEnd_toEndOf="parent"
117         app:layout_constraintStart_toStartOf="parent"
118         app:layout_constraintTop_toTopOf="parent" />
119 </android.support.constraint.ConstraintLayout>)";
120   ValidateXmlText(xml, /*expected=*/false);
121 }
122 
123 TEST(LayoutValidationTest, ViewNode) {
124   const string xml = R"(<?xml version="1.0" encoding="utf-8"?>
125 <android.support.constraint.ConstraintLayout
126     xmlns:android="http://schemas.android.com/apk/res/android"
127     xmlns:app="http://schemas.android.com/apk/res-auto"
128     android:layout_width="match_parent"
129     android:layout_height="match_parent">
130 
131     <view
132         class="android.support.design.button.MaterialButton"
133         id="@+id/view"
134         android:layout_width="wrap_content"
135         android:layout_height="wrap_content"
136         app:layout_constraintBottom_toBottomOf="parent"
137         app:layout_constraintEnd_toEndOf="parent"
138         app:layout_constraintStart_toStartOf="parent"
139         app:layout_constraintTop_toTopOf="parent" />
140 </android.support.constraint.ConstraintLayout>)";
141   ValidateXmlText(xml, /*expected=*/false);
142 }
143 
144 TEST(LayoutValidationTest, FragmentNode) {
145   // This test case is from https://developer.android.com/guide/components/fragments
146   const string xml = R"(<?xml version="1.0" encoding="utf-8"?>
147 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
148     android:orientation="horizontal"
149     android:layout_width="match_parent"
150     android:layout_height="match_parent">
151     <fragment android:name="com.example.news.ArticleListFragment"
152             android:id="@+id/list"
153             android:layout_weight="1"
154             android:layout_width="0dp"
155             android:layout_height="match_parent" />
156     <fragment android:name="com.example.news.ArticleReaderFragment"
157             android:id="@+id/viewer"
158             android:layout_weight="2"
159             android:layout_width="0dp"
160             android:layout_height="match_parent" />
161 </LinearLayout>)";
162   ValidateXmlText(xml, /*expected=*/false);
163 }
164