xref: /aosp_15_r20/external/libtextclassifier/native/utils/lua-utils_test.cc (revision 993b0882672172b81d12fad7a7ac0c3e5c824a12)
1*993b0882SAndroid Build Coastguard Worker /*
2*993b0882SAndroid Build Coastguard Worker  * Copyright (C) 2018 The Android Open Source Project
3*993b0882SAndroid Build Coastguard Worker  *
4*993b0882SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*993b0882SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*993b0882SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*993b0882SAndroid Build Coastguard Worker  *
8*993b0882SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*993b0882SAndroid Build Coastguard Worker  *
10*993b0882SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*993b0882SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*993b0882SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*993b0882SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*993b0882SAndroid Build Coastguard Worker  * limitations under the License.
15*993b0882SAndroid Build Coastguard Worker  */
16*993b0882SAndroid Build Coastguard Worker 
17*993b0882SAndroid Build Coastguard Worker #include "utils/lua-utils.h"
18*993b0882SAndroid Build Coastguard Worker 
19*993b0882SAndroid Build Coastguard Worker #include <memory>
20*993b0882SAndroid Build Coastguard Worker #include <string>
21*993b0882SAndroid Build Coastguard Worker 
22*993b0882SAndroid Build Coastguard Worker #include "utils/flatbuffers/flatbuffers.h"
23*993b0882SAndroid Build Coastguard Worker #include "utils/flatbuffers/mutable.h"
24*993b0882SAndroid Build Coastguard Worker #include "utils/lua_utils_tests_generated.h"
25*993b0882SAndroid Build Coastguard Worker #include "utils/strings/stringpiece.h"
26*993b0882SAndroid Build Coastguard Worker #include "utils/test-data-test-utils.h"
27*993b0882SAndroid Build Coastguard Worker #include "utils/testing/test_data_generator.h"
28*993b0882SAndroid Build Coastguard Worker #include "gmock/gmock.h"
29*993b0882SAndroid Build Coastguard Worker #include "gtest/gtest.h"
30*993b0882SAndroid Build Coastguard Worker 
31*993b0882SAndroid Build Coastguard Worker namespace libtextclassifier3 {
32*993b0882SAndroid Build Coastguard Worker namespace {
33*993b0882SAndroid Build Coastguard Worker 
34*993b0882SAndroid Build Coastguard Worker using testing::DoubleEq;
35*993b0882SAndroid Build Coastguard Worker using testing::ElementsAre;
36*993b0882SAndroid Build Coastguard Worker using testing::Eq;
37*993b0882SAndroid Build Coastguard Worker using testing::FloatEq;
38*993b0882SAndroid Build Coastguard Worker 
39*993b0882SAndroid Build Coastguard Worker class LuaUtilsTest : public testing::Test, protected LuaEnvironment {
40*993b0882SAndroid Build Coastguard Worker  protected:
LuaUtilsTest()41*993b0882SAndroid Build Coastguard Worker   LuaUtilsTest()
42*993b0882SAndroid Build Coastguard Worker       : schema_(GetTestFileContent("utils/lua_utils_tests.bfbs")),
43*993b0882SAndroid Build Coastguard Worker         flatbuffer_builder_(schema_.get()) {
44*993b0882SAndroid Build Coastguard Worker     EXPECT_THAT(RunProtected([this] {
45*993b0882SAndroid Build Coastguard Worker                   LoadDefaultLibraries();
46*993b0882SAndroid Build Coastguard Worker                   return LUA_OK;
47*993b0882SAndroid Build Coastguard Worker                 }),
48*993b0882SAndroid Build Coastguard Worker                 Eq(LUA_OK));
49*993b0882SAndroid Build Coastguard Worker   }
50*993b0882SAndroid Build Coastguard Worker 
RunScript(StringPiece script)51*993b0882SAndroid Build Coastguard Worker   void RunScript(StringPiece script) {
52*993b0882SAndroid Build Coastguard Worker     EXPECT_THAT(luaL_loadbuffer(state_, script.data(), script.size(),
53*993b0882SAndroid Build Coastguard Worker                                 /*name=*/nullptr),
54*993b0882SAndroid Build Coastguard Worker                 Eq(LUA_OK));
55*993b0882SAndroid Build Coastguard Worker     EXPECT_THAT(
56*993b0882SAndroid Build Coastguard Worker         lua_pcall(state_, /*nargs=*/0, /*num_results=*/1, /*errfunc=*/0),
57*993b0882SAndroid Build Coastguard Worker         Eq(LUA_OK));
58*993b0882SAndroid Build Coastguard Worker   }
59*993b0882SAndroid Build Coastguard Worker 
60*993b0882SAndroid Build Coastguard Worker   OwnedFlatbuffer<reflection::Schema, std::string> schema_;
61*993b0882SAndroid Build Coastguard Worker   MutableFlatbufferBuilder flatbuffer_builder_;
62*993b0882SAndroid Build Coastguard Worker   TestDataGenerator test_data_generator_;
63*993b0882SAndroid Build Coastguard Worker };
64*993b0882SAndroid Build Coastguard Worker 
65*993b0882SAndroid Build Coastguard Worker template <typename T>
66*993b0882SAndroid Build Coastguard Worker class TypedLuaUtilsTest : public LuaUtilsTest {};
67*993b0882SAndroid Build Coastguard Worker 
68*993b0882SAndroid Build Coastguard Worker using testing::Types;
69*993b0882SAndroid Build Coastguard Worker using LuaTypes =
70*993b0882SAndroid Build Coastguard Worker     ::testing::Types<int64, uint64, int32, uint32, int16, uint16, int8, uint8,
71*993b0882SAndroid Build Coastguard Worker                      float, double, bool, std::string>;
72*993b0882SAndroid Build Coastguard Worker TYPED_TEST_SUITE(TypedLuaUtilsTest, LuaTypes);
73*993b0882SAndroid Build Coastguard Worker 
TYPED_TEST(TypedLuaUtilsTest,HandlesVectors)74*993b0882SAndroid Build Coastguard Worker TYPED_TEST(TypedLuaUtilsTest, HandlesVectors) {
75*993b0882SAndroid Build Coastguard Worker   std::vector<TypeParam> elements(5);
76*993b0882SAndroid Build Coastguard Worker   std::generate_n(elements.begin(), 5, [&]() {
77*993b0882SAndroid Build Coastguard Worker     return this->test_data_generator_.template generate<TypeParam>();
78*993b0882SAndroid Build Coastguard Worker   });
79*993b0882SAndroid Build Coastguard Worker 
80*993b0882SAndroid Build Coastguard Worker   this->PushVector(elements);
81*993b0882SAndroid Build Coastguard Worker 
82*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(this->template ReadVector<TypeParam>(),
83*993b0882SAndroid Build Coastguard Worker               testing::ContainerEq(elements));
84*993b0882SAndroid Build Coastguard Worker }
85*993b0882SAndroid Build Coastguard Worker 
TYPED_TEST(TypedLuaUtilsTest,HandlesVectorIterators)86*993b0882SAndroid Build Coastguard Worker TYPED_TEST(TypedLuaUtilsTest, HandlesVectorIterators) {
87*993b0882SAndroid Build Coastguard Worker   std::vector<TypeParam> elements(5);
88*993b0882SAndroid Build Coastguard Worker   std::generate_n(elements.begin(), 5, [&]() {
89*993b0882SAndroid Build Coastguard Worker     return this->test_data_generator_.template generate<TypeParam>();
90*993b0882SAndroid Build Coastguard Worker   });
91*993b0882SAndroid Build Coastguard Worker 
92*993b0882SAndroid Build Coastguard Worker   this->PushVectorIterator(&elements);
93*993b0882SAndroid Build Coastguard Worker 
94*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(this->template ReadVector<TypeParam>(),
95*993b0882SAndroid Build Coastguard Worker               testing::ContainerEq(elements));
96*993b0882SAndroid Build Coastguard Worker }
97*993b0882SAndroid Build Coastguard Worker 
TEST_F(LuaUtilsTest,IndexCallback)98*993b0882SAndroid Build Coastguard Worker TEST_F(LuaUtilsTest, IndexCallback) {
99*993b0882SAndroid Build Coastguard Worker   test::TestDataT input_data;
100*993b0882SAndroid Build Coastguard Worker   input_data.repeated_byte_field = {1, 2};
101*993b0882SAndroid Build Coastguard Worker   input_data.repeated_ubyte_field = {1, 2};
102*993b0882SAndroid Build Coastguard Worker   input_data.repeated_int_field = {1, 2};
103*993b0882SAndroid Build Coastguard Worker   input_data.repeated_uint_field = {1, 2};
104*993b0882SAndroid Build Coastguard Worker   input_data.repeated_long_field = {1, 2};
105*993b0882SAndroid Build Coastguard Worker   input_data.repeated_ulong_field = {1, 2};
106*993b0882SAndroid Build Coastguard Worker   input_data.repeated_bool_field = {true, false};
107*993b0882SAndroid Build Coastguard Worker   input_data.repeated_float_field = {1, 2};
108*993b0882SAndroid Build Coastguard Worker   input_data.repeated_double_field = {1, 2};
109*993b0882SAndroid Build Coastguard Worker   input_data.repeated_string_field = {"1", "2"};
110*993b0882SAndroid Build Coastguard Worker 
111*993b0882SAndroid Build Coastguard Worker   flatbuffers::FlatBufferBuilder builder;
112*993b0882SAndroid Build Coastguard Worker   builder.Finish(test::TestData::Pack(builder, &input_data));
113*993b0882SAndroid Build Coastguard Worker   const flatbuffers::DetachedBuffer input_buffer = builder.Release();
114*993b0882SAndroid Build Coastguard Worker   PushFlatbuffer(schema_.get(),
115*993b0882SAndroid Build Coastguard Worker                  flatbuffers::GetRoot<flatbuffers::Table>(input_buffer.data()));
116*993b0882SAndroid Build Coastguard Worker   lua_setglobal(state_, "arg");
117*993b0882SAndroid Build Coastguard Worker   // A Lua script that reads the vectors and return the first value of them.
118*993b0882SAndroid Build Coastguard Worker   // This should trigger the __index callback.
119*993b0882SAndroid Build Coastguard Worker   RunScript(R"lua(
120*993b0882SAndroid Build Coastguard Worker     return {
121*993b0882SAndroid Build Coastguard Worker         byte_field = arg.repeated_byte_field[1],
122*993b0882SAndroid Build Coastguard Worker         ubyte_field = arg.repeated_ubyte_field[1],
123*993b0882SAndroid Build Coastguard Worker         int_field = arg.repeated_int_field[1],
124*993b0882SAndroid Build Coastguard Worker         uint_field = arg.repeated_uint_field[1],
125*993b0882SAndroid Build Coastguard Worker         long_field = arg.repeated_long_field[1],
126*993b0882SAndroid Build Coastguard Worker         ulong_field = arg.repeated_ulong_field[1],
127*993b0882SAndroid Build Coastguard Worker         bool_field = arg.repeated_bool_field[1],
128*993b0882SAndroid Build Coastguard Worker         float_field = arg.repeated_float_field[1],
129*993b0882SAndroid Build Coastguard Worker         double_field = arg.repeated_double_field[1],
130*993b0882SAndroid Build Coastguard Worker         string_field = arg.repeated_string_field[1],
131*993b0882SAndroid Build Coastguard Worker     }
132*993b0882SAndroid Build Coastguard Worker   )lua");
133*993b0882SAndroid Build Coastguard Worker 
134*993b0882SAndroid Build Coastguard Worker   // Read the flatbuffer.
135*993b0882SAndroid Build Coastguard Worker   std::unique_ptr<MutableFlatbuffer> buffer = flatbuffer_builder_.NewRoot();
136*993b0882SAndroid Build Coastguard Worker   ReadFlatbuffer(/*index=*/-1, buffer.get());
137*993b0882SAndroid Build Coastguard Worker   const std::string serialized_buffer = buffer->Serialize();
138*993b0882SAndroid Build Coastguard Worker   std::unique_ptr<test::TestDataT> test_data =
139*993b0882SAndroid Build Coastguard Worker       LoadAndVerifyMutableFlatbuffer<test::TestData>(buffer->Serialize());
140*993b0882SAndroid Build Coastguard Worker 
141*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->byte_field, 1);
142*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->ubyte_field, 1);
143*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->int_field, 1);
144*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->uint_field, 1);
145*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->long_field, 1);
146*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->ulong_field, 1);
147*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->bool_field, true);
148*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->float_field, FloatEq(1));
149*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->double_field, DoubleEq(1));
150*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->string_field, "1");
151*993b0882SAndroid Build Coastguard Worker }
152*993b0882SAndroid Build Coastguard Worker 
TEST_F(LuaUtilsTest,PairCallback)153*993b0882SAndroid Build Coastguard Worker TEST_F(LuaUtilsTest, PairCallback) {
154*993b0882SAndroid Build Coastguard Worker   test::TestDataT input_data;
155*993b0882SAndroid Build Coastguard Worker   input_data.repeated_byte_field = {1, 2};
156*993b0882SAndroid Build Coastguard Worker   input_data.repeated_ubyte_field = {1, 2};
157*993b0882SAndroid Build Coastguard Worker   input_data.repeated_int_field = {1, 2};
158*993b0882SAndroid Build Coastguard Worker   input_data.repeated_uint_field = {1, 2};
159*993b0882SAndroid Build Coastguard Worker   input_data.repeated_long_field = {1, 2};
160*993b0882SAndroid Build Coastguard Worker   input_data.repeated_ulong_field = {1, 2};
161*993b0882SAndroid Build Coastguard Worker   input_data.repeated_bool_field = {true, false};
162*993b0882SAndroid Build Coastguard Worker   input_data.repeated_float_field = {1, 2};
163*993b0882SAndroid Build Coastguard Worker   input_data.repeated_double_field = {1, 2};
164*993b0882SAndroid Build Coastguard Worker   input_data.repeated_string_field = {"1", "2"};
165*993b0882SAndroid Build Coastguard Worker 
166*993b0882SAndroid Build Coastguard Worker   flatbuffers::FlatBufferBuilder builder;
167*993b0882SAndroid Build Coastguard Worker   builder.Finish(test::TestData::Pack(builder, &input_data));
168*993b0882SAndroid Build Coastguard Worker   const flatbuffers::DetachedBuffer input_buffer = builder.Release();
169*993b0882SAndroid Build Coastguard Worker   PushFlatbuffer(schema_.get(),
170*993b0882SAndroid Build Coastguard Worker                  flatbuffers::GetRoot<flatbuffers::Table>(input_buffer.data()));
171*993b0882SAndroid Build Coastguard Worker   lua_setglobal(state_, "arg");
172*993b0882SAndroid Build Coastguard Worker 
173*993b0882SAndroid Build Coastguard Worker   // Iterate the pushed repeated fields by using the pair API and check
174*993b0882SAndroid Build Coastguard Worker   // if the value is correct. This should trigger the __pair callback.
175*993b0882SAndroid Build Coastguard Worker   RunScript(R"lua(
176*993b0882SAndroid Build Coastguard Worker     function equal(table1, table2)
177*993b0882SAndroid Build Coastguard Worker       for key, value in pairs(table1) do
178*993b0882SAndroid Build Coastguard Worker           if value ~= table2[key] then
179*993b0882SAndroid Build Coastguard Worker               return false
180*993b0882SAndroid Build Coastguard Worker           end
181*993b0882SAndroid Build Coastguard Worker       end
182*993b0882SAndroid Build Coastguard Worker       return true
183*993b0882SAndroid Build Coastguard Worker     end
184*993b0882SAndroid Build Coastguard Worker 
185*993b0882SAndroid Build Coastguard Worker     local valid = equal(arg.repeated_byte_field, {[1]=1,[2]=2})
186*993b0882SAndroid Build Coastguard Worker     valid = valid and equal(arg.repeated_ubyte_field, {[1]=1,[2]=2})
187*993b0882SAndroid Build Coastguard Worker     valid = valid and equal(arg.repeated_int_field, {[1]=1,[2]=2})
188*993b0882SAndroid Build Coastguard Worker     valid = valid and equal(arg.repeated_uint_field, {[1]=1,[2]=2})
189*993b0882SAndroid Build Coastguard Worker     valid = valid and equal(arg.repeated_long_field, {[1]=1,[2]=2})
190*993b0882SAndroid Build Coastguard Worker     valid = valid and equal(arg.repeated_ulong_field, {[1]=1,[2]=2})
191*993b0882SAndroid Build Coastguard Worker     valid = valid and equal(arg.repeated_bool_field, {[1]=true,[2]=false})
192*993b0882SAndroid Build Coastguard Worker     valid = valid and equal(arg.repeated_float_field, {[1]=1,[2]=2})
193*993b0882SAndroid Build Coastguard Worker     valid = valid and equal(arg.repeated_double_field, {[1]=1,[2]=2})
194*993b0882SAndroid Build Coastguard Worker     valid = valid and equal(arg.repeated_string_field, {[1]="1",[2]="2"})
195*993b0882SAndroid Build Coastguard Worker 
196*993b0882SAndroid Build Coastguard Worker     return {
197*993b0882SAndroid Build Coastguard Worker         bool_field = valid
198*993b0882SAndroid Build Coastguard Worker     }
199*993b0882SAndroid Build Coastguard Worker   )lua");
200*993b0882SAndroid Build Coastguard Worker 
201*993b0882SAndroid Build Coastguard Worker   // Read the flatbuffer.
202*993b0882SAndroid Build Coastguard Worker   std::unique_ptr<MutableFlatbuffer> buffer = flatbuffer_builder_.NewRoot();
203*993b0882SAndroid Build Coastguard Worker   ReadFlatbuffer(/*index=*/-1, buffer.get());
204*993b0882SAndroid Build Coastguard Worker   const std::string serialized_buffer = buffer->Serialize();
205*993b0882SAndroid Build Coastguard Worker   std::unique_ptr<test::TestDataT> test_data =
206*993b0882SAndroid Build Coastguard Worker       LoadAndVerifyMutableFlatbuffer<test::TestData>(buffer->Serialize());
207*993b0882SAndroid Build Coastguard Worker 
208*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->bool_field, true);
209*993b0882SAndroid Build Coastguard Worker }
210*993b0882SAndroid Build Coastguard Worker 
TEST_F(LuaUtilsTest,PushAndReadsFlatbufferRoundTrip)211*993b0882SAndroid Build Coastguard Worker TEST_F(LuaUtilsTest, PushAndReadsFlatbufferRoundTrip) {
212*993b0882SAndroid Build Coastguard Worker   // Setup.
213*993b0882SAndroid Build Coastguard Worker   test::TestDataT input_data;
214*993b0882SAndroid Build Coastguard Worker   input_data.byte_field = 1;
215*993b0882SAndroid Build Coastguard Worker   input_data.ubyte_field = 2;
216*993b0882SAndroid Build Coastguard Worker   input_data.int_field = 10;
217*993b0882SAndroid Build Coastguard Worker   input_data.uint_field = 11;
218*993b0882SAndroid Build Coastguard Worker   input_data.long_field = 20;
219*993b0882SAndroid Build Coastguard Worker   input_data.ulong_field = 21;
220*993b0882SAndroid Build Coastguard Worker   input_data.bool_field = true;
221*993b0882SAndroid Build Coastguard Worker   input_data.float_field = 42.1;
222*993b0882SAndroid Build Coastguard Worker   input_data.double_field = 12.4;
223*993b0882SAndroid Build Coastguard Worker   input_data.string_field = "hello there";
224*993b0882SAndroid Build Coastguard Worker   // Nested field.
225*993b0882SAndroid Build Coastguard Worker   input_data.nested_field = std::make_unique<test::TestDataT>();
226*993b0882SAndroid Build Coastguard Worker   input_data.nested_field->float_field = 64;
227*993b0882SAndroid Build Coastguard Worker   input_data.nested_field->string_field = "hello nested";
228*993b0882SAndroid Build Coastguard Worker   // Repeated fields.
229*993b0882SAndroid Build Coastguard Worker   input_data.repeated_byte_field = {1, 2, 1};
230*993b0882SAndroid Build Coastguard Worker   input_data.repeated_byte_field = {1, 2, 1};
231*993b0882SAndroid Build Coastguard Worker   input_data.repeated_ubyte_field = {2, 4, 2};
232*993b0882SAndroid Build Coastguard Worker   input_data.repeated_int_field = {1, 2, 3};
233*993b0882SAndroid Build Coastguard Worker   input_data.repeated_uint_field = {2, 4, 6};
234*993b0882SAndroid Build Coastguard Worker   input_data.repeated_long_field = {4, 5, 6};
235*993b0882SAndroid Build Coastguard Worker   input_data.repeated_ulong_field = {8, 10, 12};
236*993b0882SAndroid Build Coastguard Worker   input_data.repeated_bool_field = {true, false, true};
237*993b0882SAndroid Build Coastguard Worker   input_data.repeated_float_field = {1.23, 2.34, 3.45};
238*993b0882SAndroid Build Coastguard Worker   input_data.repeated_double_field = {1.11, 2.22, 3.33};
239*993b0882SAndroid Build Coastguard Worker   input_data.repeated_string_field = {"a", "bold", "one"};
240*993b0882SAndroid Build Coastguard Worker   // Repeated nested fields.
241*993b0882SAndroid Build Coastguard Worker   input_data.repeated_nested_field.push_back(
242*993b0882SAndroid Build Coastguard Worker       std::make_unique<test::TestDataT>());
243*993b0882SAndroid Build Coastguard Worker   input_data.repeated_nested_field.back()->string_field = "a";
244*993b0882SAndroid Build Coastguard Worker   input_data.repeated_nested_field.push_back(
245*993b0882SAndroid Build Coastguard Worker       std::make_unique<test::TestDataT>());
246*993b0882SAndroid Build Coastguard Worker   input_data.repeated_nested_field.back()->string_field = "b";
247*993b0882SAndroid Build Coastguard Worker   input_data.repeated_nested_field.push_back(
248*993b0882SAndroid Build Coastguard Worker       std::make_unique<test::TestDataT>());
249*993b0882SAndroid Build Coastguard Worker   input_data.repeated_nested_field.back()->repeated_string_field = {"nested",
250*993b0882SAndroid Build Coastguard Worker                                                                     "nested2"};
251*993b0882SAndroid Build Coastguard Worker   flatbuffers::FlatBufferBuilder builder;
252*993b0882SAndroid Build Coastguard Worker   builder.Finish(test::TestData::Pack(builder, &input_data));
253*993b0882SAndroid Build Coastguard Worker   const flatbuffers::DetachedBuffer input_buffer = builder.Release();
254*993b0882SAndroid Build Coastguard Worker   PushFlatbuffer(schema_.get(),
255*993b0882SAndroid Build Coastguard Worker                  flatbuffers::GetRoot<flatbuffers::Table>(input_buffer.data()));
256*993b0882SAndroid Build Coastguard Worker   lua_setglobal(state_, "arg");
257*993b0882SAndroid Build Coastguard Worker 
258*993b0882SAndroid Build Coastguard Worker   RunScript(R"lua(
259*993b0882SAndroid Build Coastguard Worker     return {
260*993b0882SAndroid Build Coastguard Worker         byte_field = arg.byte_field,
261*993b0882SAndroid Build Coastguard Worker         ubyte_field = arg.ubyte_field,
262*993b0882SAndroid Build Coastguard Worker         int_field = arg.int_field,
263*993b0882SAndroid Build Coastguard Worker         uint_field = arg.uint_field,
264*993b0882SAndroid Build Coastguard Worker         long_field = arg.long_field,
265*993b0882SAndroid Build Coastguard Worker         ulong_field = arg.ulong_field,
266*993b0882SAndroid Build Coastguard Worker         bool_field = arg.bool_field,
267*993b0882SAndroid Build Coastguard Worker         float_field = arg.float_field,
268*993b0882SAndroid Build Coastguard Worker         double_field = arg.double_field,
269*993b0882SAndroid Build Coastguard Worker         string_field = arg.string_field,
270*993b0882SAndroid Build Coastguard Worker         nested_field = {
271*993b0882SAndroid Build Coastguard Worker           float_field = arg.nested_field.float_field,
272*993b0882SAndroid Build Coastguard Worker           string_field = arg.nested_field.string_field,
273*993b0882SAndroid Build Coastguard Worker         },
274*993b0882SAndroid Build Coastguard Worker         repeated_byte_field = arg.repeated_byte_field,
275*993b0882SAndroid Build Coastguard Worker         repeated_ubyte_field = arg.repeated_ubyte_field,
276*993b0882SAndroid Build Coastguard Worker         repeated_int_field = arg.repeated_int_field,
277*993b0882SAndroid Build Coastguard Worker         repeated_uint_field = arg.repeated_uint_field,
278*993b0882SAndroid Build Coastguard Worker         repeated_long_field = arg.repeated_long_field,
279*993b0882SAndroid Build Coastguard Worker         repeated_ulong_field = arg.repeated_ulong_field,
280*993b0882SAndroid Build Coastguard Worker         repeated_bool_field = arg.repeated_bool_field,
281*993b0882SAndroid Build Coastguard Worker         repeated_float_field = arg.repeated_float_field,
282*993b0882SAndroid Build Coastguard Worker         repeated_double_field = arg.repeated_double_field,
283*993b0882SAndroid Build Coastguard Worker         repeated_string_field = arg.repeated_string_field,
284*993b0882SAndroid Build Coastguard Worker         repeated_nested_field = {
285*993b0882SAndroid Build Coastguard Worker           { string_field = arg.repeated_nested_field[1].string_field },
286*993b0882SAndroid Build Coastguard Worker           { string_field = arg.repeated_nested_field[2].string_field },
287*993b0882SAndroid Build Coastguard Worker           { repeated_string_field = arg.repeated_nested_field[3].repeated_string_field },
288*993b0882SAndroid Build Coastguard Worker         },
289*993b0882SAndroid Build Coastguard Worker     }
290*993b0882SAndroid Build Coastguard Worker   )lua");
291*993b0882SAndroid Build Coastguard Worker 
292*993b0882SAndroid Build Coastguard Worker   // Read the flatbuffer.
293*993b0882SAndroid Build Coastguard Worker   std::unique_ptr<MutableFlatbuffer> buffer = flatbuffer_builder_.NewRoot();
294*993b0882SAndroid Build Coastguard Worker   ReadFlatbuffer(/*index=*/-1, buffer.get());
295*993b0882SAndroid Build Coastguard Worker   const std::string serialized_buffer = buffer->Serialize();
296*993b0882SAndroid Build Coastguard Worker   std::unique_ptr<test::TestDataT> test_data =
297*993b0882SAndroid Build Coastguard Worker       LoadAndVerifyMutableFlatbuffer<test::TestData>(buffer->Serialize());
298*993b0882SAndroid Build Coastguard Worker 
299*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->byte_field, 1);
300*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->ubyte_field, 2);
301*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->int_field, 10);
302*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->uint_field, 11);
303*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->long_field, 20);
304*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->ulong_field, 21);
305*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->bool_field, true);
306*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->float_field, FloatEq(42.1));
307*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->double_field, DoubleEq(12.4));
308*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->string_field, "hello there");
309*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->repeated_byte_field, ElementsAre(1, 2, 1));
310*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->repeated_ubyte_field, ElementsAre(2, 4, 2));
311*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->repeated_int_field, ElementsAre(1, 2, 3));
312*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->repeated_uint_field, ElementsAre(2, 4, 6));
313*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->repeated_long_field, ElementsAre(4, 5, 6));
314*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->repeated_ulong_field, ElementsAre(8, 10, 12));
315*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->repeated_bool_field, ElementsAre(true, false, true));
316*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->repeated_float_field, ElementsAre(1.23, 2.34, 3.45));
317*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->repeated_double_field, ElementsAre(1.11, 2.22, 3.33));
318*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->repeated_string_field,
319*993b0882SAndroid Build Coastguard Worker               ElementsAre("a", "bold", "one"));
320*993b0882SAndroid Build Coastguard Worker   // Nested fields.
321*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->nested_field->float_field, FloatEq(64));
322*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->nested_field->string_field, "hello nested");
323*993b0882SAndroid Build Coastguard Worker   // Repeated nested fields.
324*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->repeated_nested_field[0]->string_field, "a");
325*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->repeated_nested_field[1]->string_field, "b");
326*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(test_data->repeated_nested_field[2]->repeated_string_field,
327*993b0882SAndroid Build Coastguard Worker               ElementsAre("nested", "nested2"));
328*993b0882SAndroid Build Coastguard Worker }
329*993b0882SAndroid Build Coastguard Worker 
TEST_F(LuaUtilsTest,HandlesRepeatedNestedFlatbufferFields)330*993b0882SAndroid Build Coastguard Worker TEST_F(LuaUtilsTest, HandlesRepeatedNestedFlatbufferFields) {
331*993b0882SAndroid Build Coastguard Worker   // Create test flatbuffer.
332*993b0882SAndroid Build Coastguard Worker   std::unique_ptr<MutableFlatbuffer> buffer = flatbuffer_builder_.NewRoot();
333*993b0882SAndroid Build Coastguard Worker   RepeatedField* repeated_field = buffer->Repeated("repeated_nested_field");
334*993b0882SAndroid Build Coastguard Worker   repeated_field->Add()->Set("string_field", "hello");
335*993b0882SAndroid Build Coastguard Worker   repeated_field->Add()->Set("string_field", "my");
336*993b0882SAndroid Build Coastguard Worker   MutableFlatbuffer* nested = repeated_field->Add();
337*993b0882SAndroid Build Coastguard Worker   nested->Set("string_field", "old");
338*993b0882SAndroid Build Coastguard Worker   RepeatedField* nested_repeated = nested->Repeated("repeated_string_field");
339*993b0882SAndroid Build Coastguard Worker   nested_repeated->Add("friend");
340*993b0882SAndroid Build Coastguard Worker   nested_repeated->Add("how");
341*993b0882SAndroid Build Coastguard Worker   nested_repeated->Add("are");
342*993b0882SAndroid Build Coastguard Worker   repeated_field->Add()->Set("string_field", "you?");
343*993b0882SAndroid Build Coastguard Worker   const std::string serialized_buffer = buffer->Serialize();
344*993b0882SAndroid Build Coastguard Worker   PushFlatbuffer(schema_.get(), flatbuffers::GetRoot<flatbuffers::Table>(
345*993b0882SAndroid Build Coastguard Worker                                     serialized_buffer.data()));
346*993b0882SAndroid Build Coastguard Worker   lua_setglobal(state_, "arg");
347*993b0882SAndroid Build Coastguard Worker 
348*993b0882SAndroid Build Coastguard Worker   RunScript(R"lua(
349*993b0882SAndroid Build Coastguard Worker     result = {}
350*993b0882SAndroid Build Coastguard Worker     for _, nested in pairs(arg.repeated_nested_field) do
351*993b0882SAndroid Build Coastguard Worker       result[#result + 1] = nested.string_field
352*993b0882SAndroid Build Coastguard Worker       for _, nested_string in pairs(nested.repeated_string_field) do
353*993b0882SAndroid Build Coastguard Worker         result[#result + 1] = nested_string
354*993b0882SAndroid Build Coastguard Worker       end
355*993b0882SAndroid Build Coastguard Worker     end
356*993b0882SAndroid Build Coastguard Worker     return result
357*993b0882SAndroid Build Coastguard Worker   )lua");
358*993b0882SAndroid Build Coastguard Worker 
359*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(
360*993b0882SAndroid Build Coastguard Worker       ReadVector<std::string>(),
361*993b0882SAndroid Build Coastguard Worker       ElementsAre("hello", "my", "old", "friend", "how", "are", "you?"));
362*993b0882SAndroid Build Coastguard Worker }
363*993b0882SAndroid Build Coastguard Worker 
TEST_F(LuaUtilsTest,CorrectlyReadsTwoFlatbuffersSimultaneously)364*993b0882SAndroid Build Coastguard Worker TEST_F(LuaUtilsTest, CorrectlyReadsTwoFlatbuffersSimultaneously) {
365*993b0882SAndroid Build Coastguard Worker   // The first flatbuffer.
366*993b0882SAndroid Build Coastguard Worker   std::unique_ptr<MutableFlatbuffer> buffer = flatbuffer_builder_.NewRoot();
367*993b0882SAndroid Build Coastguard Worker   buffer->Set("string_field", "first");
368*993b0882SAndroid Build Coastguard Worker   const std::string serialized_buffer = buffer->Serialize();
369*993b0882SAndroid Build Coastguard Worker   PushFlatbuffer(schema_.get(), flatbuffers::GetRoot<flatbuffers::Table>(
370*993b0882SAndroid Build Coastguard Worker                                     serialized_buffer.data()));
371*993b0882SAndroid Build Coastguard Worker   lua_setglobal(state_, "arg");
372*993b0882SAndroid Build Coastguard Worker   // The second flatbuffer.
373*993b0882SAndroid Build Coastguard Worker   std::unique_ptr<MutableFlatbuffer> buffer2 = flatbuffer_builder_.NewRoot();
374*993b0882SAndroid Build Coastguard Worker   buffer2->Set("string_field", "second");
375*993b0882SAndroid Build Coastguard Worker   const std::string serialized_buffer2 = buffer2->Serialize();
376*993b0882SAndroid Build Coastguard Worker   PushFlatbuffer(schema_.get(), flatbuffers::GetRoot<flatbuffers::Table>(
377*993b0882SAndroid Build Coastguard Worker                                     serialized_buffer2.data()));
378*993b0882SAndroid Build Coastguard Worker   lua_setglobal(state_, "arg2");
379*993b0882SAndroid Build Coastguard Worker 
380*993b0882SAndroid Build Coastguard Worker   RunScript(R"lua(
381*993b0882SAndroid Build Coastguard Worker     return {arg.string_field, arg2.string_field}
382*993b0882SAndroid Build Coastguard Worker   )lua");
383*993b0882SAndroid Build Coastguard Worker 
384*993b0882SAndroid Build Coastguard Worker   EXPECT_THAT(ReadVector<std::string>(), ElementsAre("first", "second"));
385*993b0882SAndroid Build Coastguard Worker }
386*993b0882SAndroid Build Coastguard Worker 
387*993b0882SAndroid Build Coastguard Worker }  // namespace
388*993b0882SAndroid Build Coastguard Worker }  // namespace libtextclassifier3
389