1// Copyright 2018 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <unittest/unittest.h>
6
7#include <fidl/flat_ast.h>
8#include <fidl/lexer.h>
9#include <fidl/parser.h>
10#include <fidl/source_file.h>
11
12#include "test_library.h"
13
14namespace {
15
16class MaxBytesLibrary : public TestLibrary {
17public:
18    MaxBytesLibrary()
19        : TestLibrary("max_bytes.fidl", R"FIDL(
20library fidl.test.maxbytes;
21
22struct OneBool {
23  bool b;
24};
25
26struct OptionalOneBool {
27  OneBool? s;
28};
29
30struct TwoBools {
31  bool a;
32  bool b;
33};
34
35struct OptionalTwoBools {
36  TwoBools? s;
37};
38
39struct BoolAndU32 {
40  bool b;
41  uint32 u;
42};
43
44struct OptionalBoolAndU32 {
45  BoolAndU32? s;
46};
47
48struct BoolAndU64 {
49  bool b;
50  uint64 u;
51};
52
53struct OptionalBoolAndU64 {
54  BoolAndU64? s;
55};
56
57union UnionOfThings {
58  OneBool ob;
59  BoolAndU64 bu;
60};
61
62struct OptionalUnion {
63  UnionOfThings? u;
64};
65
66struct PaddedVector {
67  vector<int32>:3 pv;
68};
69
70struct UnboundedVector {
71  vector<int32> uv;
72};
73
74struct UnboundedVectors {
75  vector<int32> uv1;
76  vector<int32> uv2;
77};
78
79struct ShortString {
80  string:5 s;
81};
82
83struct UnboundedString {
84  string s;
85};
86
87struct AnArray {
88  array<int64>:5 a;
89};
90
91table TableWithOneBool {
92  1: bool b;
93};
94
95table TableWithOptionalOneBool {
96  1: OneBool s;
97};
98
99table TableWithOptionalTableWithOneBool {
100  1: TableWithOneBool s;
101};
102
103table TableWithTwoBools {
104  1: bool a;
105  2: bool b;
106};
107
108table TableWithOptionalTwoBools {
109  1: TwoBools s;
110};
111
112table TableWithOptionalTableWithTwoBools {
113  1: TableWithTwoBools s;
114};
115
116table TableWithBoolAndU32 {
117  1: bool b;
118  2: uint32 u;
119};
120
121table TableWithOptionalBoolAndU32 {
122  1: BoolAndU32 s;
123};
124
125table TableWithOptionalTableWithBoolAndU32 {
126  1: TableWithBoolAndU32 s;
127};
128
129table TableWithBoolAndU64 {
130  1: bool b;
131  2: uint64 u;
132};
133
134table TableWithOptionalBoolAndU64 {
135  1: BoolAndU64 s;
136};
137
138table TableWithOptionalTableWithBoolAndU64 {
139  1: TableWithBoolAndU64 s;
140};
141
142table TableWithOptionalUnion {
143  1: UnionOfThings u;
144};
145
146table TableWithPaddedVector {
147  1: vector<int32>:3 pv;
148};
149
150table TableWithUnboundedVector {
151  1: vector<int32> uv;
152};
153
154table TableWithUnboundedVectors {
155  1: vector<int32> uv1;
156  2: vector<int32> uv2;
157};
158
159table TableWithShortString {
160  1: string:5 s;
161};
162
163table TableWithUnboundedString {
164  1: string s;
165};
166
167table TableWithAnArray {
168  1: array<int64>:5 a;
169};
170
171)FIDL") {}
172};
173
174static bool simple_structs(void) {
175    BEGIN_TEST;
176
177    MaxBytesLibrary test_library;
178    EXPECT_TRUE(test_library.Compile());
179
180    auto one_bool = test_library.LookupStruct("OneBool");
181    EXPECT_NONNULL(one_bool);
182    EXPECT_EQ(one_bool->typeshape.Size(), 1);
183    EXPECT_EQ(one_bool->typeshape.MaxOutOfLine(), 0);
184
185    auto two_bools = test_library.LookupStruct("TwoBools");
186    EXPECT_NONNULL(two_bools);
187    EXPECT_EQ(two_bools->typeshape.Size(), 2);
188    EXPECT_EQ(two_bools->typeshape.MaxOutOfLine(), 0);
189
190    auto bool_and_u32 = test_library.LookupStruct("BoolAndU32");
191    EXPECT_NONNULL(bool_and_u32);
192    EXPECT_EQ(bool_and_u32->typeshape.Size(), 8);
193    EXPECT_EQ(bool_and_u32->typeshape.MaxOutOfLine(), 0);
194
195    auto bool_and_u64 = test_library.LookupStruct("BoolAndU64");
196    EXPECT_NONNULL(bool_and_u64);
197    EXPECT_EQ(bool_and_u64->typeshape.Size(), 16);
198    EXPECT_EQ(bool_and_u64->typeshape.MaxOutOfLine(), 0);
199
200    END_TEST;
201}
202
203static bool simple_tables(void) {
204    BEGIN_TEST;
205
206    MaxBytesLibrary test_library;
207    EXPECT_TRUE(test_library.Compile());
208
209    auto one_bool = test_library.LookupTable("TableWithOneBool");
210    EXPECT_NONNULL(one_bool);
211    EXPECT_EQ(one_bool->typeshape.Size(), 16);
212    EXPECT_EQ(one_bool->typeshape.MaxOutOfLine(), 24);
213
214    auto two_bools = test_library.LookupTable("TableWithTwoBools");
215    EXPECT_NONNULL(two_bools);
216    EXPECT_EQ(two_bools->typeshape.Size(), 16);
217    EXPECT_EQ(two_bools->typeshape.MaxOutOfLine(), 48);
218
219    auto bool_and_u32 = test_library.LookupTable("TableWithBoolAndU32");
220    EXPECT_NONNULL(bool_and_u32);
221    EXPECT_EQ(bool_and_u32->typeshape.Size(), 16);
222    EXPECT_EQ(bool_and_u32->typeshape.MaxOutOfLine(), 48);
223
224    auto bool_and_u64 = test_library.LookupTable("TableWithBoolAndU64");
225    EXPECT_NONNULL(bool_and_u64);
226    EXPECT_EQ(bool_and_u64->typeshape.Size(), 16);
227    EXPECT_EQ(bool_and_u64->typeshape.MaxOutOfLine(), 48);
228
229    END_TEST;
230}
231
232static bool optional_structs(void) {
233    BEGIN_TEST;
234
235    MaxBytesLibrary test_library;
236    EXPECT_TRUE(test_library.Compile());
237
238    auto one_bool = test_library.LookupStruct("OptionalOneBool");
239    EXPECT_NONNULL(one_bool);
240    EXPECT_EQ(one_bool->typeshape.Size(), 8);
241    EXPECT_EQ(one_bool->typeshape.MaxOutOfLine(), 8);
242
243    auto two_bools = test_library.LookupStruct("OptionalTwoBools");
244    EXPECT_NONNULL(two_bools);
245    EXPECT_EQ(two_bools->typeshape.Size(), 8);
246    EXPECT_EQ(two_bools->typeshape.MaxOutOfLine(), 8);
247
248    auto bool_and_u32 = test_library.LookupStruct("OptionalBoolAndU32");
249    EXPECT_NONNULL(bool_and_u32);
250    EXPECT_EQ(bool_and_u32->typeshape.Size(), 8);
251    EXPECT_EQ(bool_and_u32->typeshape.MaxOutOfLine(), 8);
252
253    auto bool_and_u64 = test_library.LookupStruct("OptionalBoolAndU64");
254    EXPECT_NONNULL(bool_and_u64);
255    EXPECT_EQ(bool_and_u64->typeshape.Size(), 8);
256    EXPECT_EQ(bool_and_u64->typeshape.MaxOutOfLine(), 16);
257
258    END_TEST;
259}
260
261static bool optional_tables(void) {
262    BEGIN_TEST;
263
264    MaxBytesLibrary test_library;
265    EXPECT_TRUE(test_library.Compile());
266
267    auto one_bool = test_library.LookupTable("TableWithOptionalOneBool");
268    EXPECT_NONNULL(one_bool);
269    EXPECT_EQ(one_bool->typeshape.Size(), 16);
270    EXPECT_EQ(one_bool->typeshape.MaxOutOfLine(), 24);
271
272    auto table_with_one_bool = test_library.LookupTable("TableWithOptionalTableWithOneBool");
273    EXPECT_NONNULL(table_with_one_bool);
274    EXPECT_EQ(table_with_one_bool->typeshape.Size(), 16);
275    EXPECT_EQ(table_with_one_bool->typeshape.MaxOutOfLine(), 56);
276
277    auto two_bools = test_library.LookupTable("TableWithOptionalTwoBools");
278    EXPECT_NONNULL(two_bools);
279    EXPECT_EQ(two_bools->typeshape.Size(), 16);
280    EXPECT_EQ(two_bools->typeshape.MaxOutOfLine(), 24);
281
282    auto table_with_two_bools = test_library.LookupTable("TableWithOptionalTableWithTwoBools");
283    EXPECT_NONNULL(table_with_two_bools);
284    EXPECT_EQ(table_with_two_bools->typeshape.Size(), 16);
285    EXPECT_EQ(table_with_two_bools->typeshape.MaxOutOfLine(), 80);
286
287    auto bool_and_u32 = test_library.LookupTable("TableWithOptionalBoolAndU32");
288    EXPECT_NONNULL(bool_and_u32);
289    EXPECT_EQ(bool_and_u32->typeshape.Size(), 16);
290    EXPECT_EQ(bool_and_u32->typeshape.MaxOutOfLine(), 24);
291
292    auto table_with_bool_and_u32 = test_library.LookupTable("TableWithOptionalTableWithBoolAndU32");
293    EXPECT_NONNULL(table_with_bool_and_u32);
294    EXPECT_EQ(table_with_bool_and_u32->typeshape.Size(), 16);
295    EXPECT_EQ(table_with_bool_and_u32->typeshape.MaxOutOfLine(), 80);
296
297    auto bool_and_u64 = test_library.LookupTable("TableWithOptionalBoolAndU64");
298    EXPECT_NONNULL(bool_and_u64);
299    EXPECT_EQ(bool_and_u64->typeshape.Size(), 16);
300    EXPECT_EQ(bool_and_u64->typeshape.MaxOutOfLine(), 32);
301
302    auto table_with_bool_and_u64 = test_library.LookupTable("TableWithOptionalTableWithBoolAndU64");
303    EXPECT_NONNULL(table_with_bool_and_u64);
304    EXPECT_EQ(table_with_bool_and_u64->typeshape.Size(), 16);
305    EXPECT_EQ(table_with_bool_and_u64->typeshape.MaxOutOfLine(), 80);
306
307    END_TEST;
308}
309
310static bool unions(void) {
311    BEGIN_TEST;
312
313    MaxBytesLibrary test_library;
314    EXPECT_TRUE(test_library.Compile());
315
316    auto a_union = test_library.LookupUnion("UnionOfThings");
317    EXPECT_NONNULL(a_union);
318    EXPECT_EQ(a_union->typeshape.Size(), 24);
319    EXPECT_EQ(a_union->typeshape.MaxOutOfLine(), 0);
320
321    auto optional_union = test_library.LookupStruct("OptionalUnion");
322    EXPECT_NONNULL(optional_union);
323    EXPECT_EQ(optional_union->typeshape.Size(), 8);
324    EXPECT_EQ(optional_union->typeshape.MaxOutOfLine(), 24);
325
326    auto table_with_optional_union = test_library.LookupTable("TableWithOptionalUnion");
327    EXPECT_NONNULL(table_with_optional_union);
328    EXPECT_EQ(table_with_optional_union->typeshape.Size(), 16);
329    EXPECT_EQ(table_with_optional_union->typeshape.MaxOutOfLine(), 40);
330
331    END_TEST;
332}
333
334static bool vectors(void) {
335    BEGIN_TEST;
336
337    MaxBytesLibrary test_library;
338    EXPECT_TRUE(test_library.Compile());
339
340    auto padded_vector = test_library.LookupStruct("PaddedVector");
341    EXPECT_NONNULL(padded_vector);
342    EXPECT_EQ(padded_vector->typeshape.Size(), 16);
343    EXPECT_EQ(padded_vector->typeshape.MaxOutOfLine(), 16);
344
345    auto unbounded_vector = test_library.LookupStruct("UnboundedVector");
346    EXPECT_NONNULL(unbounded_vector);
347    EXPECT_EQ(unbounded_vector->typeshape.Size(), 16);
348    EXPECT_EQ(unbounded_vector->typeshape.MaxOutOfLine(), std::numeric_limits<uint32_t>::max());
349
350    auto unbounded_vectors = test_library.LookupStruct("UnboundedVectors");
351    EXPECT_NONNULL(unbounded_vectors);
352    EXPECT_EQ(unbounded_vectors->typeshape.Size(), 32);
353    EXPECT_EQ(unbounded_vectors->typeshape.MaxOutOfLine(), std::numeric_limits<uint32_t>::max());
354
355    auto table_with_padded_vector = test_library.LookupTable("TableWithPaddedVector");
356    EXPECT_NONNULL(table_with_padded_vector);
357    EXPECT_EQ(table_with_padded_vector->typeshape.Size(), 16);
358    EXPECT_EQ(table_with_padded_vector->typeshape.MaxOutOfLine(), 48);
359
360    auto table_with_unbounded_vector = test_library.LookupTable("TableWithUnboundedVector");
361    EXPECT_NONNULL(table_with_unbounded_vector);
362    EXPECT_EQ(table_with_unbounded_vector->typeshape.Size(), 16);
363    EXPECT_EQ(table_with_unbounded_vector->typeshape.MaxOutOfLine(), std::numeric_limits<uint32_t>::max());
364
365    auto table_with_unbounded_vectors = test_library.LookupTable("TableWithUnboundedVectors");
366    EXPECT_NONNULL(table_with_unbounded_vectors);
367    EXPECT_EQ(table_with_unbounded_vectors->typeshape.Size(), 16);
368    EXPECT_EQ(table_with_unbounded_vectors->typeshape.MaxOutOfLine(), std::numeric_limits<uint32_t>::max());
369
370    END_TEST;
371}
372
373static bool strings(void) {
374    BEGIN_TEST;
375
376    MaxBytesLibrary test_library;
377    EXPECT_TRUE(test_library.Compile());
378
379    auto short_string = test_library.LookupStruct("ShortString");
380    EXPECT_NONNULL(short_string);
381    EXPECT_EQ(short_string->typeshape.Size(), 16);
382    EXPECT_EQ(short_string->typeshape.MaxOutOfLine(), 8);
383
384    auto unbounded_string = test_library.LookupStruct("UnboundedString");
385    EXPECT_NONNULL(unbounded_string);
386    EXPECT_EQ(unbounded_string->typeshape.Size(), 16);
387    EXPECT_EQ(unbounded_string->typeshape.MaxOutOfLine(), std::numeric_limits<uint32_t>::max());
388
389    auto table_with_short_string = test_library.LookupTable("TableWithShortString");
390    EXPECT_NONNULL(table_with_short_string);
391    EXPECT_EQ(table_with_short_string->typeshape.Size(), 16);
392    EXPECT_EQ(table_with_short_string->typeshape.MaxOutOfLine(), 40);
393
394    auto table_with_unbounded_string = test_library.LookupTable("TableWithUnboundedString");
395    EXPECT_NONNULL(table_with_unbounded_string);
396    EXPECT_EQ(table_with_unbounded_string->typeshape.Size(), 16);
397    EXPECT_EQ(table_with_unbounded_string->typeshape.MaxOutOfLine(), std::numeric_limits<uint32_t>::max());
398
399    END_TEST;
400}
401
402static bool arrays(void) {
403    BEGIN_TEST;
404
405    MaxBytesLibrary test_library;
406    EXPECT_TRUE(test_library.Compile());
407
408    auto an_array = test_library.LookupStruct("AnArray");
409    EXPECT_NONNULL(an_array);
410    EXPECT_EQ(an_array->typeshape.Size(), 40);
411    EXPECT_EQ(an_array->typeshape.MaxOutOfLine(), 0);
412
413    auto table_with_an_array = test_library.LookupTable("TableWithAnArray");
414    EXPECT_NONNULL(table_with_an_array);
415    EXPECT_EQ(table_with_an_array->typeshape.Size(), 16);
416    EXPECT_EQ(table_with_an_array->typeshape.MaxOutOfLine(), 56);
417
418    END_TEST;
419}
420
421} // namespace
422
423BEGIN_TEST_CASE(max_bytes_tests);
424RUN_TEST(simple_structs);
425RUN_TEST(simple_tables);
426RUN_TEST(optional_structs);
427RUN_TEST(optional_tables);
428RUN_TEST(unions);
429RUN_TEST(vectors);
430RUN_TEST(strings);
431RUN_TEST(arrays);
432END_TEST_CASE(max_bytes_tests);
433