• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 enum type generation.
9 
10 use enums_rust_proto::*;
11 use googletest::prelude::*;
12 use protobuf::Enum;
13 use unittest_rust_proto::*;
14 
15 #[gtest]
test_nested_enum_values()16 fn test_nested_enum_values() {
17     assert_that!(i32::from(test_all_types::NestedEnum::Foo), eq(1));
18     assert_that!(i32::from(test_all_types::NestedEnum::Bar), eq(2));
19     assert_that!(i32::from(test_all_types::NestedEnum::Baz), eq(3));
20     assert_that!(i32::from(test_all_types::NestedEnum::Neg), eq(-1));
21 }
22 
23 #[gtest]
test_isolated_nested_enum()24 fn test_isolated_nested_enum() {
25     // Ensure that the enum is generated even when it's the only nested type for the
26     // message.
27     assert_that!(i32::from(test_required_enum_no_mask::NestedEnum::Foo), eq(2));
28 }
29 
30 #[gtest]
test_enum_value_name_same_as_enum()31 fn test_enum_value_name_same_as_enum() {
32     assert_that!(i32::from(TestEnumValueNameSameAsEnum::TestEnumValueNameSameAsEnum), eq(1));
33 }
34 
35 #[gtest]
test_enum_defaults()36 fn test_enum_defaults() {
37     assert_that!(TestSparseEnum::default(), eq(TestSparseEnum::SparseA));
38     assert_that!(TestEnumWithDupValue::default(), eq(TestEnumWithDupValue::Foo1));
39     assert_that!(TestEnumWithDupValue::default(), eq(TestEnumWithDupValue::Foo2));
40     assert_that!(
41         TestEnumWithDuplicateStrippedPrefixNames::default(),
42         eq(TestEnumWithDuplicateStrippedPrefixNames::Unknown)
43     );
44     assert_that!(test_all_types::NestedEnum::default(), eq(test_all_types::NestedEnum::Foo));
45 }
46 
47 #[gtest]
48 #[deny(unreachable_patterns)]
49 #[allow(clippy::let_unit_value)]
test_closed_enum_is_nonexhaustive()50 fn test_closed_enum_is_nonexhaustive() {
51     let val = ForeignEnum::ForeignFoo;
52     let _it_compiles: () = match val {
53         ForeignEnum::ForeignFoo => (),
54         ForeignEnum::ForeignBar => (),
55         ForeignEnum::ForeignBaz => (),
56         ForeignEnum::ForeignBax => (),
57         _ => unreachable!(),
58     };
59 }
60 
61 #[gtest]
test_closed_enum_conversion()62 fn test_closed_enum_conversion() {
63     assert_that!(i32::from(TestSparseEnum::SparseA), eq(123));
64     assert_that!(TestSparseEnum::try_from(123), ok(eq(&TestSparseEnum::SparseA)));
65 
66     assert_that!(i32::from(TestSparseEnum::SparseD), eq(-15));
67     assert_that!(TestSparseEnum::try_from(-15), ok(eq(&TestSparseEnum::SparseD)));
68 
69     assert_that!(TestSparseEnum::try_from(0), ok(eq(&TestSparseEnum::SparseF)));
70     assert_that!(TestSparseEnum::try_from(1), err(anything()));
71 }
72 
73 #[gtest]
test_closed_aliased_enum_conversion()74 fn test_closed_aliased_enum_conversion() {
75     assert_that!(i32::from(TestEnumWithDupValue::Foo1), eq(1));
76     assert_that!(i32::from(TestEnumWithDupValue::Foo2), eq(1));
77     assert_that!(i32::from(TestEnumWithDupValue::Bar1), eq(2));
78     assert_that!(i32::from(TestEnumWithDupValue::Bar2), eq(2));
79     assert_that!(i32::from(TestEnumWithDupValue::Baz), eq(3));
80 
81     assert_that!(TestEnumWithDupValue::try_from(1), ok(eq(&TestEnumWithDupValue::Foo1)));
82     assert_that!(TestEnumWithDupValue::try_from(2), ok(eq(&TestEnumWithDupValue::Bar1)));
83     assert_that!(TestEnumWithDupValue::try_from(3), ok(eq(&TestEnumWithDupValue::Baz)));
84     assert_that!(TestEnumWithDupValue::try_from(0), err(anything()));
85     assert_that!(TestEnumWithDupValue::try_from(4), err(anything()));
86 
87     assert_that!(TestEnumWithDupValue::Foo1, eq(TestEnumWithDupValue::Foo2));
88     assert_that!(TestEnumWithDupValue::Bar1, eq(TestEnumWithDupValue::Bar2));
89 }
90 
91 #[gtest]
92 #[deny(unreachable_patterns)]
93 #[allow(clippy::let_unit_value)]
test_open_enum_is_nonexhaustive()94 fn test_open_enum_is_nonexhaustive() {
95     let val = TestEnumValueNameSameAsEnum::Unknown;
96     let _it_compiles: () = match val {
97         TestEnumValueNameSameAsEnum::Unknown => (),
98         TestEnumValueNameSameAsEnum::TestEnumValueNameSameAsEnum => (),
99         _ => unreachable!(),
100     };
101 }
102 
103 #[gtest]
test_open_enum_conversion()104 fn test_open_enum_conversion() {
105     assert_that!(i32::from(TestEnumWithNumericNames::Unknown), eq(0));
106     assert_that!(i32::from(TestEnumWithNumericNames::_2020), eq(1));
107     assert_that!(i32::from(TestEnumWithNumericNames::_2021), eq(2));
108     assert_that!(i32::from(TestEnumWithNumericNames::_2022), eq(3));
109 
110     assert_that!(TestEnumWithNumericNames::from(0), eq(TestEnumWithNumericNames::Unknown));
111     assert_that!(TestEnumWithNumericNames::from(1), eq(TestEnumWithNumericNames::_2020));
112     assert_that!(TestEnumWithNumericNames::from(2), eq(TestEnumWithNumericNames::_2021));
113     assert_that!(TestEnumWithNumericNames::from(3), eq(TestEnumWithNumericNames::_2022));
114     assert_that!(
115         TestEnumWithNumericNames::from(4),
116         not(any![
117             eq(TestEnumWithNumericNames::Unknown),
118             eq(TestEnumWithNumericNames::_2020),
119             eq(TestEnumWithNumericNames::_2021),
120             eq(TestEnumWithNumericNames::_2022),
121         ])
122     );
123     assert_that!(i32::from(TestEnumWithNumericNames::from(-1)), eq(-1));
124 }
125 
126 #[gtest]
test_open_aliased_enum_conversion()127 fn test_open_aliased_enum_conversion() {
128     assert_that!(i32::from(TestEnumWithDuplicateStrippedPrefixNames::Unknown), eq(0));
129     assert_that!(i32::from(TestEnumWithDuplicateStrippedPrefixNames::Foo), eq(1));
130     assert_that!(i32::from(TestEnumWithDuplicateStrippedPrefixNames::Bar), eq(2));
131     assert_that!(i32::from(TestEnumWithDuplicateStrippedPrefixNames::DifferentNameAlias), eq(2));
132 
133     assert_that!(
134         TestEnumWithDuplicateStrippedPrefixNames::from(0),
135         eq(TestEnumWithDuplicateStrippedPrefixNames::Unknown)
136     );
137     assert_that!(
138         TestEnumWithDuplicateStrippedPrefixNames::from(1),
139         eq(TestEnumWithDuplicateStrippedPrefixNames::Foo)
140     );
141     assert_that!(
142         TestEnumWithDuplicateStrippedPrefixNames::from(2),
143         eq(TestEnumWithDuplicateStrippedPrefixNames::Bar)
144     );
145     assert_that!(
146         TestEnumWithDuplicateStrippedPrefixNames::from(2),
147         eq(TestEnumWithDuplicateStrippedPrefixNames::DifferentNameAlias)
148     );
149     assert_that!(
150         TestEnumWithDuplicateStrippedPrefixNames::from(3),
151         not(any![
152             eq(TestEnumWithDuplicateStrippedPrefixNames::Unknown),
153             eq(TestEnumWithDuplicateStrippedPrefixNames::Foo),
154             eq(TestEnumWithDuplicateStrippedPrefixNames::Bar),
155         ])
156     );
157     assert_that!(i32::from(TestEnumWithDuplicateStrippedPrefixNames::from(5)), eq(5));
158 }
159 
160 #[gtest]
test_enum_conversion_failure_display()161 fn test_enum_conversion_failure_display() {
162     let err = TestSparseEnum::try_from(1).unwrap_err();
163     assert_that!(format!("{err}"), eq("1 is not a known value for TestSparseEnum"));
164 }
165 
166 #[gtest]
test_enum_conversion_failure_impls_std_error()167 fn test_enum_conversion_failure_impls_std_error() {
168     let err = TestSparseEnum::try_from(1).unwrap_err();
169     let _test_compiles: &dyn std::error::Error = &err;
170 }
171 
172 #[gtest]
test_is_known_for_closed_enum()173 fn test_is_known_for_closed_enum() {
174     assert_that!(test_all_types::NestedEnum::is_known(-2), eq(false));
175     assert_that!(test_all_types::NestedEnum::is_known(-1), eq(true));
176     assert_that!(test_all_types::NestedEnum::is_known(0), eq(false));
177     assert_that!(test_all_types::NestedEnum::is_known(1), eq(true));
178     assert_that!(test_all_types::NestedEnum::is_known(2), eq(true));
179     assert_that!(test_all_types::NestedEnum::is_known(3), eq(true));
180     assert_that!(test_all_types::NestedEnum::is_known(4), eq(false));
181 }
182 
183 #[gtest]
test_is_known_for_open_enum()184 fn test_is_known_for_open_enum() {
185     assert_that!(TestEnumWithNumericNames::is_known(-1), eq(false));
186     assert_that!(TestEnumWithNumericNames::is_known(0), eq(true));
187     assert_that!(TestEnumWithNumericNames::is_known(1), eq(true));
188     assert_that!(TestEnumWithNumericNames::is_known(2), eq(true));
189     assert_that!(TestEnumWithNumericNames::is_known(3), eq(true));
190     assert_that!(TestEnumWithNumericNames::is_known(4), eq(false));
191 }
192