1// Copyright 2014 The Android Open Source Project
2//
3// This software is licensed under the terms of the GNU General Public
4// License version 2, as published by the Free Software Foundation, and
5// may be copied, distributed, and modified under those terms.
6//
7// This program is distributed in the hope that it will be useful,
8// but WITHOUT ANY WARRANTY; without even the implied warranty of
9// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10// GNU General Public License for more details.
11
12#include "android/base/containers/StringVector.h"
13
14#include <gtest/gtest.h>
15
16namespace android {
17namespace base {
18
19// Generate a pseudo-random string.
20static String genHashString(size_t n) {
21    size_t count = ((n << 3) ^ ((n >> 1) * 11)) % 100;
22    String result;
23    size_t hash = 3467 * n;
24    for (size_t n = 0; n < count; ++n) {
25        result += "0123456789abcdefghijklmnopqrstvuwxyz"[hash % 36];
26        hash = hash * 3667 + n;
27    }
28    return result;
29}
30
31TEST(StringVector, Empty) {
32    StringVector v;
33    EXPECT_TRUE(v.empty());
34    EXPECT_EQ(0U, v.size());
35}
36
37TEST(StringVector, ResizeGrows) {
38    StringVector v;
39    const size_t kCount = 100;
40    v.resize(kCount);
41    EXPECT_EQ(kCount, v.size());
42    for (size_t n = 0; n < kCount; ++n) {
43        EXPECT_TRUE(v[n].empty());
44    }
45}
46
47TEST(StringVector, AppendOneString) {
48    StringVector v;
49    String str("Hello World");
50    v.append(str);
51    EXPECT_EQ(1U, v.size());
52    EXPECT_NE(str.c_str(), v[0].c_str());
53    EXPECT_STREQ(str.c_str(), v[0].c_str());
54}
55
56TEST(StringVector, AppendLotsOfStrings) {
57    StringVector v;
58    const size_t kMaxCount = 1000;
59    for (size_t n = 0; n < kMaxCount; ++n) {
60        v.append(genHashString(n));
61    }
62    EXPECT_EQ(kMaxCount, v.size());
63    for (size_t n = 0; n < kMaxCount; ++n) {
64        String expected = genHashString(n);
65        EXPECT_EQ(expected.size(), v[n].size());
66        EXPECT_STREQ(expected.c_str(), v[n].c_str())
67                << "At index " << n;
68    }
69}
70
71TEST(StringVector, Prepend) {
72    StringVector v;
73    v.prepend(String("hello"));
74    v.prepend(String("world"));
75    EXPECT_EQ(2U, v.size());
76    EXPECT_STREQ("world", v[0].c_str());
77    EXPECT_STREQ("hello", v[1].c_str());
78}
79
80TEST(StringVector, PrependLotsOfStrings) {
81    StringVector v;
82    const size_t kMaxCount = 1000;
83    for (size_t n = 0; n < kMaxCount; ++n) {
84        v.prepend(genHashString(n));
85    }
86    EXPECT_EQ(kMaxCount, v.size());
87    for (size_t n = 0; n < kMaxCount; ++n) {
88        String expected = genHashString(kMaxCount - n - 1U);
89        EXPECT_EQ(expected.size(), v[n].size());
90        EXPECT_STREQ(expected.c_str(), v[n].c_str())
91                << "At index " << n;
92    }
93}
94
95TEST(StringVector, Swap) {
96    static const char* const kList1[] = {
97        "Hello", "World!",
98    };
99    const size_t kList1Len = sizeof(kList1)/sizeof(kList1[0]);
100
101    static const char* const kList2[] = {
102        "Menthe", "a", "l'", "eau",
103    };
104    const size_t kList2Len = sizeof(kList2)/sizeof(kList1[0]);
105
106    StringVector v1;
107    for (size_t n = 0; n < kList1Len; ++n) {
108        v1.append(StringView(kList1[n]));
109    }
110
111    StringVector v2;
112    for (size_t n = 0; n < kList2Len; ++n) {
113        v2.append(StringView(kList2[n]));
114    }
115
116    v1.swap(&v2);
117
118    EXPECT_EQ(kList2Len, v1.size());
119    for (size_t n = 0; n < kList2Len; ++n) {
120        EXPECT_EQ(String(kList2[n]), v1[n]) << "At index " << n;
121    }
122
123    EXPECT_EQ(kList1Len, v2.size());
124    for (size_t n = 0; n < kList1Len; ++n) {
125        EXPECT_EQ(String(kList1[n]), v2[n]) << "At index " << n;
126    }
127}
128
129TEST(StringVector, AssignmentOperator) {
130    static const char* const kList[] = {
131        "Menthe", "a", "l'", "eau",
132    };
133    const size_t kListLen = sizeof(kList)/sizeof(kList[0]);
134
135    StringVector v1;
136    for (size_t n = 0; n < kListLen; ++n) {
137        v1.append(StringView(kList[n]));
138    }
139
140    StringVector v2;
141    v2 = v1;
142    v1.reserve(0);
143    EXPECT_TRUE(v1.empty());
144
145    for (size_t n = 0; n < kListLen; ++n) {
146        EXPECT_EQ(::strlen(kList[n]), v2[n].size()) << "At index " << n;
147        EXPECT_STREQ(kList[n], v2[n].c_str()) << "At index " << n;
148    }
149}
150
151}  // namespace base
152}  // namespace android
153