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 the generated View class for Container and Box from
16 // nested_structure.emb.
17 //
18 // These tests check that nested structures work.
19 #include <stdint.h>
20
21 #include <vector>
22
23 #include "gtest/gtest.h"
24 #include "testdata/nested_structure.emb.h"
25
26 namespace emboss {
27 namespace test {
28 namespace {
29
30 alignas(8) static const ::std::uint8_t kContainer[20] = {
31 0x28, 0x00, 0x00, 0x00, // 0:4 weight == 40
32 0x78, 0x56, 0x34, 0x12, // 4:8 important_box.id == 0x12345678
33 0x03, 0x02, 0x01, 0x00, // 8:12 important_box.count == 0x010203
34 0x21, 0x43, 0x65, 0x87, // 12:16 other_box.id == 0x87654321
35 0xcc, 0xbb, 0xaa, 0x00, // 16:20 other_box.count == 0xaabbcc
36 };
37
38 // ContainerView::SizeInBytes() returns the expected value.
TEST(ContainerView,StaticSizeIsCorrect)39 TEST(ContainerView, StaticSizeIsCorrect) {
40 EXPECT_EQ(20U, ContainerView::SizeInBytes());
41 }
42
43 // ContainerView::SizeInBytes() returns the expected value.
TEST(ContainerView,SizeFieldIsCorrect)44 TEST(ContainerView, SizeFieldIsCorrect) {
45 auto view = MakeAlignedContainerView<const ::std::uint8_t, 8>(
46 kContainer, sizeof kContainer);
47 EXPECT_EQ(40U, view.weight().Read());
48 }
49
50 // ContainerView::important_box() returns a BoxView, and not a different
51 // template instantiation.
TEST(ContainerView,FieldTypesAreExpected)52 TEST(ContainerView, FieldTypesAreExpected) {
53 auto container = MakeAlignedContainerView<const ::std::uint8_t, 8>(
54 kContainer, sizeof kContainer);
55 auto box = container.important_box();
56 EXPECT_EQ(0x12345678U, box.id().Read());
57 }
58
59 // Box::SizeInBytes() returns the expected value, when retrieved from a
60 // Container.
TEST(ContainerView,BoxSizeFieldIsCorrect)61 TEST(ContainerView, BoxSizeFieldIsCorrect) {
62 auto view = MakeAlignedContainerView<const ::std::uint8_t, 8>(
63 kContainer, sizeof kContainer);
64 EXPECT_EQ(8U, view.important_box().SizeInBytes());
65 }
66
67 // Box::id() and Box::count() return correct values when retrieved from
68 // Container.
TEST(ContainerView,BoxFieldValuesAreCorrect)69 TEST(ContainerView, BoxFieldValuesAreCorrect) {
70 auto view = MakeAlignedContainerView<const ::std::uint8_t, 8>(
71 kContainer, sizeof kContainer);
72 EXPECT_EQ(0x12345678U, view.important_box().id().Read());
73 EXPECT_EQ(0x010203U, view.important_box().count().Read());
74 EXPECT_EQ(0x87654321U, view.other_box().id().Read());
75 EXPECT_EQ(0xaabbccU, view.other_box().count().Read());
76 }
77
TEST(ContainerView,CanWriteValues)78 TEST(ContainerView, CanWriteValues) {
79 alignas(8)::std::uint8_t buffer[sizeof kContainer];
80 auto writer =
81 MakeAlignedContainerView</**/ ::std::uint8_t, 8>(buffer, sizeof buffer);
82 writer.weight().Write(40);
83 writer.important_box().id().Write(0x12345678);
84 writer.important_box().count().Write(0x010203);
85 writer.other_box().id().Write(0x87654321);
86 writer.other_box().count().Write(0xaabbcc);
87 EXPECT_EQ(::std::vector</**/ ::std::uint8_t>(kContainer,
88 kContainer + sizeof kContainer),
89 ::std::vector</**/ ::std::uint8_t>(buffer, buffer + sizeof buffer));
90 }
91
TEST(ContainerView,CanReadTextFormat)92 TEST(ContainerView, CanReadTextFormat) {
93 alignas(8)::std::uint8_t buffer[sizeof kContainer];
94 auto writer =
95 MakeAlignedContainerView</**/ ::std::uint8_t, 8>(buffer, sizeof buffer);
96 EXPECT_TRUE(::emboss::UpdateFromText(writer, R"(
97 {
98 weight: 40
99 important_box: {
100 id: 0x12345678
101 count: 0x010203
102 }
103 other_box: {
104 id: 0x87654321
105 count: 0xaabbcc
106 }
107 }
108 )"));
109 EXPECT_EQ(::std::vector</**/ ::std::uint8_t>(kContainer,
110 kContainer + sizeof kContainer),
111 ::std::vector</**/ ::std::uint8_t>(buffer, buffer + sizeof buffer));
112 }
113
114 alignas(8) static const ::std::uint8_t kTruck[44] = {
115 0x88, 0x66, 0x44, 0x22, // 0:4 id == 0x22446688
116 0x64, 0x00, 0x00, 0x00, // 4:8 cargo[0].weight == 100
117 0xff, 0x00, 0x00, 0x00, // 8:12 cargo[0].important_box.id == 255
118 0x0a, 0x00, 0x00, 0x00, // 12:16 cargo[0].important_box.count == 10
119 0x00, 0x94, 0x35, 0x77, // 16:20 cargo[0].other_box.id == 2000000000
120 0xf4, 0x01, 0x00, 0x00, // 20:24 cargo[0].other_box.count == 500
121 0x65, 0x00, 0x00, 0x00, // 24:28 cargo[1].weight == 101
122 0xfe, 0x00, 0x00, 0x00, // 28:32 cargo[1].important_box.id == 254
123 0x09, 0x00, 0x00, 0x00, // 32:36 cargo[1].important_box.count == 9
124 0x01, 0x94, 0x35, 0x77, // 36:40 cargo[1].other_box.id == 2000000001
125 0xf3, 0x01, 0x00, 0x00, // 40:44 cargo[1].other_box.count == 499
126 };
127
TEST(TruckView,ValuesAreCorrect)128 TEST(TruckView, ValuesAreCorrect) {
129 auto view =
130 MakeAlignedTruckView<const ::std::uint8_t, 8>(kTruck, sizeof kTruck);
131 EXPECT_EQ(0x22446688U, view.id().Read());
132 EXPECT_EQ(100U, view.cargo()[0].weight().Read());
133 EXPECT_EQ(255U, view.cargo()[0].important_box().id().Read());
134 EXPECT_EQ(10U, view.cargo()[0].important_box().count().Read());
135 EXPECT_EQ(2000000000U, view.cargo()[0].other_box().id().Read());
136 EXPECT_EQ(500U, view.cargo()[0].other_box().count().Read());
137 EXPECT_EQ(101U, view.cargo()[1].weight().Read());
138 EXPECT_EQ(254U, view.cargo()[1].important_box().id().Read());
139 EXPECT_EQ(9U, view.cargo()[1].important_box().count().Read());
140 EXPECT_EQ(2000000001U, view.cargo()[1].other_box().id().Read());
141 EXPECT_EQ(499U, view.cargo()[1].other_box().count().Read());
142 }
143
TEST(TruckView,WriteValues)144 TEST(TruckView, WriteValues) {
145 ::std::uint8_t buffer[sizeof kTruck];
146 auto writer = TruckWriter(buffer, sizeof buffer);
147 writer.id().Write(0x22446688);
148 writer.cargo()[0].weight().Write(100);
149 writer.cargo()[0].important_box().id().Write(255);
150 writer.cargo()[0].important_box().count().Write(10);
151 writer.cargo()[0].other_box().id().Write(2000000000);
152 writer.cargo()[0].other_box().count().Write(500);
153 writer.cargo()[1].weight().Write(101);
154 writer.cargo()[1].important_box().id().Write(254);
155 writer.cargo()[1].important_box().count().Write(9);
156 writer.cargo()[1].other_box().id().Write(2000000001);
157 writer.cargo()[1].other_box().count().Write(499);
158 EXPECT_EQ(::std::vector</**/ ::std::uint8_t>(kTruck, kTruck + sizeof kTruck),
159 ::std::vector</**/ ::std::uint8_t>(buffer, buffer + sizeof buffer));
160 }
161
TEST(TruckView,CanReadTextFormat)162 TEST(TruckView, CanReadTextFormat) {
163 ::std::uint8_t buffer[sizeof kTruck];
164 auto writer = TruckWriter(buffer, sizeof buffer);
165 EXPECT_TRUE(::emboss::UpdateFromText(writer, R"(
166 {
167 id: 0x22446688
168 cargo: {
169 {
170 weight: 100
171 important_box: {
172 id: 255
173 count: 10
174 }
175 other_box: {
176 id: 2_000_000_000
177 count: 500
178 }
179 },
180 {
181 weight: 101
182 important_box: {
183 id: 254
184 count: 9
185 }
186 other_box: {
187 id: 2_000_000_001
188 count: 499
189 }
190 },
191 }
192 }
193 )"));
194 EXPECT_EQ(::std::vector</**/ ::std::uint8_t>(kTruck, kTruck + sizeof kTruck),
195 ::std::vector</**/ ::std::uint8_t>(buffer, buffer + sizeof buffer));
196 }
197
198 } // namespace
199 } // namespace test
200 } // namespace emboss
201