Home | History | Annotate | Download | only in impl
      1 /*
      2  * Copyright (C) 2015 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 
     17 package com.android.layoutlib.bridge.impl;
     18 
     19 import org.junit.Test;
     20 import org.kxml2.io.KXmlParser;
     21 import org.xmlpull.v1.XmlPullParser;
     22 import org.xmlpull.v1.XmlPullParserException;
     23 
     24 import java.io.StringReader;
     25 
     26 import static com.android.SdkConstants.NS_RESOURCES;
     27 import static org.junit.Assert.assertEquals;
     28 import static org.junit.Assert.assertNotSame;
     29 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
     30 import static org.xmlpull.v1.XmlPullParser.END_TAG;
     31 import static org.xmlpull.v1.XmlPullParser.START_TAG;
     32 
     33 
     34 public class LayoutParserWrapperTest {
     35     @Test
     36     @SuppressWarnings("StatementWithEmptyBody")  // some for loops need to be empty statements.
     37     public void testDataBindingLayout() throws Exception {
     38         LayoutParserWrapper parser = getParserFromString(sDataBindingLayout);
     39         parser.peekTillLayoutStart();
     40         assertEquals("Expected START_TAG", START_TAG, parser.next());
     41         assertEquals("RelativeLayout", parser.getName());
     42         for (int next = parser.next(); next != START_TAG && next != END_DOCUMENT;
     43              next = parser.next());
     44         assertEquals("Expected START_TAG", START_TAG, parser.getEventType());
     45         assertEquals("TextView", parser.getName());
     46         assertEquals("layout_width incorrect for first text view.", "wrap_content",
     47                 parser.getAttributeValue(NS_RESOURCES, "layout_width"));
     48         // Ensure that data-binding part is stripped.
     49         assertEquals("Bound attribute android:text incorrect", "World",
     50                 parser.getAttributeValue(NS_RESOURCES, "text"));
     51         assertEquals("resource attribute 'id' for first text view incorrect.", "@+id/first",
     52                 parser.getAttributeValue(NS_RESOURCES, "id"));
     53         for (int next = parser.next();
     54              (next != END_TAG || !"RelativeLayout".equals(parser.getName())) && next != END_DOCUMENT;
     55              next = parser.next());
     56         assertNotSame("Unexpected end of document", END_DOCUMENT, parser.getEventType());
     57         assertEquals("Document didn't end when expected.", END_DOCUMENT, parser.next());
     58     }
     59 
     60     @Test
     61     @SuppressWarnings("StatementWithEmptyBody")
     62     public void testNonDataBindingLayout() throws Exception {
     63         LayoutParserWrapper parser = getParserFromString(sNonDataBindingLayout);
     64         parser.peekTillLayoutStart();
     65         assertEquals("Expected START_TAG", START_TAG, parser.next());
     66         assertEquals("RelativeLayout", parser.getName());
     67         for (int next = parser.next(); next != START_TAG && next != END_DOCUMENT;
     68              next = parser.next());
     69         assertEquals("Expected START_TAG", START_TAG, parser.getEventType());
     70         assertEquals("TextView", parser.getName());
     71         assertEquals("layout_width incorrect for first text view.", "wrap_content",
     72                 parser.getAttributeValue(NS_RESOURCES, "layout_width"));
     73         // Ensure that value isn't modified.
     74         assertEquals("Bound attribute android:text incorrect", "@{user.firstName,default=World}",
     75                 parser.getAttributeValue(NS_RESOURCES, "text"));
     76         assertEquals("resource attribute 'id' for first text view incorrect.", "@+id/first",
     77                 parser.getAttributeValue(NS_RESOURCES, "id"));
     78         for (int next = parser.next();
     79              (next != END_TAG || !"RelativeLayout".equals(parser.getName())) && next != END_DOCUMENT;
     80              next = parser.next());
     81         assertNotSame("Unexpected end of document", END_DOCUMENT, parser.getEventType());
     82         assertEquals("Document didn't end when expected.", END_DOCUMENT, parser.next());
     83     }
     84 
     85     private static LayoutParserWrapper getParserFromString(String layoutContent) throws
     86             XmlPullParserException {
     87         XmlPullParser parser = new KXmlParser();
     88         parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
     89         parser.setInput(new StringReader(layoutContent));
     90         return new LayoutParserWrapper(parser);
     91     }
     92 
     93     private static final String sDataBindingLayout =
     94             //language=XML
     95             "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
     96                     "<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
     97                     "        xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n" +
     98                     "        xmlns:tools=\"http://schemas.android.com/tools\"\n" +
     99                     "        tools:context=\".MainActivity\"\n" +
    100                     "        tools:showIn=\"@layout/activity_main\">\n" +
    101                     "\n" +
    102                     "    <data>\n" +
    103                     "\n" +
    104                     "        <variable\n" +
    105                     "            name=\"user\"\n" +
    106                     "            type=\"com.example.User\" />\n" +
    107                     "        <variable\n" +
    108                     "            name=\"activity\"\n" +
    109                     "            type=\"com.example.MainActivity\" />\n" +
    110                     "    </data>\n" +
    111                     "\n" +
    112                     "    <RelativeLayout\n" +
    113                     "        android:layout_width=\"match_parent\"\n" +
    114                     "        android:layout_height=\"match_parent\"\n" +
    115                     "        android:paddingBottom=\"@dimen/activity_vertical_margin\"\n" +
    116                     "        android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n" +
    117                     "        android:paddingRight=\"@dimen/activity_horizontal_margin\"\n" +
    118                     "        android:paddingTop=\"@dimen/activity_vertical_margin\"\n" +
    119                     "        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n" +
    120                     "    >\n" +
    121                     "\n" +
    122                     "        <TextView\n" +
    123                     "            android:id=\"@+id/first\"\n" +
    124                     "            android:layout_width=\"wrap_content\"\n" +
    125                     "            android:layout_alignParentStart=\"true\"\n" +
    126                     "            android:layout_alignParentLeft=\"true\"\n" +
    127                     "            android:layout_height=\"wrap_content\"\n" +
    128                     "            android:text=\"@{user.firstName,default=World}\" />\n" +
    129                     "\n" +
    130                     "        <TextView\n" +
    131                     "            android:id=\"@+id/last\"\n" +
    132                     "            android:layout_width=\"wrap_content\"\n" +
    133                     "            android:layout_height=\"wrap_content\"\n" +
    134                     "            android:layout_toEndOf=\"@id/first\"\n" +
    135                     "            android:layout_toRightOf=\"@id/first\"\n" +
    136                     "            android:text=\"@{user.lastName,default=Hello}\" />\n" +
    137                     "\n" +
    138                     "        <Button\n" +
    139                     "            android:layout_width=\"wrap_content\"\n" +
    140                     "            android:layout_height=\"wrap_content\"\n" +
    141                     "            android:layout_below=\"@id/last\"\n" +
    142                     "            android:text=\"Submit\"\n" +
    143                     "            android:onClick=\"@{activity.onClick}\"/>\n" +
    144                     "    </RelativeLayout>\n" +
    145                     "</layout>";
    146 
    147     private static final String sNonDataBindingLayout =
    148             //language=XML
    149             "<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
    150                     "    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n" +
    151                     "    android:layout_width=\"match_parent\"\n" +
    152                     "    android:layout_height=\"match_parent\"\n" +
    153                     "    android:paddingBottom=\"@dimen/activity_vertical_margin\"\n" +
    154                     "    android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n" +
    155                     "    android:paddingRight=\"@dimen/activity_horizontal_margin\"\n" +
    156                     "    android:paddingTop=\"@dimen/activity_vertical_margin\"\n" +
    157                     "    app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n" +
    158                     ">\n" +
    159                     "\n" +
    160                     "    <TextView\n" +
    161                     "        android:id=\"@+id/first\"\n" +
    162                     "        android:layout_width=\"wrap_content\"\n" +
    163                     "        android:layout_alignParentStart=\"true\"\n" +
    164                     "        android:layout_alignParentLeft=\"true\"\n" +
    165                     "        android:layout_height=\"wrap_content\"\n" +
    166                     "        android:text=\"@{user.firstName,default=World}\" />\n" +
    167                     "\n" +
    168                     "    <TextView\n" +
    169                     "        android:id=\"@+id/last\"\n" +
    170                     "        android:layout_width=\"wrap_content\"\n" +
    171                     "        android:layout_height=\"wrap_content\"\n" +
    172                     "        android:layout_toEndOf=\"@id/first\"\n" +
    173                     "        android:layout_toRightOf=\"@id/first\"\n" +
    174                     "        android:text=\"@{user.lastName,default=Hello}\" />\n" +
    175                     "\n" +
    176                     "    <Button\n" +
    177                     "        android:layout_width=\"wrap_content\"\n" +
    178                     "        android:layout_height=\"wrap_content\"\n" +
    179                     "        android:layout_below=\"@id/last\"\n" +
    180                     "        android:text=\"Submit\"\n" +
    181                     "        android:onClick=\"@{activity.onClick}\"/>\n" +
    182                     "</RelativeLayout>";
    183 }
    184