• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 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 #pragma once
15 
16 #include "lib/stdcompat/type_traits.h"
17 #include "pw_status/status.h"
18 
19 /// Verifies that `expr` is OkStatus()
20 ///
21 /// Converts `expr` to a Status value and checks that it is `OkStatus()`.
22 ///
23 /// @param[in] expr The expression to check.
24 #define PW_TEST_EXPECT_OK(expr)                     \
25   if (cpp20::is_constant_evaluated()) {             \
26     ::pw::unit_test::internal::Constexpr_EXPECT_OK( \
27         ::pw::internal::ConvertToStatus(expr));     \
28   } else                                            \
29     EXPECT_EQ(::pw::internal::ConvertToStatus(expr), ::pw::OkStatus())
30 
31 /// See `PW_TEST_EXPECT_OK`.
32 #define PW_TEST_ASSERT_OK(expr)                          \
33   if (cpp20::is_constant_evaluated()) {                  \
34     if (!::pw::unit_test::internal::Constexpr_EXPECT_OK( \
35             ::pw::internal::ConvertToStatus(expr))) {    \
36       return;                                            \
37     }                                                    \
38   } else                                                 \
39     ASSERT_EQ(::pw::internal::ConvertToStatus(expr), ::pw::OkStatus())
40 
41 /// Executes an expression that returns a `pw::Result` or `pw::StatusWithSize`
42 /// and assigns or moves that value to lhs if the error code is OK. If the
43 /// status is non-OK, generates a test failure and returns from the current
44 /// function, which must have a void return type.
45 ///
46 /// Example: Declaring and initializing a new value. E.g.:
47 ///   PW_TEST_ASSERT_OK_AND_ASSIGN(auto value, MaybeGetValue(arg));
48 ///   PW_TEST_ASSERT_OK_AND_ASSIGN(const ValueType value, MaybeGetValue(arg));
49 ///
50 /// Example: Assigning to an existing value
51 ///   ValueType value;
52 ///   PW_TEST_ASSERT_OK_AND_ASSIGN(value, MaybeGetValue(arg));
53 ///
54 /// The value assignment example would expand into something like:
55 ///   auto status_or_value = MaybeGetValue(arg);
56 ///   PW_TEST_ASSERT_OK(status_or_value.status());
57 ///   value = status_or_value.ValueOrDie();
58 ///
59 /// WARNING: PW_TEST_ASSERT_OK_AND_ASSIGN expand into multiple statements; it
60 /// cannot be used in a single statement (e.g. as the body of an if statement
61 /// without {})!
62 ///
63 /// @param [in] lhs Variable to assign unwrapped value to
64 /// @param [in] rexpr Expression to unwrap. Must be a `Result` or
65 /// `StatusWithSize`.
66 #define PW_TEST_ASSERT_OK_AND_ASSIGN(lhs, rexpr) \
67   _PW_TEST_ASSERT_OK_AND_ASSIGN_DETAIL(          \
68       _PW_UNIQUE_IDENTIFIER_DETAIL(__LINE__), lhs, rexpr)
69 
70 #define _PW_TEST_ASSERT_OK_AND_ASSIGN_DETAIL(result, lhs, rexpr) \
71   auto result = (rexpr);                                         \
72   PW_TEST_ASSERT_OK(result);                                     \
73   lhs = ::pw::internal::ConvertToValue(result)
74 
75 #define _PW_UNIQUE_IDENTIFIER_DETAIL(line) \
76   _PW_UNIQUE_IDENTIFIER_EXPANDED_DETAIL(line)
77 #define _PW_UNIQUE_IDENTIFIER_EXPANDED_DETAIL(line) \
78   _assert_pw_test_assert_ok_and_assign_unique_name_##line
79 
80 namespace pw::unit_test::internal {
81 
82 // Functions for PW_CONSTEXPR_TEST compatibility. See pw_unit_test/constexpr.h.
83 bool EXPECT_OK_FAILED();
84 
Constexpr_EXPECT_OK(Status status)85 constexpr bool Constexpr_EXPECT_OK(Status status) {
86   return status.ok() ? true : EXPECT_OK_FAILED();
87 }
88 
89 }  // namespace pw::unit_test::internal
90