1 // Copyright 2020 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_status/try.h"
16
17 #include "gtest/gtest.h"
18
19 namespace pw {
20 namespace {
21
ReturnStatus(Status status)22 Status ReturnStatus(Status status) { return status; }
ReturnStatusWithSize(StatusWithSize status)23 StatusWithSize ReturnStatusWithSize(StatusWithSize status) { return status; }
24
TryStatus(Status status)25 Status TryStatus(Status status) {
26 PW_TRY(ReturnStatus(status));
27
28 // Any status other than OK should have already returned.
29 EXPECT_EQ(status, OkStatus());
30 return status;
31 }
32
TryStatus(StatusWithSize status)33 Status TryStatus(StatusWithSize status) {
34 PW_TRY(ReturnStatusWithSize(status));
35
36 // Any status other than OK should have already returned.
37 EXPECT_EQ(status.status(), OkStatus());
38 return status.status();
39 }
40
TEST(Status,Try_Status)41 TEST(Status, Try_Status) {
42 EXPECT_EQ(TryStatus(OkStatus()), OkStatus());
43
44 // Don't need all the status types, just pick a few not-ok ones.
45 EXPECT_EQ(TryStatus(Status::Cancelled()), Status::Cancelled());
46 EXPECT_EQ(TryStatus(Status::DataLoss()), Status::DataLoss());
47 EXPECT_EQ(TryStatus(Status::Unimplemented()), Status::Unimplemented());
48 }
49
TEST(Status,Try_StatusWithSizeOk)50 TEST(Status, Try_StatusWithSizeOk) {
51 for (size_t i = 0; i < 32; ++i) {
52 StatusWithSize val(OkStatus(), 0);
53 EXPECT_EQ(TryStatus(val), OkStatus());
54 }
55 }
56
TEST(Status,Try_StatusWithSizeError)57 TEST(Status, Try_StatusWithSizeError) {
58 for (size_t i = 0; i < 32; ++i) {
59 StatusWithSize val(Status::DataLoss(), i);
60 EXPECT_EQ(TryStatus(val), Status::DataLoss());
61 }
62 }
63
TEST(Status,Try_StatusWithSizeFromConstant)64 TEST(Status, Try_StatusWithSizeFromConstant) {
65 // Don't need all the status types, just pick a few not-ok ones.
66 EXPECT_EQ(TryStatus(StatusWithSize::Cancelled()), Status::Cancelled());
67 EXPECT_EQ(TryStatus(StatusWithSize::DataLoss()), Status::DataLoss());
68 EXPECT_EQ(TryStatus(StatusWithSize::Unimplemented()),
69 Status::Unimplemented());
70 }
71
TryStatusAssign(size_t & size_val,StatusWithSize status)72 Status TryStatusAssign(size_t& size_val, StatusWithSize status) {
73 PW_TRY_ASSIGN(size_val, ReturnStatusWithSize(status));
74
75 // Any status other than OK should have already returned.
76 EXPECT_EQ(status.status(), OkStatus());
77 EXPECT_EQ(size_val, status.size());
78 return status.status();
79 }
80
TEST(Status,TryAssignOk)81 TEST(Status, TryAssignOk) {
82 size_t size_val = 0;
83
84 for (size_t i = 1; i < 32; ++i) {
85 StatusWithSize val(OkStatus(), i);
86 EXPECT_EQ(TryStatusAssign(size_val, val), OkStatus());
87 EXPECT_EQ(size_val, i);
88 }
89 }
90
TEST(Status,TryAssignError)91 TEST(Status, TryAssignError) {
92 size_t size_val = 0u;
93
94 for (size_t i = 1; i < 32; ++i) {
95 StatusWithSize val(Status::OutOfRange(), i);
96 EXPECT_EQ(TryStatusAssign(size_val, val), Status::OutOfRange());
97 EXPECT_EQ(size_val, 0u);
98 }
99 }
100
TryStatusWithSize(StatusWithSize status)101 StatusWithSize TryStatusWithSize(StatusWithSize status) {
102 PW_TRY_WITH_SIZE(ReturnStatusWithSize(status));
103
104 // Any status other than OK should have already returned.
105 EXPECT_TRUE(status.ok());
106 return status;
107 }
108
TryStatusWithSize(Status status)109 StatusWithSize TryStatusWithSize(Status status) {
110 PW_TRY_WITH_SIZE(ReturnStatus(status));
111
112 // Any status other than OK should have already returned.
113 EXPECT_EQ(status, OkStatus());
114
115 StatusWithSize return_val(status, 0u);
116 return return_val;
117 }
118
TEST(Status,TryWithSize_StatusOk)119 TEST(Status, TryWithSize_StatusOk) {
120 StatusWithSize result = TryStatusWithSize(OkStatus());
121 EXPECT_EQ(result.status(), OkStatus());
122 EXPECT_EQ(result.size(), 0u);
123 }
124
TEST(Status,TryWithSize_StatusError)125 TEST(Status, TryWithSize_StatusError) {
126 StatusWithSize result = TryStatusWithSize(Status::PermissionDenied());
127 EXPECT_EQ(result.status(), Status::PermissionDenied());
128 EXPECT_EQ(result.size(), 0u);
129 }
130
TEST(Status,TryWithSize_StatusWithSizeOk)131 TEST(Status, TryWithSize_StatusWithSizeOk) {
132 for (size_t i = 0; i < 32; ++i) {
133 StatusWithSize val(OkStatus(), i);
134 EXPECT_EQ(TryStatusWithSize(val).status(), OkStatus());
135 EXPECT_EQ(TryStatusWithSize(val).size(), i);
136 }
137 }
138
TEST(Status,TryWithSize_StatusWithSizeError)139 TEST(Status, TryWithSize_StatusWithSizeError) {
140 for (size_t i = 0; i < 32; ++i) {
141 StatusWithSize val(Status::DataLoss(), i);
142 StatusWithSize result = TryStatusWithSize(val);
143 EXPECT_EQ(result.status(), Status::DataLoss());
144 EXPECT_EQ(result.size(), i);
145 }
146 }
147
TEST(Status,TryWithSize_StatusWithSizeConst)148 TEST(Status, TryWithSize_StatusWithSizeConst) {
149 StatusWithSize result = TryStatusWithSize(StatusWithSize::DataLoss());
150 EXPECT_EQ(result.status(), Status::DataLoss());
151 EXPECT_EQ(result.size(), 0u);
152
153 result = TryStatusWithSize(StatusWithSize::NotFound());
154 EXPECT_EQ(result.status(), Status::NotFound());
155 EXPECT_EQ(result.size(), 0u);
156
157 result = TryStatusWithSize(StatusWithSize::Unimplemented());
158 EXPECT_EQ(result.status(), Status::Unimplemented());
159 EXPECT_EQ(result.size(), 0u);
160 }
161
162 } // namespace
163 } // namespace pw
164