1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2023 Google LLC. All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7
8 //! Tests covering accessors for singular bool, int32, int64, and bytes fields
9 //! on proto3.
10
11 use googletest::prelude::*;
12 use protobuf::prelude::*;
13
14 use protobuf::Optional;
15 use unittest_proto3_optional_rust_proto::{test_proto3_optional, TestProto3Optional};
16 use unittest_proto3_rust_proto::{test_all_types, TestAllTypes};
17
18 #[gtest]
test_fixed32_accessors()19 fn test_fixed32_accessors() {
20 let mut msg = TestAllTypes::new();
21 assert_that!(msg.optional_fixed32(), eq(0));
22
23 msg.set_optional_fixed32(42);
24 assert_that!(msg.optional_fixed32(), eq(42));
25
26 msg.set_optional_fixed32(u32::default());
27 assert_that!(msg.optional_fixed32(), eq(0));
28
29 msg.set_optional_fixed32(43);
30 assert_that!(msg.optional_fixed32(), eq(43));
31 }
32
33 #[gtest]
test_bool_accessors()34 fn test_bool_accessors() {
35 let mut msg = TestAllTypes::new();
36 assert_that!(msg.optional_bool(), eq(false));
37
38 msg.set_optional_bool(true);
39 assert_that!(msg.optional_bool(), eq(true));
40
41 msg.set_optional_bool(bool::default());
42 assert_that!(msg.optional_bool(), eq(false));
43 }
44
45 #[gtest]
test_bytes_accessors()46 fn test_bytes_accessors() {
47 let mut msg = TestAllTypes::new();
48 // Note: even though it's named 'optional_bytes', the field is actually not
49 // proto3 optional, so it does not support presence.
50 assert_that!(*msg.optional_bytes(), empty());
51
52 msg.set_optional_bytes(b"accessors_test");
53 assert_that!(msg.optional_bytes(), eq(b"accessors_test"));
54
55 {
56 let s = Vec::from(&b"hello world"[..]);
57 msg.set_optional_bytes(&s[..]);
58 }
59 assert_that!(msg.optional_bytes(), eq(b"hello world"));
60
61 msg.set_optional_bytes(b"");
62 assert_that!(*msg.optional_bytes(), empty());
63 }
64
65 #[gtest]
test_optional_bytes_accessors()66 fn test_optional_bytes_accessors() {
67 let mut msg = TestProto3Optional::new();
68 assert_that!(*msg.optional_bytes(), empty());
69 assert_that!(msg.optional_bytes_opt(), eq(Optional::Unset(&b""[..])));
70
71 {
72 let s = Vec::from(&b"hello world"[..]);
73 msg.set_optional_bytes(&s[..]);
74 }
75 assert_that!(msg.optional_bytes(), eq(b"hello world"));
76 assert_that!(msg.optional_bytes_opt(), eq(Optional::Set(&b"hello world"[..])));
77
78 msg.set_optional_bytes(b"");
79 assert_that!(*msg.optional_bytes(), empty());
80 assert_that!(msg.optional_bytes_opt(), eq(Optional::Set(&b""[..])));
81
82 msg.set_optional_bytes(b"\xffbinary\x85non-utf8");
83 assert_that!(msg.optional_bytes(), eq(b"\xffbinary\x85non-utf8"));
84 assert_that!(msg.optional_bytes_opt(), eq(Optional::Set(&b"\xffbinary\x85non-utf8"[..])));
85 }
86
87 #[gtest]
test_string_accessors()88 fn test_string_accessors() {
89 let mut msg = TestAllTypes::new();
90 // Note: even though it's named 'optional_string', the field is actually not
91 // proto3 optional, so it does not support presence.
92 assert_that!(*msg.optional_string().as_bytes(), empty());
93
94 msg.set_optional_string("accessors_test");
95 assert_that!(msg.optional_string(), eq("accessors_test"));
96
97 {
98 let s = String::from("hello world");
99 msg.set_optional_string(&s[..]);
100 }
101 assert_that!(msg.optional_string(), eq("hello world"));
102
103 msg.set_optional_string("");
104 assert_that!(*msg.optional_string().as_bytes(), empty());
105 }
106
107 #[gtest]
test_optional_string_accessors()108 fn test_optional_string_accessors() {
109 let mut msg = TestProto3Optional::new();
110 assert_that!(*msg.optional_string().as_bytes(), empty());
111 assert_that!(msg.optional_string_opt(), eq(Optional::Unset("".into())));
112
113 {
114 let s = String::from("hello world");
115 msg.set_optional_string(&s[..]);
116 }
117 assert_that!(msg.optional_string(), eq("hello world"));
118 assert_that!(msg.optional_string_opt(), eq(Optional::Set("hello world".into())));
119
120 msg.set_optional_string("accessors_test");
121 assert_that!(msg.optional_string(), eq("accessors_test"));
122 assert_that!(msg.optional_string_opt(), eq(Optional::Set("accessors_test".into())));
123
124 msg.set_optional_string("");
125 assert_that!(*msg.optional_string().as_bytes(), empty());
126 assert_that!(msg.optional_string_opt(), eq(Optional::Set("".into())));
127 }
128
129 #[gtest]
test_nested_enum_accessors()130 fn test_nested_enum_accessors() {
131 use test_all_types::NestedEnum;
132
133 let mut msg = TestAllTypes::new();
134 assert_that!(msg.optional_nested_enum(), eq(NestedEnum::Zero));
135
136 msg.set_optional_nested_enum(NestedEnum::Baz);
137 assert_that!(msg.optional_nested_enum(), eq(NestedEnum::Baz));
138
139 msg.set_optional_nested_enum(NestedEnum::default());
140 assert_that!(msg.optional_nested_enum(), eq(NestedEnum::Zero));
141 }
142
143 #[gtest]
test_optional_nested_enum_accessors()144 fn test_optional_nested_enum_accessors() {
145 use test_proto3_optional::NestedEnum;
146
147 let mut msg = TestProto3Optional::new();
148 assert_that!(msg.optional_nested_enum(), eq(NestedEnum::Unspecified));
149 assert_that!(msg.optional_nested_enum_opt(), eq(Optional::Unset(NestedEnum::Unspecified)));
150
151 msg.set_optional_nested_enum(NestedEnum::Baz);
152 assert_that!(msg.optional_nested_enum_opt(), eq(Optional::Set(NestedEnum::Baz)));
153 assert_that!(msg.optional_nested_enum(), eq(NestedEnum::Baz));
154
155 msg.set_optional_nested_enum(NestedEnum::default());
156 assert_that!(msg.optional_nested_enum(), eq(NestedEnum::Unspecified));
157 assert_that!(msg.optional_nested_enum_opt(), eq(Optional::Set(NestedEnum::Unspecified)));
158 }
159
160 #[gtest]
test_foreign_enum_accessors()161 fn test_foreign_enum_accessors() {
162 use unittest_proto3_rust_proto::ForeignEnum;
163
164 let mut msg = TestAllTypes::new();
165 assert_that!(msg.optional_foreign_enum(), eq(ForeignEnum::ForeignZero));
166
167 msg.set_optional_foreign_enum(ForeignEnum::ForeignBaz);
168 assert_that!(msg.optional_foreign_enum(), eq(ForeignEnum::ForeignBaz));
169
170 msg.set_optional_foreign_enum(ForeignEnum::default());
171 assert_that!(msg.optional_foreign_enum(), eq(ForeignEnum::ForeignZero));
172 }
173
174 #[gtest]
test_oneof_accessors()175 fn test_oneof_accessors() {
176 use test_all_types::OneofField::*;
177
178 let mut msg = TestAllTypes::new();
179 assert_that!(msg.oneof_field(), matches_pattern!(not_set(_)));
180
181 msg.set_oneof_uint32(7);
182 assert_that!(msg.oneof_uint32_opt(), eq(Optional::Set(7)));
183 assert_that!(msg.oneof_field(), matches_pattern!(OneofUint32(eq(7))));
184
185 msg.clear_oneof_uint32();
186 assert_that!(msg.oneof_uint32_opt(), eq(Optional::Unset(0)));
187 assert_that!(msg.oneof_field(), matches_pattern!(not_set(_)));
188
189 msg.oneof_nested_message_mut(); // Cause the nested_message field to become set.
190
191 assert_that!(msg.oneof_bytes_opt(), matches_pattern!(Optional::Unset(_)));
192 assert_that!(msg.oneof_field(), matches_pattern!(OneofNestedMessage(_)));
193
194 msg.set_oneof_uint32(7);
195 msg.set_oneof_bytes(b"123");
196 assert_that!(msg.oneof_uint32_opt(), eq(Optional::Unset(0)));
197 assert_that!(msg.oneof_field(), matches_pattern!(OneofBytes(eq(b"123"))));
198
199 msg.clear_oneof_bytes();
200 assert_that!(msg.oneof_field(), matches_pattern!(not_set(_)));
201 }
202
203 #[gtest]
test_oneof_accessors_view_long_lifetime()204 fn test_oneof_accessors_view_long_lifetime() {
205 use test_all_types::OneofField::*;
206
207 let mut msg = TestAllTypes::new();
208 msg.set_oneof_uint32(7);
209
210 // The oneof-view accessor on MsgViews should maintain the longest lifetime (can
211 // outlive the message view).
212 let oneof = {
213 let view = msg.as_view();
214 view.oneof_field()
215 };
216 assert_that!(oneof, matches_pattern!(OneofUint32(eq(7))));
217 }
218
219 #[gtest]
test_oneof_enum_accessors()220 fn test_oneof_enum_accessors() {
221 use unittest_proto3_rust_proto::{
222 test_oneof2::{Foo, FooCase, NestedEnum},
223 TestOneof2,
224 };
225
226 let mut msg = TestOneof2::new();
227 assert_that!(msg.foo_enum_opt(), eq(Optional::Unset(NestedEnum::Unknown)));
228 assert_that!(msg.foo(), matches_pattern!(Foo::not_set(_)));
229 assert_that!(msg.foo_case(), matches_pattern!(FooCase::not_set));
230
231 msg.set_foo_enum(NestedEnum::Bar);
232 assert_that!(msg.foo_enum_opt(), eq(Optional::Set(NestedEnum::Bar)));
233 assert_that!(msg.foo(), matches_pattern!(Foo::FooEnum(eq(NestedEnum::Bar))));
234 assert_that!(msg.foo_case(), matches_pattern!(FooCase::FooEnum));
235 }
236
237 #[gtest]
test_submsg_setter()238 fn test_submsg_setter() {
239 use test_all_types::*;
240
241 let mut nested = NestedMessage::new();
242 nested.set_bb(7);
243
244 let mut parent = TestAllTypes::new();
245 parent.set_optional_nested_message(nested);
246
247 assert_that!(parent.optional_nested_message().bb(), eq(7));
248 }
249
250 #[gtest]
test_ctype_stringpiece()251 fn test_ctype_stringpiece() {
252 let mut msg = TestAllTypes::new();
253 assert_that!(msg.optional_string_piece(), eq(""));
254 msg.set_optional_string_piece("hello");
255 assert_that!(msg.optional_string_piece(), eq("hello"));
256 }
257
258 #[gtest]
test_msg_clear()259 fn test_msg_clear() {
260 let mut m = TestAllTypes::new();
261 m.set_optional_int32(42);
262 assert_that!(m.optional_int32(), eq(42));
263 m.clear();
264 assert_that!(m.optional_int32(), eq(0));
265 }
266
267 #[gtest]
test_submsg_clear()268 fn test_submsg_clear() {
269 let mut m = TestAllTypes::new();
270 let mut sub = m.optional_nested_message_mut();
271 sub.set_bb(7);
272
273 assert_that!(m.has_optional_nested_message(), eq(true));
274 assert_that!(m.optional_nested_message().bb(), eq(7));
275
276 m.optional_nested_message_mut().clear();
277
278 // .clear() on the submsg doesn't affect its presence on the parent:
279 assert_that!(m.has_optional_nested_message(), eq(true));
280 // ...but it does clear the submsg's value:
281 assert_that!(m.optional_nested_message().bb(), eq(0));
282 }
283