blob: d8f7ca6d49d8d7be61a8e0d6dd576f8ab7dae233 [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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "api/rtcerror.h"
14#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
61// Simple test for ostream operator for RTCErrorType.
62TEST(RTCErrorTypeTest, OstreamOperator) {
63 std::ostringstream oss;
64 oss << webrtc::RTCErrorType::NONE << ' '
65 << webrtc::RTCErrorType::INVALID_PARAMETER << ' '
66 << webrtc::RTCErrorType::INTERNAL_ERROR;
67 EXPECT_EQ("NONE INVALID_PARAMETER INTERNAL_ERROR", oss.str());
68}
69
70// Test that the default constructor creates a "no error" error.
71TEST(RTCErrorTest, DefaultConstructor) {
72 RTCError e;
73 EXPECT_EQ(RTCErrorType::NONE, e.type());
74 EXPECT_EQ(std::string(), e.message());
75 EXPECT_TRUE(e.ok());
76}
77
78TEST(RTCErrorTest, NormalConstructors) {
79 RTCError a(RTCErrorType::INVALID_PARAMETER);
80 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, a.type());
81 EXPECT_EQ(std::string(), a.message());
82
83 // Constructor that takes const char* message.
84 RTCError b(RTCErrorType::UNSUPPORTED_PARAMETER, "foobar");
85 EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER, b.type());
86 EXPECT_EQ(std::string("foobar"), b.message());
87
88 // Constructor that takes std::string message.
89 RTCError c(RTCErrorType::INVALID_RANGE, std::string("new"));
90 EXPECT_EQ(RTCErrorType::INVALID_RANGE, c.type());
91 EXPECT_EQ(std::string("new"), c.message());
92}
93
94TEST(RTCErrorTest, MoveConstructor) {
95 // Static string.
96 RTCError a(RTCErrorType::INVALID_PARAMETER, "foo");
97 RTCError b(std::move(a));
98 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, b.type());
99 EXPECT_EQ(std::string("foo"), b.message());
100
101 // Non-static string.
102 RTCError c(RTCErrorType::UNSUPPORTED_PARAMETER, std::string("bar"));
103 RTCError d(std::move(c));
104 EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER, d.type());
105 EXPECT_EQ(std::string("bar"), d.message());
106}
107
108TEST(RTCErrorTest, MoveAssignment) {
109 // Try all combinations of "is static string"/"is non-static string" moves.
110 RTCError e(RTCErrorType::INVALID_PARAMETER, "foo");
111
112 e = RTCError(RTCErrorType::UNSUPPORTED_PARAMETER, "bar");
113 EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER, e.type());
114 EXPECT_EQ(std::string("bar"), e.message());
115
116 e = RTCError(RTCErrorType::SYNTAX_ERROR, std::string("baz"));
117 EXPECT_EQ(std::string("baz"), e.message());
118
119 e = RTCError(RTCErrorType::SYNTAX_ERROR, std::string("another"));
120 EXPECT_EQ(std::string("another"), e.message());
121
122 e = RTCError(RTCErrorType::SYNTAX_ERROR, "last");
123 EXPECT_EQ(std::string("last"), e.message());
124}
125
126// Test that the error returned by RTCError::OK() is a "no error" error.
127TEST(RTCErrorTest, OKConstant) {
128 RTCError ok = RTCError::OK();
129 EXPECT_EQ(RTCErrorType::NONE, ok.type());
130 EXPECT_EQ(std::string(), ok.message());
131 EXPECT_TRUE(ok.ok());
132}
133
134// Test that "error.ok()" behaves as expected.
135TEST(RTCErrorTest, OkMethod) {
136 RTCError success;
137 RTCError failure(RTCErrorType::INTERNAL_ERROR);
138 EXPECT_TRUE(success.ok());
139 EXPECT_FALSE(failure.ok());
140}
141
142// Test that a message can be set using either static const strings or
143// std::strings.
144TEST(RTCErrorTest, SetMessage) {
145 RTCError e;
146 // Try all combinations of "is static string"/"is non-static string" calls.
147 e.set_message("foo");
148 EXPECT_EQ(std::string("foo"), e.message());
149
150 e.set_message("bar");
151 EXPECT_EQ(std::string("bar"), e.message());
152
153 e.set_message(std::string("string"));
154 EXPECT_EQ(std::string("string"), e.message());
155
156 e.set_message(std::string("more"));
157 EXPECT_EQ(std::string("more"), e.message());
158
159 e.set_message("love to test");
160 EXPECT_EQ(std::string("love to test"), e.message());
161}
162
163// Test that the default constructor creates an "INTERNAL_ERROR".
164TEST(RTCErrorOrTest, DefaultConstructor) {
165 RTCErrorOr<MoveOnlyInt> e;
166 EXPECT_EQ(RTCErrorType::INTERNAL_ERROR, e.error().type());
167}
168
169// Test that an RTCErrorOr can be implicitly constructed from a value.
170TEST(RTCErrorOrTest, ImplicitValueConstructor) {
171 RTCErrorOr<MoveOnlyInt> e = [] { return MoveOnlyInt(100); }();
172 EXPECT_EQ(100, e.value().value);
173}
174
175// Test that an RTCErrorOr can be implicitly constructed from an RTCError.
176TEST(RTCErrorOrTest, ImplicitErrorConstructor) {
177 RTCErrorOr<MoveOnlyInt> e = [] {
178 return RTCError(RTCErrorType::SYNTAX_ERROR);
179 }();
180 EXPECT_EQ(RTCErrorType::SYNTAX_ERROR, e.error().type());
181}
182
183TEST(RTCErrorOrTest, MoveConstructor) {
184 RTCErrorOr<MoveOnlyInt> a(MoveOnlyInt(5));
185 RTCErrorOr<MoveOnlyInt> b(std::move(a));
186 EXPECT_EQ(5, b.value().value);
187}
188
189TEST(RTCErrorOrTest, MoveAssignment) {
190 RTCErrorOr<MoveOnlyInt> a(MoveOnlyInt(5));
191 RTCErrorOr<MoveOnlyInt> b(MoveOnlyInt(10));
192 a = std::move(b);
193 EXPECT_EQ(10, a.value().value);
194}
195
196TEST(RTCErrorOrTest, ConversionConstructor) {
197 RTCErrorOr<MoveOnlyInt> a(MoveOnlyInt(1));
198 RTCErrorOr<MoveOnlyInt2> b(std::move(a));
199}
200
201TEST(RTCErrorOrTest, ConversionAssignment) {
202 RTCErrorOr<MoveOnlyInt> a(MoveOnlyInt(5));
203 RTCErrorOr<MoveOnlyInt2> b(MoveOnlyInt2(10));
204 b = std::move(a);
205 EXPECT_EQ(5, b.value().value);
206}
207
208TEST(RTCErrorOrTest, OkMethod) {
209 RTCErrorOr<int> success(1337);
210 RTCErrorOr<int> error = RTCError(RTCErrorType::INTERNAL_ERROR);
211 EXPECT_TRUE(success.ok());
212 EXPECT_FALSE(error.ok());
213}
214
215TEST(RTCErrorOrTest, MoveError) {
216 RTCErrorOr<int> e({RTCErrorType::SYNTAX_ERROR, "message"});
217 RTCError err = e.MoveError();
218 EXPECT_EQ(RTCErrorType::SYNTAX_ERROR, err.type());
219 EXPECT_EQ(std::string("message"), err.message());
220}
221
222TEST(RTCErrorOrTest, MoveValue) {
223 RTCErrorOr<MoveOnlyInt> e(MoveOnlyInt(88));
224 MoveOnlyInt value = e.MoveValue();
225 EXPECT_EQ(88, value.value);
226}
227
228// Death tests.
229// Disabled on Android because death tests misbehave on Android, see
230// base/test/gtest_util.h.
231#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
232
233TEST(RTCErrorOrDeathTest, ConstructWithOkError) {
234 EXPECT_DEATH(RTCErrorOr<int> err = RTCError::OK(), "");
235}
236
237TEST(RTCErrorOrDeathTest, DereferenceErrorValue) {
238 RTCErrorOr<int> error = RTCError(RTCErrorType::INTERNAL_ERROR);
239 EXPECT_DEATH(error.value(), "");
240}
241
242TEST(RTCErrorOrDeathTest, MoveErrorValue) {
243 RTCErrorOr<int> error = RTCError(RTCErrorType::INTERNAL_ERROR);
244 EXPECT_DEATH(error.MoveValue(), "");
245}
246
247#endif // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
248
249} // namespace webrtc