1 /* Copyright (c) 2011, 2021, Oracle and/or its affiliates.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
22 
23 // First include (the generated) my_config.h, to get correct platform defines.
24 #include "my_config.h"
25 #include <gtest/gtest.h>
26 
27 #include "sql_plist.h"
28 #include "test_utils.h"
29 
30 namespace sql_plist_unittest {
31 
32 // A simple helper function to insert values into a List.
33 template <class T, int size, class L>
insert_values(T (& array)[size],L * list)34 void insert_values(T (&array)[size], L *list)
35 {
36   uint ix, elements= list->elements();
37   for (ix= 0; ix < size; ++ix)
38     list->push_back(&array[ix]);
39   EXPECT_EQ(ix + elements, list->elements());
40 }
41 
42 /*
43   The fixture for testing the MySQL List and List_iterator classes.
44   A fresh instance of this class will be created for each of the
45   TEST_F functions below.
46 */
47 class IPListTest : public ::testing::Test
48 {
49 protected:
IPListTest()50   IPListTest()
51     : m_int_list(), m_int_list_iter(m_int_list)
52   {
53   }
54 
55 public:
56   template<typename V>
57   struct I_P_ListTestValue
58   {
59     V value;
I_P_ListTestValuesql_plist_unittest::IPListTest::I_P_ListTestValue60     I_P_ListTestValue(V val) : value(val) {}
operator ==sql_plist_unittest::IPListTest::I_P_ListTestValue61     bool operator == (const I_P_ListTestValue<V> &obj) const
62     { return value == obj.value; }
63     struct I_P_ListTestValue<V> *next;
64     struct I_P_ListTestValue<V> **prev;
65   };
66 
67 protected:
68   template<typename V>
69   struct I_P_ListCountedPushBack
70   {
71     typedef I_P_ListTestValue<V> Value;
72     typedef I_P_List<Value,
73                      I_P_List_adapter<Value, &Value::next, &Value::prev>,
74                      I_P_List_counter,
75                      I_P_List_fast_push_back<Value>
76                     > Type;
77   };
78 
79   I_P_ListCountedPushBack<int>::Type m_int_list;
80   I_P_ListCountedPushBack<int>::Type::Iterator m_int_list_iter;
81 
82 private:
83   // Declares (but does not define) copy constructor and assignment operator.
84   GTEST_DISALLOW_COPY_AND_ASSIGN_(IPListTest);
85 };
86 
87 
88 // Allow construction of test messages via the << operator.
89 template<typename T>
operator <<(std::ostream & s,const IPListTest::I_P_ListTestValue<T> & v)90 std::ostream &operator<< (std::ostream &s,
91                           const IPListTest::I_P_ListTestValue<T> &v)
92 {
93   return s << v.value;
94 }
95 
96 
97 // Tests that we can construct and destruct lists.
TEST_F(IPListTest,ConstructAndDestruct)98 TEST_F(IPListTest, ConstructAndDestruct)
99 {
100   EXPECT_TRUE(m_int_list.is_empty());
101   I_P_ListCountedPushBack<int>::Type *p_int_list;
102   p_int_list= new I_P_ListCountedPushBack<int>::Type;
103   EXPECT_TRUE(p_int_list->is_empty());
104   delete p_int_list;
105 }
106 
107 
108 // Tests basic operations push and remove.
TEST_F(IPListTest,BasicOperations)109 TEST_F(IPListTest, BasicOperations)
110 {
111   I_P_ListTestValue<int> v1(1), v2(2), v3(3);
112   m_int_list.push_front(&v1);
113   m_int_list.insert_after(&v1, &v2);
114   m_int_list.push_back(&v3);
115   EXPECT_FALSE(m_int_list.is_empty());
116   EXPECT_EQ(3U, m_int_list.elements());
117 
118   EXPECT_EQ(&v1, m_int_list.front());
119   m_int_list.remove(&v1);
120   EXPECT_EQ(&v2, m_int_list.front());
121   m_int_list.remove(&v2);
122   EXPECT_EQ(&v3, m_int_list.front());
123   m_int_list.remove(&v3);
124   EXPECT_TRUE(m_int_list.is_empty()) << "The list should be empty now!";
125 }
126 
127 
128 // Tests that we can iterate over values.
TEST_F(IPListTest,Iterate)129 TEST_F(IPListTest, Iterate)
130 {
131   I_P_ListTestValue<int> values[]= {3, 2, 1};
132   insert_values(values, &m_int_list);
133   m_int_list_iter.init(m_int_list);
134   for (int ix= 0; ix < array_size(values); ++ix)
135   {
136     EXPECT_EQ(values[ix], *m_int_list_iter++);
137   }
138   m_int_list_iter.init(m_int_list);
139   I_P_ListTestValue<int> *value;
140   int value_number= 0;
141   while ((value= m_int_list_iter++))
142   {
143     EXPECT_EQ(values[value_number++], value->value);
144   }
145 }
146 
147 }  // namespace
148