@@ -42,6 +42,41 @@ return {
4242 end,
4343 print = print,
4444
45+ iteratePlain = function()
46+ local sum = 0
47+ for k, v in pairs({a = 1, b = 2, c = 3}) do sum = sum + v end
48+ for i, v in ipairs({10, 20, 30}) do sum = sum + v end
49+ return sum
50+ end,
51+ honoursCustomPairs = function()
52+ local t = setmetatable({}, { __pairs = function(v) return next, {z = 9}, nil end })
53+ local sum = 0
54+ for k, v in pairs(t) do sum = sum + v end
55+ return sum
56+ end,
57+ iterateHiddenMetatable = function()
58+ local t = setmetatable({a = 1, b = 2}, { __metatable = false })
59+ local sum = 0
60+ for k, v in pairs(t) do sum = sum + v end
61+ for i, v in ipairs(setmetatable({7, 8}, { __metatable = false })) do sum = sum + v end
62+ return sum
63+ end,
64+ iterateReadOnly = function(t)
65+ local keys, sum = {}, 0
66+ for k, v in pairs(t) do keys[#keys + 1] = k; sum = sum + v end
67+ table.sort(keys)
68+ return table.concat(keys, ','), sum, #t
69+ end,
70+ iterateReadOnlyArray = function(t)
71+ local sum = 0
72+ for i, v in ipairs(t) do sum = sum + v end
73+ return sum, #t
74+ end,
75+ readOnlyIterationStateIsGuarded = function(t)
76+ local _, state = pairs(t)
77+ return rawequal(state, t)
78+ end,
79+
4580 -- should throw an error
4681 incorrectRequire = function() require('counter') end,
4782 modifySystemLib = function() math.sin = 5 end,
@@ -181,6 +216,32 @@ return {
181216 EXPECT_EQ (LuaUtil::getMutableFromReadOnly (LuaUtil::makeReadOnly (script)), script);
182217 }
183218
219+ TEST_F (LuaStateTest, Iteration)
220+ {
221+ const VFS ::Path::Normalized path (" bbb/tests.lua" );
222+ sol::table script = mLua .runInNewSandbox (path);
223+
224+ EXPECT_EQ (LuaUtil::call (script[" iteratePlain" ]).get <int >(), 66 );
225+ EXPECT_EQ (LuaUtil::call (script[" honoursCustomPairs" ]).get <int >(), 9 );
226+ EXPECT_EQ (LuaUtil::call (script[" iterateHiddenMetatable" ]).get <int >(), 18 );
227+
228+ mLua .protectedCall ([&](LuaUtil::LuaView& view) {
229+ sol::table hash = LuaUtil::makeReadOnly (view.sol ().create_table_with (" a" , 1 , " b" , 2 , " c" , 3 ));
230+ sol::table array = LuaUtil::makeReadOnly (view.sol ().create_table_with (1 , 10 , 2 , 20 , 3 , 30 ));
231+
232+ auto readOnly = LuaUtil::call (script[" iterateReadOnly" ], hash);
233+ EXPECT_EQ (readOnly.get <std::string>(0 ), " a,b,c" );
234+ EXPECT_EQ (readOnly.get <int >(1 ), 6 );
235+ EXPECT_EQ (readOnly.get <int >(2 ), 0 );
236+
237+ auto readOnlyArray = LuaUtil::call (script[" iterateReadOnlyArray" ], array);
238+ EXPECT_EQ (readOnlyArray.get <int >(0 ), 60 );
239+ EXPECT_EQ (readOnlyArray.get <int >(1 ), 3 );
240+
241+ EXPECT_TRUE (LuaUtil::call (script[" readOnlyIterationStateIsGuarded" ], hash).get <bool >());
242+ });
243+ }
244+
184245 TEST_F (LuaStateTest, Print)
185246 {
186247 const VFS ::Path::Normalized path (" bbb/tests.lua" );
0 commit comments