1 // Copyright (c) 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "gn/string_atom.h"
6
7 #include "util/test/test.h"
8
9 #include <set>
10 #include <string>
11 #include <vector>
12
TEST(StringAtomTest,EmptyString)13 TEST(StringAtomTest, EmptyString) {
14 StringAtom key1;
15 StringAtom key2("");
16
17 ASSERT_STREQ(key1.str().c_str(), "");
18 ASSERT_STREQ(key2.str().c_str(), "");
19 ASSERT_EQ(&key1.str(), &key2.str());
20 }
21
TEST(StringAtomTest,Find)22 TEST(StringAtomTest, Find) {
23 StringAtom empty;
24 EXPECT_EQ(empty.str(), std::string());
25
26 StringAtom foo("foo");
27 EXPECT_EQ(foo.str(), std::string("foo"));
28
29 StringAtom foo2("foo");
30 EXPECT_EQ(&foo.str(), &foo2.str());
31 }
32
33 // Default compare should always be ordered.
TEST(StringAtomTest,DefaultCompare)34 TEST(StringAtomTest, DefaultCompare) {
35 auto foo = StringAtom("foo");
36 auto bar = StringAtom("bar");
37 auto zoo = StringAtom("zoo");
38
39 EXPECT_TRUE(bar < foo);
40 EXPECT_TRUE(foo < zoo);
41 EXPECT_TRUE(bar < zoo);
42 }
43
TEST(StringAtomTest,NormalSet)44 TEST(StringAtomTest, NormalSet) {
45 std::set<StringAtom> set;
46 auto foo_ret = set.insert(std::string_view("foo"));
47 auto bar_ret = set.insert(std::string_view("bar"));
48 auto zoo_ret = set.insert(std::string_view("zoo"));
49
50 StringAtom foo_key("foo");
51 EXPECT_EQ(*foo_ret.first, foo_key);
52
53 auto foo_it = set.find(foo_key);
54 EXPECT_NE(foo_it, set.end());
55 EXPECT_EQ(*foo_it, foo_key);
56
57 EXPECT_EQ(set.find(std::string_view("bar")), bar_ret.first);
58 EXPECT_EQ(set.find(std::string_view("zoo")), zoo_ret.first);
59
60 // Normal sets are always ordered according to the key value.
61 auto it = set.begin();
62 EXPECT_EQ(it, bar_ret.first);
63 ++it;
64
65 EXPECT_EQ(it, foo_ret.first);
66 ++it;
67
68 EXPECT_EQ(it, zoo_ret.first);
69 ++it;
70
71 EXPECT_EQ(it, set.end());
72 }
73
TEST(StringAtomTest,FastSet)74 TEST(StringAtomTest, FastSet) {
75 std::set<StringAtom, StringAtom::PtrCompare> set;
76
77 auto foo_ret = set.insert(std::string_view("foo"));
78 auto bar_ret = set.insert(std::string_view("bar"));
79 auto zoo_ret = set.insert(std::string_view("zoo"));
80
81 StringAtom foo_key("foo");
82 EXPECT_EQ(*foo_ret.first, foo_key);
83
84 auto foo_it = set.find(foo_key);
85 EXPECT_NE(foo_it, set.end());
86 EXPECT_EQ(*foo_it, foo_key);
87
88 EXPECT_EQ(set.find(std::string_view("bar")), bar_ret.first);
89 EXPECT_EQ(set.find(std::string_view("zoo")), zoo_ret.first);
90
91 // Fast sets are ordered according to the key pointer.
92 // Because of the underlying bump allocator, addresses
93 // for the first three inserts are in increasing order.
94 auto it = set.begin();
95 EXPECT_EQ(it, foo_ret.first);
96 ++it;
97
98 EXPECT_EQ(it, bar_ret.first);
99 ++it;
100
101 EXPECT_EQ(it, zoo_ret.first);
102 ++it;
103
104 EXPECT_EQ(it, set.end());
105 }
106
TEST(StringAtom,AllocMoreThanASingleSlabOfKeys)107 TEST(StringAtom, AllocMoreThanASingleSlabOfKeys) {
108 // Verify that allocating more than 128 string keys works properly.
109 const size_t kMaxCount = 16384;
110 std::vector<StringAtom> keys;
111
112 // Small lambda to create a string for the n-th key.
113 auto string_for = [](size_t index) -> std::string {
114 return std::to_string(index) + "_key";
115 };
116
117 for (size_t nn = 0; nn < kMaxCount; ++nn) {
118 keys.push_back(StringAtom(string_for(nn)));
119 }
120
121 for (size_t nn = 0; nn < kMaxCount; ++nn) {
122 ASSERT_EQ(keys[nn].str(), string_for(nn));
123 }
124 }
125