blob: 1c44c4eaa601ce3e384297294dc88a5a36f3895d [file] [log] [blame]
Wyatt Heplere2dc6d12019-11-15 09:05:07 -08001// Copyright 2019 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
Wyatt Hepler1a960942019-11-26 14:13:38 -08004// use this file except in compliance with the License. You may obtain a copy of
5// the License at
Wyatt Heplere2dc6d12019-11-15 09:05:07 -08006//
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
Wyatt Hepler1a960942019-11-26 14:13:38 -080012// License for the specific language governing permissions and limitations under
13// the License.
Wyatt Heplere2dc6d12019-11-15 09:05:07 -080014
15#include "pw_string/format.h"
16
17#include <cstdarg>
18
19#include "gtest/gtest.h"
20#include "pw_span/span.h"
21
22namespace pw::string {
23namespace {
24
25TEST(Format, ValidFormatString_Succeeds) {
26 char buffer[32];
27 auto result = Format(buffer, "-_-");
28
29 EXPECT_EQ(Status::OK, result.status());
30 EXPECT_EQ(3u, result.size());
31 EXPECT_STREQ("-_-", buffer);
32}
33
34TEST(Format, ValidFormatStringAndArguments_Succeeds) {
35 char buffer[32];
36 auto result = Format(buffer, "%d4%s", 123, "5");
37
38 EXPECT_EQ(Status::OK, result.status());
39 EXPECT_EQ(5u, result.size());
40 EXPECT_STREQ("12345", buffer);
41}
42
43TEST(Format, InvalidConversionSpecifier_ReturnsInvalidArgumentAndTerminates) {
44 char buffer[32] = {'?', '?', '?', '?', '\0'};
45
46 // Make the format string volatile to prevent the compiler from potentially
47 // checking this as a format string.
48 const char* volatile fmt = "abc %9999999999999999999999999999999999d4%s";
Wyatt Hepler956ea9d2019-12-03 11:11:13 -080049
50 if (std::snprintf(buffer, sizeof(buffer), fmt, 123, "5") >= 0) {
51 // This snprintf implementation does not detect invalid format strings.
52 return;
53 }
54
Wyatt Heplere2dc6d12019-11-15 09:05:07 -080055 auto result = Format(buffer, fmt, 123, "5");
56
57 EXPECT_EQ(Status::INVALID_ARGUMENT, result.status());
58 EXPECT_STREQ("", buffer);
59}
60
61TEST(Format, EmptyBuffer_ReturnsResourceExhausted) {
62 auto result = Format(span<char>(), "?");
63
64 EXPECT_EQ(Status::RESOURCE_EXHAUSTED, result.status());
65 EXPECT_EQ(0u, result.size());
66}
67
68TEST(Format, FormatLargerThanBuffer_ReturnsResourceExhausted) {
69 char buffer[5];
70 auto result = Format(buffer, "2big!");
71
72 EXPECT_EQ(Status::RESOURCE_EXHAUSTED, result.status());
73 EXPECT_EQ(4u, result.size());
74 EXPECT_STREQ("2big", buffer);
75}
76
77TEST(Format, ArgumentLargerThanBuffer_ReturnsResourceExhausted) {
78 char buffer[5];
Wyatt Hepler2596fe52020-01-23 17:40:10 -080079 auto result = Format(buffer, "%s", "2big!");
Wyatt Heplere2dc6d12019-11-15 09:05:07 -080080
81 EXPECT_EQ(Status::RESOURCE_EXHAUSTED, result.status());
82 EXPECT_EQ(4u, result.size());
83 EXPECT_STREQ("2big", buffer);
84}
85
86StatusWithSize CallFormatWithVaList(span<char> buffer, const char* fmt, ...) {
87 va_list args;
88 va_start(args, fmt);
89
Wyatt Hepler2596fe52020-01-23 17:40:10 -080090 StatusWithSize result = FormatVaList(buffer, fmt, args);
Wyatt Heplere2dc6d12019-11-15 09:05:07 -080091
92 va_end(args);
93 return result;
94}
95
96TEST(Format, CallFormatWithVaList_CallsCorrectFormatOverload) {
97 char buffer[8];
98 auto result = CallFormatWithVaList(buffer, "Yo%s", "?!");
99
100 EXPECT_EQ(Status::OK, result.status());
101 EXPECT_EQ(4u, result.size());
102 EXPECT_STREQ("Yo?!", buffer);
103}
104
105} // namespace
106} // namespace pw::string