Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *  * Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  *  * Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in
     12  *    the documentation and/or other materials provided with the
     13  *    distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
     22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #include <stdlib.h>
     30 #include <string>
     31 #include <sstream>
     32 
     33 #include <gtest/gtest.h>
     34 
     35 #include "../linked_list.h"
     36 
     37 namespace {
     38 
     39 bool alloc_called = false;
     40 bool free_called = false;
     41 
     42 class LinkedListTestAllocator {
     43  public:
     44   typedef LinkedListEntry<const char> entry_t;
     45 
     46   static entry_t* alloc() {
     47     alloc_called = true;
     48     return reinterpret_cast<entry_t*>(::malloc(sizeof(entry_t)));
     49   }
     50 
     51   static void free(entry_t* p) {
     52     free_called = true;
     53     ::free(p);
     54   }
     55  private:
     56   DISALLOW_IMPLICIT_CONSTRUCTORS(LinkedListTestAllocator);
     57 };
     58 
     59 typedef LinkedList<const char, LinkedListTestAllocator> test_list_t;
     60 
     61 std::string test_list_to_string(test_list_t& list) {
     62   std::stringstream ss;
     63   list.for_each([&] (const char* c) {
     64     ss << c;
     65   });
     66 
     67   return ss.str();
     68 }
     69 
     70 };
     71 
     72 TEST(linked_list, simple) {
     73   alloc_called = free_called = false;
     74   test_list_t list;
     75   ASSERT_EQ("", test_list_to_string(list));
     76   ASSERT_TRUE(!alloc_called);
     77   ASSERT_TRUE(!free_called);
     78   list.push_front("a");
     79   ASSERT_TRUE(alloc_called);
     80   ASSERT_TRUE(!free_called);
     81   ASSERT_EQ("a", test_list_to_string(list));
     82   list.push_front("b");
     83   ASSERT_EQ("ba", test_list_to_string(list));
     84   list.push_front("c");
     85   list.push_front("d");
     86   ASSERT_EQ("dcba", test_list_to_string(list));
     87   ASSERT_TRUE(alloc_called);
     88   ASSERT_TRUE(!free_called);
     89   alloc_called = free_called = false;
     90   list.remove_if([] (const char* c) {
     91     return *c == 'c';
     92   });
     93 
     94   ASSERT_TRUE(!alloc_called);
     95   ASSERT_TRUE(free_called);
     96 
     97   ASSERT_EQ("dba", test_list_to_string(list));
     98   alloc_called = free_called = false;
     99   list.remove_if([] (const char* c) {
    100     return *c == '2';
    101   });
    102   ASSERT_TRUE(!alloc_called);
    103   ASSERT_TRUE(!free_called);
    104   ASSERT_EQ("dba", test_list_to_string(list));
    105   list.clear();
    106   ASSERT_TRUE(!alloc_called);
    107   ASSERT_TRUE(free_called);
    108   ASSERT_EQ("", test_list_to_string(list));
    109 }
    110 
    111 TEST(linked_list, push_pop) {
    112   test_list_t list;
    113   list.push_front("b");
    114   list.push_front("a");
    115   ASSERT_EQ("ab", test_list_to_string(list));
    116   list.push_back("c");
    117   ASSERT_EQ("abc", test_list_to_string(list));
    118   ASSERT_STREQ("a", list.pop_front());
    119   ASSERT_EQ("bc", test_list_to_string(list));
    120   ASSERT_STREQ("b", list.pop_front());
    121   ASSERT_EQ("c", test_list_to_string(list));
    122   ASSERT_STREQ("c", list.pop_front());
    123   ASSERT_EQ("", test_list_to_string(list));
    124   ASSERT_TRUE(list.pop_front() == nullptr);
    125   list.push_back("r");
    126   ASSERT_EQ("r", test_list_to_string(list));
    127   ASSERT_STREQ("r", list.pop_front());
    128   ASSERT_TRUE(list.pop_front() == nullptr);
    129 }
    130 
    131 TEST(linked_list, remove_if_then_pop) {
    132   test_list_t list;
    133   list.push_back("a");
    134   list.push_back("b");
    135   list.push_back("c");
    136   list.push_back("d");
    137   list.remove_if([](const char* c) {
    138     return *c == 'b' || *c == 'c';
    139   });
    140 
    141   ASSERT_EQ("ad", test_list_to_string(list));
    142   ASSERT_STREQ("a", list.pop_front());
    143   ASSERT_EQ("d", test_list_to_string(list));
    144   ASSERT_STREQ("d", list.pop_front());
    145   ASSERT_TRUE(list.pop_front() == nullptr);
    146 }
    147 
    148 TEST(linked_list, remove_if_last_then_push_back) {
    149   test_list_t list;
    150 
    151   list.push_back("a");
    152   list.push_back("b");
    153   list.push_back("c");
    154   list.push_back("d");
    155 
    156   list.remove_if([](const char* c) {
    157     return *c == 'c' || *c == 'd';
    158   });
    159 
    160   ASSERT_EQ("ab", test_list_to_string(list));
    161   list.push_back("d");
    162   ASSERT_EQ("abd", test_list_to_string(list));
    163 }
    164 
    165 TEST(linked_list, copy_to_array) {
    166   test_list_t list;
    167   const size_t max_size = 128;
    168   const char* buf[max_size];
    169   memset(buf, 0, sizeof(buf));
    170 
    171   ASSERT_EQ(0U, list.copy_to_array(buf, max_size));
    172   ASSERT_EQ(nullptr, buf[0]);
    173 
    174   list.push_back("a");
    175   list.push_back("b");
    176   list.push_back("c");
    177   list.push_back("d");
    178 
    179   memset(buf, 0, sizeof(buf));
    180   ASSERT_EQ(2U, list.copy_to_array(buf, 2));
    181   ASSERT_STREQ("a", buf[0]);
    182   ASSERT_STREQ("b", buf[1]);
    183   ASSERT_EQ(nullptr, buf[2]);
    184 
    185   ASSERT_EQ(4U, list.copy_to_array(buf, max_size));
    186   ASSERT_STREQ("a", buf[0]);
    187   ASSERT_STREQ("b", buf[1]);
    188   ASSERT_STREQ("c", buf[2]);
    189   ASSERT_STREQ("d", buf[3]);
    190   ASSERT_EQ(nullptr, buf[4]);
    191 
    192   memset(buf, 0, sizeof(buf));
    193   list.remove_if([](const char* c) {
    194     return *c != 'c';
    195   });
    196   ASSERT_EQ(1U, list.copy_to_array(buf, max_size));
    197   ASSERT_STREQ("c", buf[0]);
    198   ASSERT_EQ(nullptr, buf[1]);
    199 
    200   memset(buf, 0, sizeof(buf));
    201 
    202   list.remove_if([](const char* c) {
    203     return *c == 'c';
    204   });
    205 
    206   ASSERT_EQ(0U, list.copy_to_array(buf, max_size));
    207   ASSERT_EQ(nullptr, buf[0]);
    208 }
    209 
    210 TEST(linked_list, test_visit) {
    211   test_list_t list;
    212   list.push_back("a");
    213   list.push_back("b");
    214   list.push_back("c");
    215   list.push_back("d");
    216 
    217   int visits = 0;
    218   std::stringstream ss;
    219   bool result = list.visit([&](const char* c) {
    220     ++visits;
    221     ss << c;
    222     return true;
    223   });
    224 
    225   ASSERT_TRUE(result);
    226   ASSERT_EQ(4, visits);
    227   ASSERT_EQ("abcd", ss.str());
    228 
    229   visits = 0;
    230   ss.str(std::string());
    231 
    232   result = list.visit([&](const char* c) {
    233     if (++visits == 3) {
    234       return false;
    235     }
    236 
    237     ss << c;
    238     return true;
    239   });
    240 
    241   ASSERT_TRUE(!result);
    242   ASSERT_EQ(3, visits);
    243   ASSERT_EQ("ab", ss.str());
    244 }
    245 
    246