1 // Copyright 2021 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 #include "pw_string/util.h"
16
17 #include "gtest/gtest.h"
18
19 namespace pw::string {
20 namespace {
21
22 using namespace std::literals::string_view_literals;
23
TEST(ClampedLength,Nullptr_Returns0)24 TEST(ClampedLength, Nullptr_Returns0) {
25 EXPECT_EQ(0u, internal::ClampedLength(nullptr, 100));
26 }
27
TEST(ClampedLength,EmptyString_Returns0)28 TEST(ClampedLength, EmptyString_Returns0) {
29 EXPECT_EQ(0u, internal::ClampedLength("", 0));
30 EXPECT_EQ(0u, internal::ClampedLength("", 100));
31 }
32
TEST(ClampedLength,MaxLongerThanString_ReturnsStrlen)33 TEST(ClampedLength, MaxLongerThanString_ReturnsStrlen) {
34 EXPECT_EQ(5u, internal::ClampedLength("12345", 100));
35 }
36
TEST(ClampedLength,StringMaxLongerThanMax_ReturnsMax)37 TEST(ClampedLength, StringMaxLongerThanMax_ReturnsMax) {
38 EXPECT_EQ(0u, internal::ClampedLength("12345", 0));
39 EXPECT_EQ(4u, internal::ClampedLength("12345", 4));
40 }
41
TEST(ClampedLength,LengthEqualsMax)42 TEST(ClampedLength, LengthEqualsMax) {
43 EXPECT_EQ(5u, internal::ClampedLength("12345", 5));
44 }
45
TEST(ClampedCString,NullPtr_ReturnsEmpty)46 TEST(ClampedCString, NullPtr_ReturnsEmpty) {
47 EXPECT_TRUE(ClampedCString(nullptr, 100).empty());
48 }
49
TEST(ClampedCString,EmptyString_Returns0)50 TEST(ClampedCString, EmptyString_Returns0) {
51 EXPECT_TRUE(ClampedCString("", 0).empty());
52 EXPECT_TRUE(ClampedCString("", 100).empty());
53 }
54
TEST(ClampedCString,MaxLongerThanString_ReturnsStr)55 TEST(ClampedCString, MaxLongerThanString_ReturnsStr) {
56 static constexpr char kInput[] = "12345";
57 const std::string_view result = ClampedCString(kInput, 100);
58 EXPECT_EQ(result.size(), strlen(kInput));
59 EXPECT_EQ(result.data(), &kInput[0]);
60 }
61
TEST(ClampedCString,StringMaxLongerThanMax_ClampsView)62 TEST(ClampedCString, StringMaxLongerThanMax_ClampsView) {
63 static constexpr char kInput[] = "12345";
64
65 EXPECT_TRUE(ClampedCString(kInput, 0).empty());
66
67 const std::string_view result = ClampedCString(kInput, 4);
68 EXPECT_EQ(result.size(), 4u);
69 EXPECT_EQ(result.data(), &kInput[0]);
70 }
71
TEST(ClampedCString,FullStringView)72 TEST(ClampedCString, FullStringView) {
73 static constexpr char kInput[] = "12345";
74 const std::string_view result = ClampedCString(kInput);
75 EXPECT_EQ(result.size(), strlen(kInput));
76 EXPECT_EQ(result.data(), &kInput[0]);
77 }
78
TEST(NullTerminatedLength,EmptyString_RequiresNullTerminator)79 TEST(NullTerminatedLength, EmptyString_RequiresNullTerminator) {
80 EXPECT_TRUE(NullTerminatedLength("", 0).status().IsOutOfRange());
81
82 ASSERT_TRUE(NullTerminatedLength("", 100).status().ok());
83 EXPECT_EQ(0u, NullTerminatedLength("", 100).value());
84 }
85
TEST(NullTerminatedLength,MaxLongerThanString_ReturnsStrlen)86 TEST(NullTerminatedLength, MaxLongerThanString_ReturnsStrlen) {
87 ASSERT_TRUE(NullTerminatedLength("12345", 100).status().ok());
88 EXPECT_EQ(5u, NullTerminatedLength("12345", 100).value());
89 }
90
TEST(NullTerminatedLength,StringMaxLongerThanMax_Fails)91 TEST(NullTerminatedLength, StringMaxLongerThanMax_Fails) {
92 EXPECT_TRUE(NullTerminatedLength("12345", 0).status().IsOutOfRange());
93 EXPECT_TRUE(NullTerminatedLength("12345", 4).status().IsOutOfRange());
94 }
95
TEST(NullTerminatedLength,LengthEqualsMax)96 TEST(NullTerminatedLength, LengthEqualsMax) {
97 static constexpr char kInput[] = "12345";
98 ASSERT_TRUE(NullTerminatedLength(kInput).ok());
99 EXPECT_EQ(5u, NullTerminatedLength(kInput).value());
100 }
101
102 class TestWithBuffer : public ::testing::Test {
103 protected:
104 static constexpr char kStartingString[] = "!@#$%^&*()!@#$%^&*()";
105
TestWithBuffer()106 TestWithBuffer() { std::memcpy(buffer_, kStartingString, sizeof(buffer_)); }
107
108 char buffer_[sizeof(kStartingString)];
109 };
110
111 class CopyTest : public TestWithBuffer {};
112
TEST_F(CopyTest,EmptyStringView_WritesNullTerminator)113 TEST_F(CopyTest, EmptyStringView_WritesNullTerminator) {
114 EXPECT_EQ(0u, Copy("", buffer_).size());
115 EXPECT_EQ('\0', buffer_[0]);
116 }
117
TEST_F(CopyTest,EmptyBuffer_WritesNothing)118 TEST_F(CopyTest, EmptyBuffer_WritesNothing) {
119 auto result = Copy("Hello", std::span(buffer_, 0));
120 EXPECT_EQ(0u, result.size());
121 EXPECT_FALSE(result.ok());
122 EXPECT_STREQ(kStartingString, buffer_);
123 }
124
TEST_F(CopyTest,TooSmall_Truncates)125 TEST_F(CopyTest, TooSmall_Truncates) {
126 auto result = Copy("Hi!", std::span(buffer_, 3));
127 EXPECT_EQ(2u, result.size());
128 EXPECT_FALSE(result.ok());
129 EXPECT_STREQ("Hi", buffer_);
130 }
131
TEST_F(CopyTest,ExactFit)132 TEST_F(CopyTest, ExactFit) {
133 auto result = Copy("Hi!", std::span(buffer_, 4));
134 EXPECT_EQ(3u, result.size());
135 EXPECT_TRUE(result.ok());
136 EXPECT_STREQ("Hi!", buffer_);
137 }
138
TEST_F(CopyTest,NullTerminatorsInString)139 TEST_F(CopyTest, NullTerminatorsInString) {
140 ASSERT_EQ(4u, Copy("\0!\0\0"sv, std::span(buffer_, 5)).size());
141 EXPECT_EQ("\0!\0\0"sv, std::string_view(buffer_, 4));
142 }
143
144 } // namespace
145 } // namespace pw::string
146