Home | History | Annotate | Download | only in databinding
      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 android.databinding;
     18 
     19 import android.os.Parcel;
     20 import android.os.Parcelable;
     21 import android.test.AndroidTestCase;
     22 
     23 import java.io.ByteArrayInputStream;
     24 import java.io.ByteArrayOutputStream;
     25 import java.io.Closeable;
     26 import java.io.IOException;
     27 import java.io.ObjectInputStream;
     28 import java.io.ObjectOutputStream;
     29 import java.io.Serializable;
     30 import java.util.UUID;
     31 
     32 public class ObservableParcelTest extends AndroidTestCase {
     33     public void testParcelInt() {
     34         ObservableInt observableInt = new ObservableInt();
     35         observableInt.set(Integer.MAX_VALUE - 1);
     36         ObservableInt read = parcelAndUnparcel(observableInt, ObservableInt.class);
     37         assertEquals(Integer.MAX_VALUE - 1, read.get());
     38     }
     39 
     40     public void testParcelBoolean() {
     41         ObservableBoolean obj = new ObservableBoolean(false);
     42         ObservableBoolean read = parcelAndUnparcel(obj, ObservableBoolean.class);
     43         assertFalse(read.get());
     44 
     45         ObservableBoolean obj2 = new ObservableBoolean(true);
     46         ObservableBoolean read2 = parcelAndUnparcel(obj2, ObservableBoolean.class);
     47         assertTrue(read2.get());
     48     }
     49 
     50     public void testParcelByte() {
     51         ObservableByte obj = new ObservableByte((byte) 7);
     52         ObservableByte read = parcelAndUnparcel(obj, ObservableByte.class);
     53         assertEquals((byte) 7, read.get());
     54     }
     55 
     56     public void testParcelChar() {
     57         ObservableChar obj = new ObservableChar('y');
     58         ObservableChar read = parcelAndUnparcel(obj, ObservableChar.class);
     59         assertEquals('y', read.get());
     60     }
     61 
     62     public void testParcelDouble() {
     63         ObservableDouble obj = new ObservableDouble(Double.MAX_VALUE);
     64         ObservableDouble read = parcelAndUnparcel(obj, ObservableDouble.class);
     65         assertEquals(Double.MAX_VALUE, read.get());
     66     }
     67 
     68     public void testParcelFloat() {
     69         ObservableFloat obj = new ObservableFloat(Float.MIN_VALUE);
     70         ObservableFloat read = parcelAndUnparcel(obj, ObservableFloat.class);
     71         assertEquals(Float.MIN_VALUE, read.get());
     72     }
     73 
     74     public void testParcelParcel() {
     75         MyParcelable myParcelable = new MyParcelable(5, "foo");
     76         ObservableParcelable<MyParcelable> obj = new ObservableParcelable<>(myParcelable);
     77         ObservableParcelable read = parcelAndUnparcel(obj,
     78                 ObservableParcelable.class);
     79         assertEquals(myParcelable, read.get());
     80     }
     81 
     82     public void testParcelLong() {
     83         ObservableLong obj = new ObservableLong(Long.MAX_VALUE - 1);
     84         ObservableLong read = parcelAndUnparcel(obj, ObservableLong.class);
     85         assertEquals(Long.MAX_VALUE - 1, read.get());
     86     }
     87 
     88     public void testParcelShort() {
     89         ObservableShort obj = new ObservableShort(Short.MIN_VALUE);
     90         ObservableShort read = parcelAndUnparcel(obj, ObservableShort.class);
     91         assertEquals(Short.MIN_VALUE, read.get());
     92     }
     93 
     94     public void testSerializeInt() throws IOException, ClassNotFoundException {
     95         ObservableInt observableInt = new ObservableInt();
     96         observableInt.set(Integer.MAX_VALUE - 1);
     97         ObservableInt read = serializeAndDeserialize(observableInt, ObservableInt.class);
     98         assertEquals(Integer.MAX_VALUE - 1, read.get());
     99     }
    100 
    101     public void testSerializeBoolean() throws IOException, ClassNotFoundException {
    102         ObservableBoolean obj = new ObservableBoolean(false);
    103         ObservableBoolean read = serializeAndDeserialize(obj, ObservableBoolean.class);
    104         assertFalse(read.get());
    105         ObservableBoolean obj2 = new ObservableBoolean(true);
    106         ObservableBoolean read2 = serializeAndDeserialize(obj2, ObservableBoolean.class);
    107         assertTrue(read2.get());
    108     }
    109 
    110     public void testSerializeByte() throws IOException, ClassNotFoundException {
    111         ObservableByte obj = new ObservableByte((byte) 7);
    112         ObservableByte read = serializeAndDeserialize(obj, ObservableByte.class);
    113         assertEquals((byte) 7, read.get());
    114     }
    115 
    116     public void testSerializeChar() throws IOException, ClassNotFoundException {
    117         ObservableChar obj = new ObservableChar('y');
    118         ObservableChar read = serializeAndDeserialize(obj, ObservableChar.class);
    119         assertEquals('y', read.get());
    120     }
    121 
    122     public void testSerializeDouble() throws IOException, ClassNotFoundException {
    123         ObservableDouble obj = new ObservableDouble(Double.MAX_VALUE);
    124         ObservableDouble read = serializeAndDeserialize(obj, ObservableDouble.class);
    125         assertEquals(Double.MAX_VALUE, read.get());
    126     }
    127 
    128     public void testSerializeFloat() throws IOException, ClassNotFoundException {
    129         ObservableFloat obj = new ObservableFloat(Float.MIN_VALUE);
    130         ObservableFloat read = serializeAndDeserialize(obj, ObservableFloat.class);
    131         assertEquals(Float.MIN_VALUE, read.get());
    132     }
    133 
    134     public void testSerializeParcel() throws IOException, ClassNotFoundException {
    135         MyParcelable myParcelable = new MyParcelable(5, "foo");
    136         ObservableParcelable<MyParcelable> obj = new ObservableParcelable<>(myParcelable);
    137         ObservableParcelable read = serializeAndDeserialize(obj,
    138                 ObservableParcelable.class);
    139         assertEquals(myParcelable, read.get());
    140     }
    141 
    142     public void testSerializeField() throws IOException, ClassNotFoundException {
    143         MyParcelable myParcelable = new MyParcelable(5, "foo");
    144         ObservableField<MyParcelable> obj = new ObservableField<>(myParcelable);
    145         ObservableField read = serializeAndDeserialize(obj, ObservableField.class);
    146         assertEquals(myParcelable, read.get());
    147     }
    148 
    149     public void testSerializeLong() throws IOException, ClassNotFoundException {
    150         ObservableLong obj = new ObservableLong(Long.MAX_VALUE - 1);
    151         ObservableLong read = serializeAndDeserialize(obj, ObservableLong.class);
    152         assertEquals(Long.MAX_VALUE - 1, read.get());
    153     }
    154 
    155     public void testSerializeShort() throws IOException, ClassNotFoundException {
    156         ObservableShort obj = new ObservableShort(Short.MIN_VALUE);
    157         ObservableShort read = serializeAndDeserialize(obj, ObservableShort.class);
    158         assertEquals(Short.MIN_VALUE, read.get());
    159     }
    160 
    161     private <T extends Parcelable> T parcelAndUnparcel(T t, Class<T> klass) {
    162         Parcel parcel = Parcel.obtain();
    163         parcel.writeParcelable(t, 0);
    164         // we append a suffix to the parcelable to test out of bounds
    165         String parcelSuffix = UUID.randomUUID().toString();
    166         parcel.writeString(parcelSuffix);
    167         // get ready to read
    168         parcel.setDataPosition(0);
    169         Parcelable parcelable = parcel.readParcelable(getClass().getClassLoader());
    170         assertNotNull(parcelable);
    171         assertEquals(klass, parcelable.getClass());
    172         assertEquals(parcelSuffix, parcel.readString());
    173         return (T) parcelable;
    174     }
    175 
    176     private <T> T serializeAndDeserialize(T t, Class<T> klass)
    177             throws IOException, ClassNotFoundException {
    178         ObjectOutputStream oos = null;
    179         ByteArrayOutputStream bos = null;
    180         String suffix = UUID.randomUUID().toString();
    181         try {
    182             bos = new ByteArrayOutputStream();
    183             oos = new ObjectOutputStream(bos);
    184             oos.writeObject(t);
    185             oos.writeObject(suffix);
    186         } finally {
    187             closeQuietly(bos);
    188             closeQuietly(oos);
    189         }
    190         ByteArrayInputStream bis = null;
    191         ObjectInputStream ois = null;
    192         try {
    193             bis = new ByteArrayInputStream(bos.toByteArray());
    194             ois = new ObjectInputStream(bis);
    195             Object o = ois.readObject();
    196             assertEquals(klass, o.getClass());
    197             assertEquals(suffix, ois.readObject());
    198             return (T) o;
    199         } finally {
    200             closeQuietly(bis);
    201             closeQuietly(ois);
    202         }
    203     }
    204 
    205     private static void closeQuietly(Closeable closeable) {
    206         try {
    207             if (closeable != null) {
    208                 closeable.close();
    209             }
    210         } catch (IOException ignored) {
    211         }
    212     }
    213 
    214     public static class MyParcelable implements Parcelable, Serializable {
    215         int x;
    216         String y;
    217 
    218         public MyParcelable() {
    219         }
    220 
    221         public MyParcelable(int x, String y) {
    222             this.x = x;
    223             this.y = y;
    224         }
    225 
    226         @Override
    227         public int describeContents() {
    228             return 0;
    229         }
    230 
    231         @Override
    232         public void writeToParcel(Parcel dest, int flags) {
    233             dest.writeInt(x);
    234             dest.writeString(y);
    235         }
    236 
    237         @Override
    238         public boolean equals(Object o) {
    239             if (this == o) {
    240                 return true;
    241             }
    242             if (o == null || getClass() != o.getClass()) {
    243                 return false;
    244             }
    245 
    246             MyParcelable that = (MyParcelable) o;
    247 
    248             if (x != that.x) {
    249                 return false;
    250             }
    251             if (y != null ? !y.equals(that.y) : that.y != null) {
    252                 return false;
    253             }
    254 
    255             return true;
    256         }
    257 
    258         @Override
    259         public int hashCode() {
    260             int result = x;
    261             result = 31 * result + (y != null ? y.hashCode() : 0);
    262             return result;
    263         }
    264 
    265         public static final Parcelable.Creator<MyParcelable> CREATOR
    266                 = new Parcelable.Creator<MyParcelable>() {
    267 
    268             @Override
    269             public MyParcelable createFromParcel(Parcel source) {
    270                 return new MyParcelable(source.readInt(), source.readString());
    271             }
    272 
    273             @Override
    274             public MyParcelable[] newArray(int size) {
    275                 return new MyParcelable[size];
    276             }
    277         };
    278     }
    279 }
    280