blob: e9beb0017a998dcb17321c20fa75a4fa2bfa9837 [file] [log] [blame]
deadbeef6038e972017-02-16 23:31:33 -08001/*
2 * Copyright 2017 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include <utility>
12
Steve Anton10542f22019-01-11 09:11:00 -080013#include "api/rtc_error.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "test/gtest.h"
deadbeef6038e972017-02-16 23:31:33 -080015
16namespace {
17
18const int kDefaultMoveOnlyIntValue = 0xbadf00d;
19
20// Class that has no copy constructor, ensuring that RTCErrorOr can
21struct MoveOnlyInt {
22 MoveOnlyInt() {}
23 explicit MoveOnlyInt(int value) : value(value) {}
24 MoveOnlyInt(const MoveOnlyInt& other) = delete;
deadbeefb5388d72017-02-24 01:17:43 -080025 MoveOnlyInt& operator=(const MoveOnlyInt& other) = delete;
26 MoveOnlyInt(MoveOnlyInt&& other) : value(other.value) {}
27 MoveOnlyInt& operator=(MoveOnlyInt&& other) {
28 value = other.value;
29 return *this;
30 }
deadbeef6038e972017-02-16 23:31:33 -080031
32 int value = kDefaultMoveOnlyIntValue;
33};
34
35// Same as above. Used to test conversion from RTCErrorOr<A> to RTCErrorOr<B>
36// when A can be converted to B.
37struct MoveOnlyInt2 {
38 MoveOnlyInt2() {}
39 explicit MoveOnlyInt2(int value) : value(value) {}
40 MoveOnlyInt2(const MoveOnlyInt2& other) = delete;
deadbeefb5388d72017-02-24 01:17:43 -080041 MoveOnlyInt2& operator=(const MoveOnlyInt2& other) = delete;
42 MoveOnlyInt2(MoveOnlyInt2&& other) : value(other.value) {}
43 MoveOnlyInt2& operator=(MoveOnlyInt2&& other) {
44 value = other.value;
45 return *this;
46 }
deadbeef6038e972017-02-16 23:31:33 -080047
48 explicit MoveOnlyInt2(MoveOnlyInt&& other) : value(other.value) {}
49 MoveOnlyInt2& operator=(MoveOnlyInt&& other) {
50 value = other.value;
51 return *this;
52 }
53
54 int value = kDefaultMoveOnlyIntValue;
55};
56
57} // namespace
58
59namespace webrtc {
60
deadbeef6038e972017-02-16 23:31:33 -080061// Test that the default constructor creates a "no error" error.
62TEST(RTCErrorTest, DefaultConstructor) {
63 RTCError e;
64 EXPECT_EQ(RTCErrorType::NONE, e.type());
65 EXPECT_EQ(std::string(), e.message());
66 EXPECT_TRUE(e.ok());
67}
68
69TEST(RTCErrorTest, NormalConstructors) {
70 RTCError a(RTCErrorType::INVALID_PARAMETER);
71 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, a.type());
72 EXPECT_EQ(std::string(), a.message());
73
74 // Constructor that takes const char* message.
75 RTCError b(RTCErrorType::UNSUPPORTED_PARAMETER, "foobar");
76 EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER, b.type());
77 EXPECT_EQ(std::string("foobar"), b.message());
78
79 // Constructor that takes std::string message.
80 RTCError c(RTCErrorType::INVALID_RANGE, std::string("new"));
81 EXPECT_EQ(RTCErrorType::INVALID_RANGE, c.type());
82 EXPECT_EQ(std::string("new"), c.message());
83}
84
85TEST(RTCErrorTest, MoveConstructor) {
86 // Static string.
87 RTCError a(RTCErrorType::INVALID_PARAMETER, "foo");
88 RTCError b(std::move(a));
89 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, b.type());
90 EXPECT_EQ(std::string("foo"), b.message());
91
92 // Non-static string.
93 RTCError c(RTCErrorType::UNSUPPORTED_PARAMETER, std::string("bar"));
94 RTCError d(std::move(c));
95 EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER, d.type());
96 EXPECT_EQ(std::string("bar"), d.message());
97}
98
99TEST(RTCErrorTest, MoveAssignment) {
100 // Try all combinations of "is static string"/"is non-static string" moves.
101 RTCError e(RTCErrorType::INVALID_PARAMETER, "foo");
102
103 e = RTCError(RTCErrorType::UNSUPPORTED_PARAMETER, "bar");
104 EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER, e.type());
105 EXPECT_EQ(std::string("bar"), e.message());
106
107 e = RTCError(RTCErrorType::SYNTAX_ERROR, std::string("baz"));
108 EXPECT_EQ(std::string("baz"), e.message());
109
110 e = RTCError(RTCErrorType::SYNTAX_ERROR, std::string("another"));
111 EXPECT_EQ(std::string("another"), e.message());
112
113 e = RTCError(RTCErrorType::SYNTAX_ERROR, "last");
114 EXPECT_EQ(std::string("last"), e.message());
115}
116
117// Test that the error returned by RTCError::OK() is a "no error" error.
118TEST(RTCErrorTest, OKConstant) {
119 RTCError ok = RTCError::OK();
120 EXPECT_EQ(RTCErrorType::NONE, ok.type());
121 EXPECT_EQ(std::string(), ok.message());
122 EXPECT_TRUE(ok.ok());
123}
124
125// Test that "error.ok()" behaves as expected.
126TEST(RTCErrorTest, OkMethod) {
127 RTCError success;
128 RTCError failure(RTCErrorType::INTERNAL_ERROR);
129 EXPECT_TRUE(success.ok());
130 EXPECT_FALSE(failure.ok());
131}
132
133// Test that a message can be set using either static const strings or
134// std::strings.
135TEST(RTCErrorTest, SetMessage) {
136 RTCError e;
137 // Try all combinations of "is static string"/"is non-static string" calls.
138 e.set_message("foo");
139 EXPECT_EQ(std::string("foo"), e.message());
140
141 e.set_message("bar");
142 EXPECT_EQ(std::string("bar"), e.message());
143
144 e.set_message(std::string("string"));
145 EXPECT_EQ(std::string("string"), e.message());
146
147 e.set_message(std::string("more"));
148 EXPECT_EQ(std::string("more"), e.message());
149
150 e.set_message("love to test");
151 EXPECT_EQ(std::string("love to test"), e.message());
152}
153
154// Test that the default constructor creates an "INTERNAL_ERROR".
155TEST(RTCErrorOrTest, DefaultConstructor) {
156 RTCErrorOr<MoveOnlyInt> e;
157 EXPECT_EQ(RTCErrorType::INTERNAL_ERROR, e.error().type());
158}
159
160// Test that an RTCErrorOr can be implicitly constructed from a value.
161TEST(RTCErrorOrTest, ImplicitValueConstructor) {
162 RTCErrorOr<MoveOnlyInt> e = [] { return MoveOnlyInt(100); }();
163 EXPECT_EQ(100, e.value().value);
164}
165
166// Test that an RTCErrorOr can be implicitly constructed from an RTCError.
167TEST(RTCErrorOrTest, ImplicitErrorConstructor) {
168 RTCErrorOr<MoveOnlyInt> e = [] {
169 return RTCError(RTCErrorType::SYNTAX_ERROR);
170 }();
171 EXPECT_EQ(RTCErrorType::SYNTAX_ERROR, e.error().type());
172}
173
174TEST(RTCErrorOrTest, MoveConstructor) {
175 RTCErrorOr<MoveOnlyInt> a(MoveOnlyInt(5));
176 RTCErrorOr<MoveOnlyInt> b(std::move(a));
177 EXPECT_EQ(5, b.value().value);
178}
179
180TEST(RTCErrorOrTest, MoveAssignment) {
181 RTCErrorOr<MoveOnlyInt> a(MoveOnlyInt(5));
182 RTCErrorOr<MoveOnlyInt> b(MoveOnlyInt(10));
183 a = std::move(b);
184 EXPECT_EQ(10, a.value().value);
185}
186
187TEST(RTCErrorOrTest, ConversionConstructor) {
188 RTCErrorOr<MoveOnlyInt> a(MoveOnlyInt(1));
189 RTCErrorOr<MoveOnlyInt2> b(std::move(a));
190}
191
192TEST(RTCErrorOrTest, ConversionAssignment) {
193 RTCErrorOr<MoveOnlyInt> a(MoveOnlyInt(5));
194 RTCErrorOr<MoveOnlyInt2> b(MoveOnlyInt2(10));
195 b = std::move(a);
196 EXPECT_EQ(5, b.value().value);
197}
198
199TEST(RTCErrorOrTest, OkMethod) {
200 RTCErrorOr<int> success(1337);
201 RTCErrorOr<int> error = RTCError(RTCErrorType::INTERNAL_ERROR);
202 EXPECT_TRUE(success.ok());
203 EXPECT_FALSE(error.ok());
204}
205
206TEST(RTCErrorOrTest, MoveError) {
207 RTCErrorOr<int> e({RTCErrorType::SYNTAX_ERROR, "message"});
208 RTCError err = e.MoveError();
209 EXPECT_EQ(RTCErrorType::SYNTAX_ERROR, err.type());
210 EXPECT_EQ(std::string("message"), err.message());
211}
212
213TEST(RTCErrorOrTest, MoveValue) {
214 RTCErrorOr<MoveOnlyInt> e(MoveOnlyInt(88));
215 MoveOnlyInt value = e.MoveValue();
216 EXPECT_EQ(88, value.value);
217}
218
219// Death tests.
220// Disabled on Android because death tests misbehave on Android, see
221// base/test/gtest_util.h.
222#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
223
224TEST(RTCErrorOrDeathTest, ConstructWithOkError) {
Jonas Olsson941a07c2018-09-13 10:07:07 +0200225 RTCErrorOr<int> err;
226 EXPECT_DEATH(err = RTCError::OK(), "");
deadbeef6038e972017-02-16 23:31:33 -0800227}
228
229TEST(RTCErrorOrDeathTest, DereferenceErrorValue) {
230 RTCErrorOr<int> error = RTCError(RTCErrorType::INTERNAL_ERROR);
231 EXPECT_DEATH(error.value(), "");
232}
233
234TEST(RTCErrorOrDeathTest, MoveErrorValue) {
235 RTCErrorOr<int> error = RTCError(RTCErrorType::INTERNAL_ERROR);
236 EXPECT_DEATH(error.MoveValue(), "");
237}
238
239#endif // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
240
241} // namespace webrtc