1 // Copyright 2019 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of 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,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 // Tests for [requires] using requires.emb.
16 #include <stdint.h>
17
18 #include <vector>
19
20 #include "gtest/gtest.h"
21 #include "testdata/requires.emb.h"
22
23 namespace emboss {
24 namespace test {
25 namespace {
26
TEST(RequiresIntegers,Ok)27 TEST(RequiresIntegers, Ok) {
28 ::std::array</**/ ::std::uint8_t, 3> buffer = {0, 0, 0};
29 auto view = MakeRequiresIntegersView(&buffer);
30 EXPECT_TRUE(view.zero_through_nine().Ok());
31 EXPECT_FALSE(view.ten_through_twenty().Ok());
32 EXPECT_TRUE(view.disjoint().Ok());
33 EXPECT_FALSE(view.ztn_plus_ttt().Ok());
34 EXPECT_TRUE(view.zero_through_nine_plus_five().Ok());
35 EXPECT_FALSE(view.alias_of_zero_through_nine().Ok());
36
37 buffer[1] = 10;
38 EXPECT_TRUE(view.zero_through_nine().Ok());
39 EXPECT_TRUE(view.ten_through_twenty().Ok());
40 EXPECT_TRUE(view.disjoint().Ok());
41 EXPECT_TRUE(view.ztn_plus_ttt().Ok());
42 EXPECT_TRUE(view.zero_through_nine_plus_five().Ok());
43 EXPECT_FALSE(view.alias_of_zero_through_nine().Ok());
44
45 buffer[0] = 2;
46 EXPECT_TRUE(view.zero_through_nine().Ok());
47 EXPECT_TRUE(view.ten_through_twenty().Ok());
48 EXPECT_TRUE(view.disjoint().Ok());
49 EXPECT_TRUE(view.ztn_plus_ttt().Ok());
50 EXPECT_TRUE(view.zero_through_nine_plus_five().Ok());
51 EXPECT_TRUE(view.alias_of_zero_through_nine().Ok());
52 EXPECT_FALSE(view.Ok());
53
54 buffer[1] = 12;
55 EXPECT_TRUE(view.zero_through_nine().Ok());
56 EXPECT_TRUE(view.ten_through_twenty().Ok());
57 EXPECT_TRUE(view.disjoint().Ok());
58 EXPECT_TRUE(view.ztn_plus_ttt().Ok());
59 EXPECT_TRUE(view.zero_through_nine_plus_five().Ok());
60 EXPECT_TRUE(view.alias_of_zero_through_nine().Ok());
61 EXPECT_TRUE(view.Ok());
62 }
63
TEST(RequiresIntegers,CouldWriteValue)64 TEST(RequiresIntegers, CouldWriteValue) {
65 ::std::array</**/ ::std::uint8_t, 3> buffer = {0, 0, 0};
66 auto view = MakeRequiresIntegersView(&buffer);
67
68 EXPECT_TRUE(view.zero_through_nine().CouldWriteValue(0));
69 EXPECT_TRUE(view.zero_through_nine().CouldWriteValue(9));
70 EXPECT_FALSE(view.zero_through_nine().CouldWriteValue(-1));
71 EXPECT_FALSE(view.zero_through_nine().CouldWriteValue(10));
72
73 EXPECT_TRUE(view.ten_through_twenty().CouldWriteValue(10));
74 EXPECT_TRUE(view.ten_through_twenty().CouldWriteValue(20));
75 EXPECT_FALSE(view.ten_through_twenty().CouldWriteValue(-1));
76 EXPECT_FALSE(view.ten_through_twenty().CouldWriteValue(9));
77 EXPECT_FALSE(view.ten_through_twenty().CouldWriteValue(21));
78
79 EXPECT_TRUE(view.disjoint().CouldWriteValue(0));
80 EXPECT_TRUE(view.disjoint().CouldWriteValue(5));
81 EXPECT_TRUE(view.disjoint().CouldWriteValue(15));
82 EXPECT_TRUE(view.disjoint().CouldWriteValue(20));
83 EXPECT_FALSE(view.disjoint().CouldWriteValue(-1));
84 EXPECT_FALSE(view.disjoint().CouldWriteValue(6));
85 EXPECT_FALSE(view.disjoint().CouldWriteValue(14));
86 EXPECT_FALSE(view.disjoint().CouldWriteValue(21));
87 }
88
TEST(RequiresBools,Ok)89 TEST(RequiresBools, Ok) {
90 ::std::array</**/ ::std::uint8_t, 1> buffer = {0};
91 auto view = MakeRequiresBoolsView(&buffer);
92 EXPECT_TRUE(view.must_be_false().Ok());
93 EXPECT_FALSE(view.must_be_true().Ok());
94 EXPECT_TRUE(view.b_must_be_false().Ok());
95 EXPECT_FALSE(view.alias_of_a_must_be_true().Ok());
96 EXPECT_FALSE(view.Ok());
97
98 view.a().Write(true);
99 view.must_be_true().Write(true);
100 EXPECT_TRUE(view.must_be_false().Ok());
101 EXPECT_TRUE(view.must_be_true().Ok());
102 EXPECT_TRUE(view.b_must_be_false().Ok());
103 EXPECT_TRUE(view.alias_of_a_must_be_true().Ok());
104 EXPECT_TRUE(view.Ok());
105 }
106
TEST(RequiresBools,CouldWriteValue)107 TEST(RequiresBools, CouldWriteValue) {
108 ::std::array</**/ ::std::uint8_t, 1> buffer = {0};
109 auto view = MakeRequiresBoolsView(&buffer);
110
111 EXPECT_TRUE(view.a().CouldWriteValue(true));
112 EXPECT_TRUE(view.a().CouldWriteValue(false));
113 EXPECT_TRUE(view.b().CouldWriteValue(true));
114 EXPECT_TRUE(view.b().CouldWriteValue(false));
115 EXPECT_TRUE(view.must_be_true().CouldWriteValue(true));
116 EXPECT_FALSE(view.must_be_true().CouldWriteValue(false));
117 EXPECT_FALSE(view.must_be_false().CouldWriteValue(true));
118 EXPECT_TRUE(view.must_be_false().CouldWriteValue(false));
119 EXPECT_TRUE(view.alias_of_a_must_be_true().CouldWriteValue(true));
120 EXPECT_FALSE(view.alias_of_a_must_be_true().CouldWriteValue(false));
121 #if EMBOSS_CHECK_ABORTS
122 EXPECT_DEATH(view.alias_of_a_must_be_true().Write(false), "");
123 #endif // EMBOSS_CHECK_ABORTS
124 }
125
TEST(RequiresEnums,Ok)126 TEST(RequiresEnums, Ok) {
127 ::std::array</**/ ::std::uint8_t, 3> buffer = {0, 0, 0};
128 auto view = MakeRequiresEnumsView(&buffer);
129 EXPECT_TRUE(view.a().Ok());
130 EXPECT_TRUE(view.b().Ok());
131 EXPECT_TRUE(view.c().Ok());
132 EXPECT_TRUE(view.filtered_a().Ok());
133 EXPECT_FALSE(view.alias_of_a().Ok());
134 EXPECT_FALSE(view.Ok());
135
136 view.a().Write(RequiresEnums::Enum::EN1);
137 EXPECT_TRUE(view.a().Ok());
138 EXPECT_TRUE(view.b().Ok());
139 EXPECT_TRUE(view.c().Ok());
140 EXPECT_TRUE(view.filtered_a().Ok());
141 EXPECT_TRUE(view.alias_of_a().Ok());
142 EXPECT_TRUE(view.Ok());
143
144 view.b().Write(RequiresEnums::Enum::EN1);
145 EXPECT_TRUE(view.a().Ok());
146 EXPECT_TRUE(view.b().Ok());
147 EXPECT_TRUE(view.c().Ok());
148 EXPECT_TRUE(view.filtered_a().Ok());
149 EXPECT_TRUE(view.alias_of_a().Ok());
150 EXPECT_FALSE(view.Ok());
151
152 buffer[2] = 2;
153 EXPECT_FALSE(view.c().Ok());
154 }
155
TEST(RequiresEnums,CouldWriteValue)156 TEST(RequiresEnums, CouldWriteValue) {
157 ::std::array</**/ ::std::uint8_t, 3> buffer = {0, 0, 0};
158 auto view = MakeRequiresEnumsView(&buffer);
159
160 EXPECT_TRUE(view.a().CouldWriteValue(RequiresEnums::Enum::EN0));
161 EXPECT_TRUE(view.a().CouldWriteValue(RequiresEnums::Enum::EN3));
162 EXPECT_TRUE(view.b().CouldWriteValue(RequiresEnums::Enum::EN0));
163 EXPECT_TRUE(view.b().CouldWriteValue(RequiresEnums::Enum::EN3));
164 EXPECT_TRUE(view.c().CouldWriteValue(RequiresEnums::Enum::EN0));
165 EXPECT_TRUE(view.c().CouldWriteValue(RequiresEnums::Enum::EN1));
166 EXPECT_FALSE(view.c().CouldWriteValue(RequiresEnums::Enum::EN2));
167 EXPECT_FALSE(view.c().CouldWriteValue(RequiresEnums::Enum::EN3));
168 EXPECT_FALSE(view.alias_of_a().CouldWriteValue(RequiresEnums::Enum::EN0));
169 EXPECT_TRUE(view.alias_of_a().CouldWriteValue(RequiresEnums::Enum::EN1));
170 EXPECT_FALSE(view.alias_of_a().CouldWriteValue(RequiresEnums::Enum::EN2));
171 EXPECT_FALSE(view.alias_of_a().CouldWriteValue(RequiresEnums::Enum::EN3));
172 }
173
TEST(RequiresWithOptionalFields,Ok)174 TEST(RequiresWithOptionalFields, Ok) {
175 ::std::array</**/ ::std::uint8_t, 1> buffer = {0};
176 auto view = MakeRequiresWithOptionalFieldsView(&buffer);
177 EXPECT_FALSE(view.Ok());
178 view.a().Write(true);
179 EXPECT_TRUE(view.Ok());
180 EXPECT_FALSE(view.has_b().Value());
181 view.b_exists().Write(true);
182 EXPECT_TRUE(view.b().Ok());
183 EXPECT_FALSE(view.b_true().Ok());
184 view.b_true().Write(true);
185 EXPECT_TRUE(view.b_true().Ok());
186 EXPECT_TRUE(view.Ok());
187 view.a().Write(false);
188 EXPECT_TRUE(view.Ok());
189 }
190
TEST(RequiresWithOptionalFields,CouldWriteValue)191 TEST(RequiresWithOptionalFields, CouldWriteValue) {
192 ::std::array</**/ ::std::uint8_t, 1> buffer = {0};
193 auto view = MakeRequiresWithOptionalFieldsView(&buffer);
194 view.b_exists().Write(true);
195
196 EXPECT_TRUE(view.a().CouldWriteValue(true));
197 EXPECT_TRUE(view.a().CouldWriteValue(false));
198 EXPECT_TRUE(view.b().CouldWriteValue(true));
199 EXPECT_TRUE(view.b().CouldWriteValue(false));
200 EXPECT_TRUE(view.b_true().CouldWriteValue(true));
201 EXPECT_FALSE(view.b_true().CouldWriteValue(false));
202 }
203
TEST(WriteToString,NotOkFieldsAreNotWritten)204 TEST(WriteToString, NotOkFieldsAreNotWritten) {
205 ::std::array</**/ ::std::uint8_t, 3> buffer = {0x00, 0x00, 0x00};
206 auto reader = MakeRequiresIntegersView(&buffer);
207 EXPECT_FALSE(reader.Ok());
208 EXPECT_EQ(
209 "{\n"
210 " zero_through_nine: 0 # 0x0\n"
211 " # ten_through_twenty: UNREADABLE\n"
212 " disjoint: 0 # 0x0\n"
213 " # ztn_plus_ttt: UNREADABLE\n"
214 " # alias_of_zero_through_nine: UNREADABLE\n"
215 " zero_through_nine_plus_five: 5 # 0x5\n"
216 "}",
217 ::emboss::WriteToString(
218 reader, ::emboss::MultilineText().WithAllowPartialOutput(true)));
219 EXPECT_EQ(
220 "{ zero_through_nine: 0, disjoint: 0, zero_through_nine_plus_five: 5 }",
221 ::emboss::WriteToString(
222 reader, ::emboss::TextOutputOptions().WithAllowPartialOutput(true)));
223 }
224
TEST(WriteToString,NotOkArrayElementsAreNotWritten)225 TEST(WriteToString, NotOkArrayElementsAreNotWritten) {
226 ::std::array</**/ ::std::uint8_t, 4> buffer = {0x20, 0x00, 0x30, 0x05};
227 auto reader = MakeRequiresInArrayElementsView(&buffer);
228 EXPECT_FALSE(reader.Ok());
229 EXPECT_EQ(
230 "{\n"
231 " xs: {\n"
232 " [0]: {\n"
233 " # x: UNREADABLE\n"
234 " }\n"
235 " [1]: {\n"
236 " x: 0 # 0x0\n"
237 " }\n"
238 " [2]: {\n"
239 " # x: UNREADABLE\n"
240 " }\n"
241 " [3]: {\n"
242 " x: 5 # 0x5\n"
243 " }\n"
244 " }\n"
245 "}",
246 ::emboss::WriteToString(
247 reader, ::emboss::MultilineText().WithAllowPartialOutput(true)));
248 EXPECT_EQ(
249 "{ xs: { [0]: { }, { x: 0 }, { }, { x: 5 } } }",
250 ::emboss::WriteToString(
251 reader, ::emboss::TextOutputOptions().WithAllowPartialOutput(true)));
252 }
253
254 } // namespace
255 } // namespace test
256 } // namespace emboss
257