From a4d36b89df1d380c693a9dca6984ef0ce5023cf0 Mon Sep 17 00:00:00 2001 From: Oscar Lim Date: Sun, 19 Jul 2015 23:34:51 -0700 Subject: [PATCH] Fix deepcompare with __pairs This uses `next, t` instead of `pairs(t)` to iterate through a table so that the `__pairs` metamethod is not used. --- spec/assertions_spec.lua | 7 +++++++ src/util.lua | 8 ++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/spec/assertions_spec.lua b/spec/assertions_spec.lua index a829625..a3932fb 100644 --- a/spec/assertions_spec.lua +++ b/spec/assertions_spec.lua @@ -45,6 +45,13 @@ describe("Test Assertions", function() assert.is_not.same(nil, "a string") end) + it("Checks same() assertion ignores __pairs metamethod", function() + local t1 = setmetatable({1,2,3}, {__pairs = function(t) return nil end}) + local t2 = {1,2,3} + assert.same(t1, t2) + assert.same(t2, t1) + end) + it("Checks same() assertion to handle recursive tables", function() local t1 = { k1 = 1, k2 = 2 } local t2 = { k1 = 1, k2 = 2 } diff --git a/src/util.lua b/src/util.lua index d414b1f..6402380 100644 --- a/src/util.lua +++ b/src/util.lua @@ -30,7 +30,7 @@ function util.deepcompare(t1,t2,ignore_mt,cycles,thresh1,thresh2) cycles[1][t1] = cycles[1][t1] + 1 cycles[2][t2] = cycles[2][t2] + 1 - for k1,v1 in pairs(t1) do + for k1,v1 in next, t1 do local v2 = t2[k1] if v2 == nil then return false, {k1} @@ -43,7 +43,7 @@ function util.deepcompare(t1,t2,ignore_mt,cycles,thresh1,thresh2) return false, crumbs end end - for k2,_ in pairs(t2) do + for k2,_ in next, t2 do -- only check wether each element has a t1 counterpart, actual comparison -- has been done in first loop above if t1[k2] == nil then return false, {k2} end @@ -58,7 +58,7 @@ end function util.shallowcopy(t) if type(t) ~= "table" then return t end local copy = {} - for k,v in next, t, nil do + for k,v in next, t do copy[k] = v end return copy @@ -74,7 +74,7 @@ function util.deepcopy(t, deepmt, cache) if cache[t] then return cache[t] end cache[t] = copy - for k,v in next, t, nil do + for k,v in next, t do copy[k] = (spy.is_spy(v) and v or util.deepcopy(v, deepmt, cache)) end if deepmt then