forked from facebook/hermes
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathStringViewTest.cpp
More file actions
152 lines (125 loc) · 4.94 KB
/
StringViewTest.cpp
File metadata and controls
152 lines (125 loc) · 4.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "hermes/VM/StringView.h"
#include "hermes/VM/Runtime.h"
#include "TestHelpers.h"
#include "gtest/gtest.h"
using namespace hermes::vm;
namespace {
using StringViewTest = RuntimeTestFixture;
TEST_F(StringViewTest, Construction) {
// Test createStringView
UTF16Ref str1 = createUTF16Ref(u"abcdef\x100");
auto strPrim1 = StringPrimitive::createNoThrow(runtime, str1);
StringView view1 = StringPrimitive::createStringView(runtime, strPrim1);
EXPECT_TRUE(!view1.isASCII());
EXPECT_EQ(view1.length(), 7u);
// Test getUTF16Ref and copyUTF16String.
SmallU16String<8> storage;
UTF16Ref ref1 = view1.getUTF16Ref(storage);
// Does not need to use storage.
EXPECT_TRUE(storage.empty());
EXPECT_EQ(ref1.data(), view1.castToChar16Ptr());
// After copy, storage should now contain data.
view1.appendUTF16String(storage);
EXPECT_EQ(storage.size(), 7u);
}
TEST_F(StringViewTest, Comparison) {
auto strPrim1 =
StringPrimitive::createNoThrow(runtime, createUTF16Ref(u"abcde"));
auto view1 = StringPrimitive::createStringView(runtime, strPrim1);
auto strPrim2 =
StringPrimitive::createNoThrow(runtime, createUTF16Ref(u"abcdefg"));
auto view2 = StringPrimitive::createStringView(runtime, strPrim2);
EXPECT_FALSE(view1.equals(view2));
EXPECT_FALSE(view2.equals(view1));
auto strPrim3 =
StringPrimitive::createNoThrow(runtime, createUTF16Ref(u"abc"));
auto view3 = StringPrimitive::createStringView(runtime, strPrim3);
EXPECT_FALSE(view1.equals(view3));
EXPECT_FALSE(view3.equals(view1));
auto strPrim4 =
StringPrimitive::createNoThrow(runtime, createUTF16Ref(u"defgh"));
auto view4 = StringPrimitive::createStringView(runtime, strPrim4);
EXPECT_FALSE(view1.equals(view4));
EXPECT_FALSE(view4.equals(view1));
llvh::StringRef str = "abcde";
auto strPrim5 = StringPrimitive::createNoThrow(runtime, str);
auto view5 = StringPrimitive::createStringView(runtime, strPrim5);
EXPECT_TRUE(view1.equals(view5));
EXPECT_TRUE(view1.equals(view5));
// Test copy ctor and operator=.
StringView tmp = view1;
EXPECT_TRUE(tmp.equals(view1));
tmp = view2;
EXPECT_FALSE(tmp.equals(view1));
tmp = view1;
EXPECT_TRUE(tmp.equals(view1));
}
TEST_F(StringViewTest, HandleHandling) {
// StringView conditionally holds onto a handle.
// This verifies that we correctly perform handle book-keeping in ctors and
// operator=. It has no assertions; it relies on GCScope to check its handle
// count in its dtor.
GCScope scope1{runtime, "StringViewTest.HandleHandling1"};
auto strPrim1 = StringPrimitive::createNoThrow(
runtime, createUTF16Ref(u"I have a handle"));
StringView scope1View1 = StringPrimitive::createStringView(runtime, strPrim1);
StringView scope1View2 = StringPrimitive::createStringView(runtime, strPrim1);
StringView scope1View3 = StringPrimitive::createStringView(runtime, strPrim1);
(void)scope1View3;
GCScope scope2{runtime, "StringViewTest.HandleHandling2"};
auto strPrim2 = StringPrimitive::createNoThrow(
runtime, createUTF16Ref(u"I also have a handle"));
StringView scope2View1 = StringPrimitive::createStringView(runtime, strPrim2);
// This assignment requires us to change the GCScope associated with the
// handle in scope1.
StringView tmp1 = scope2View1;
tmp1 = scope1View1;
// This ctor ensures we bump the handle count in scope1 and decrement it
// scope2.
StringView tmp2 = scope1View1;
(void)tmp2;
// Same but with moves ctor and operator=.
StringView tmp3 = std::move(scope1View2);
(void)tmp3;
StringView tmp4 = scope2View1;
tmp4 = std::move(scope1View2);
}
TEST_F(StringViewTest, Iteration) {
auto str1 = createUTF16Ref(u"abcdefghijklmnopqrstuvwxyz");
auto strPrim1 = StringPrimitive::createNoThrow(runtime, str1);
auto view1 = StringPrimitive::createStringView(runtime, strPrim1);
uint32_t index = 0;
for (const char16_t c : view1) {
EXPECT_EQ(c, str1[index++]);
}
}
TEST_F(StringViewTest, Slice) {
auto str = createUTF16Ref(u"abcdefgh");
auto strPrim1 = StringPrimitive::createNoThrow(runtime, str);
auto view = StringPrimitive::createStringView(runtime, strPrim1);
auto itr = view.begin();
for (uint32_t i = 0; i < 8; ++i, ++itr) {
EXPECT_TRUE(view.slice(i).equals(str.slice(i)));
EXPECT_TRUE(view.slice(i, 8 - i).equals(str.slice(i, 8 - i)));
EXPECT_TRUE(view.slice(itr, view.end()).equals(str.slice(i)));
}
}
TEST_F(StringViewTest, Output) {
auto str = createUTF16Ref(u"abcd");
llvh::SmallVector<char, 32> result{};
llvh::raw_svector_ostream os{result};
auto strPrim = StringPrimitive::createNoThrow(runtime, str);
auto view = StringPrimitive::createStringView(runtime, strPrim);
os << view;
EXPECT_EQ('a', result[0]);
EXPECT_EQ('b', result[1]);
EXPECT_EQ('c', result[2]);
EXPECT_EQ('d', result[3]);
}
} // namespace