Home | History | Annotate | Download | only in protobuf
      1 // Protocol Buffers - Google's data interchange format
      2 // Copyright 2008 Google Inc.  All rights reserved.
      3 // https://developers.google.com/protocol-buffers/
      4 //
      5 // Redistribution and use in source and binary forms, with or without
      6 // modification, are permitted provided that the following conditions are
      7 // met:
      8 //
      9 //     * Redistributions of source code must retain the above copyright
     10 // notice, this list of conditions and the following disclaimer.
     11 //     * Redistributions in binary form must reproduce the above
     12 // copyright notice, this list of conditions and the following disclaimer
     13 // in the documentation and/or other materials provided with the
     14 // distribution.
     15 //     * Neither the name of Google Inc. nor the names of its
     16 // contributors may be used to endorse or promote products derived from
     17 // this software without specific prior written permission.
     18 //
     19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30 
     31 package com.google.protobuf;
     32 
     33 import static java.util.Arrays.asList;
     34 
     35 import junit.framework.TestCase;
     36 
     37 import java.util.ArrayList;
     38 import java.util.ConcurrentModificationException;
     39 import java.util.Iterator;
     40 import java.util.List;
     41 
     42 /**
     43  * Tests for {@link LazyStringArrayList}.
     44  *
     45  * @author jonp (at) google.com (Jon Perlow)
     46  */
     47 public class LazyStringArrayListTest extends TestCase {
     48 
     49   private static String STRING_A = "A";
     50   private static String STRING_B = "B";
     51   private static String STRING_C = "C";
     52 
     53   private static ByteString BYTE_STRING_A = ByteString.copyFromUtf8("A");
     54   private static ByteString BYTE_STRING_B = ByteString.copyFromUtf8("B");
     55   private static ByteString BYTE_STRING_C = ByteString.copyFromUtf8("C");
     56 
     57   public void testJustStrings() {
     58     LazyStringArrayList list = new LazyStringArrayList();
     59     list.add(STRING_A);
     60     list.add(STRING_B);
     61     list.add(STRING_C);
     62 
     63     assertEquals(3, list.size());
     64     assertSame(STRING_A, list.get(0));
     65     assertSame(STRING_B, list.get(1));
     66     assertSame(STRING_C, list.get(2));
     67 
     68     list.set(1, STRING_C);
     69     assertSame(STRING_C, list.get(1));
     70 
     71     list.remove(1);
     72     assertSame(STRING_A, list.get(0));
     73     assertSame(STRING_C, list.get(1));
     74 
     75     List<ByteString> byteStringList = list.asByteStringList();
     76     assertEquals(BYTE_STRING_A, byteStringList.get(0));
     77     assertEquals(BYTE_STRING_C, byteStringList.get(1));
     78 
     79     // Underlying list should be transformed.
     80     assertSame(byteStringList.get(0), list.getByteString(0));
     81     assertSame(byteStringList.get(1), list.getByteString(1));
     82   }
     83 
     84   public void testJustByteString() {
     85     LazyStringArrayList list = new LazyStringArrayList();
     86     list.add(BYTE_STRING_A);
     87     list.add(BYTE_STRING_B);
     88     list.add(BYTE_STRING_C);
     89 
     90     assertEquals(3, list.size());
     91     assertSame(BYTE_STRING_A, list.getByteString(0));
     92     assertSame(BYTE_STRING_B, list.getByteString(1));
     93     assertSame(BYTE_STRING_C, list.getByteString(2));
     94 
     95     list.remove(1);
     96     assertSame(BYTE_STRING_A, list.getByteString(0));
     97     assertSame(BYTE_STRING_C, list.getByteString(1));
     98 
     99     List<ByteString> byteStringList = list.asByteStringList();
    100     assertSame(BYTE_STRING_A, byteStringList.get(0));
    101     assertSame(BYTE_STRING_C, byteStringList.get(1));
    102   }
    103 
    104   public void testConversionBackAndForth() {
    105     LazyStringArrayList list = new LazyStringArrayList();
    106     list.add(STRING_A);
    107     list.add(BYTE_STRING_B);
    108     list.add(BYTE_STRING_C);
    109 
    110     // String a should be the same because it was originally a string
    111     assertSame(STRING_A, list.get(0));
    112 
    113     // String b and c should be different because the string has to be computed
    114     // from the ByteString
    115     String bPrime = list.get(1);
    116     assertNotSame(STRING_B, bPrime);
    117     assertEquals(STRING_B, bPrime);
    118     String cPrime = list.get(2);
    119     assertNotSame(STRING_C, cPrime);
    120     assertEquals(STRING_C, cPrime);
    121 
    122     // String c and c should stay the same once cached.
    123     assertSame(bPrime, list.get(1));
    124     assertSame(cPrime, list.get(2));
    125 
    126     // ByteString needs to be computed from string for both a and b
    127     ByteString aPrimeByteString = list.getByteString(0);
    128     assertEquals(BYTE_STRING_A, aPrimeByteString);
    129     ByteString bPrimeByteString = list.getByteString(1);
    130     assertNotSame(BYTE_STRING_B, bPrimeByteString);
    131     assertEquals(BYTE_STRING_B, list.getByteString(1));
    132 
    133     // Once cached, ByteString should stay cached.
    134     assertSame(aPrimeByteString, list.getByteString(0));
    135     assertSame(bPrimeByteString, list.getByteString(1));
    136   }
    137 
    138   public void testCopyConstructorCopiesByReference() {
    139     LazyStringArrayList list1 = new LazyStringArrayList();
    140     list1.add(STRING_A);
    141     list1.add(BYTE_STRING_B);
    142     list1.add(BYTE_STRING_C);
    143 
    144     LazyStringArrayList list2 = new LazyStringArrayList(list1);
    145     assertEquals(3, list2.size());
    146     assertSame(STRING_A, list2.get(0));
    147     assertSame(BYTE_STRING_B, list2.getByteString(1));
    148     assertSame(BYTE_STRING_C, list2.getByteString(2));
    149   }
    150 
    151   public void testListCopyConstructor() {
    152     List<String> list1 = new ArrayList<String>();
    153     list1.add(STRING_A);
    154     list1.add(STRING_B);
    155     list1.add(STRING_C);
    156 
    157     LazyStringArrayList list2 = new LazyStringArrayList(list1);
    158     assertEquals(3, list2.size());
    159     assertSame(STRING_A, list2.get(0));
    160     assertSame(STRING_B, list2.get(1));
    161     assertSame(STRING_C, list2.get(2));
    162   }
    163 
    164   public void testAddAllCopiesByReferenceIfPossible() {
    165     LazyStringArrayList list1 = new LazyStringArrayList();
    166     list1.add(STRING_A);
    167     list1.add(BYTE_STRING_B);
    168     list1.add(BYTE_STRING_C);
    169 
    170     LazyStringArrayList list2 = new LazyStringArrayList();
    171     list2.addAll(list1);
    172 
    173     assertEquals(3, list2.size());
    174     assertSame(STRING_A, list2.get(0));
    175     assertSame(BYTE_STRING_B, list2.getByteString(1));
    176     assertSame(BYTE_STRING_C, list2.getByteString(2));
    177   }
    178 
    179   public void testModificationWithIteration() {
    180     LazyStringArrayList list = new LazyStringArrayList();
    181     list.addAll(asList(STRING_A, STRING_B, STRING_C));
    182     Iterator<String> iterator = list.iterator();
    183     assertEquals(3, list.size());
    184     assertEquals(STRING_A, list.get(0));
    185     assertEquals(STRING_A, iterator.next());
    186 
    187     // Does not structurally modify.
    188     iterator = list.iterator();
    189     list.set(0, STRING_B);
    190     iterator.next();
    191 
    192     list.remove(0);
    193     try {
    194       iterator.next();
    195       fail();
    196     } catch (ConcurrentModificationException e) {
    197       // expected
    198     }
    199 
    200     iterator = list.iterator();
    201     list.add(0, STRING_C);
    202     try {
    203       iterator.next();
    204       fail();
    205     } catch (ConcurrentModificationException e) {
    206       // expected
    207     }
    208   }
    209 
    210   public void testMakeImmutable() {
    211     LazyStringArrayList list = new LazyStringArrayList();
    212     list.add(STRING_A);
    213     list.add(STRING_B);
    214     list.add(STRING_C);
    215     list.makeImmutable();
    216     assertGenericListImmutable(list, STRING_A);
    217 
    218     // LazyStringArrayList has extra methods not covered in the generic
    219     // assertion.
    220 
    221     try {
    222       list.add(BYTE_STRING_A.toByteArray());
    223       fail();
    224     } catch (UnsupportedOperationException e) {
    225       // expected
    226     }
    227 
    228     try {
    229       list.add(BYTE_STRING_A);
    230       fail();
    231     } catch (UnsupportedOperationException e) {
    232       // expected
    233     }
    234 
    235     try {
    236       list.addAllByteArray(asList(BYTE_STRING_A.toByteArray()));
    237       fail();
    238     } catch (UnsupportedOperationException e) {
    239       // expected
    240     }
    241 
    242     try {
    243       list.addAllByteString(asList(BYTE_STRING_A));
    244       fail();
    245     } catch (UnsupportedOperationException e) {
    246       // expected
    247     }
    248 
    249     try {
    250       list.mergeFrom(new LazyStringArrayList());
    251       fail();
    252     } catch (UnsupportedOperationException e) {
    253       // expected
    254     }
    255 
    256     try {
    257       list.set(0, BYTE_STRING_A.toByteArray());
    258       fail();
    259     } catch (UnsupportedOperationException e) {
    260       // expected
    261     }
    262 
    263     try {
    264       list.set(0, BYTE_STRING_A);
    265       fail();
    266     } catch (UnsupportedOperationException e) {
    267       // expected
    268     }
    269   }
    270 
    271   public void testImmutabilityPropagation() {
    272     LazyStringArrayList list = new LazyStringArrayList();
    273     list.add(STRING_A);
    274     list.makeImmutable();
    275 
    276     assertGenericListImmutable(list.asByteStringList(), BYTE_STRING_A);
    277 
    278     // Arrays use reference equality so need to retrieve the underlying value
    279     // to properly test deep immutability.
    280     List<byte[]> byteArrayList = list.asByteArrayList();
    281     assertGenericListImmutable(byteArrayList, byteArrayList.get(0));
    282   }
    283 
    284   private static <T> void assertGenericListImmutable(List<T> list, T value) {
    285     try {
    286       list.add(value);
    287       fail();
    288     } catch (UnsupportedOperationException e) {
    289       // expected
    290     }
    291 
    292     try {
    293       list.add(0, value);
    294       fail();
    295     } catch (UnsupportedOperationException e) {
    296       // expected
    297     }
    298 
    299     try {
    300       list.addAll(asList(value));
    301       fail();
    302     } catch (UnsupportedOperationException e) {
    303       // expected
    304     }
    305 
    306     try {
    307       list.addAll(0, asList(value));
    308       fail();
    309     } catch (UnsupportedOperationException e) {
    310       // expected
    311     }
    312 
    313     try {
    314       list.clear();
    315       fail();
    316     } catch (UnsupportedOperationException e) {
    317       // expected
    318     }
    319 
    320     try {
    321       list.remove(0);
    322       fail();
    323     } catch (UnsupportedOperationException e) {
    324       // expected
    325     }
    326 
    327     try {
    328       list.remove(value);
    329       fail();
    330     } catch (UnsupportedOperationException e) {
    331       // expected
    332     }
    333 
    334     try {
    335       list.removeAll(asList(value));
    336       fail();
    337     } catch (UnsupportedOperationException e) {
    338       // expected
    339     }
    340 
    341     try {
    342       list.retainAll(asList());
    343       fail();
    344     } catch (UnsupportedOperationException e) {
    345       // expected
    346     }
    347 
    348     try {
    349       list.retainAll(asList());
    350       fail();
    351     } catch (UnsupportedOperationException e) {
    352       // expected
    353     }
    354 
    355     try {
    356       list.set(0, value);
    357       fail();
    358     } catch (UnsupportedOperationException e) {
    359       // expected
    360     }
    361   }
    362 }
    363