From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from [87.239.111.99] (localhost [127.0.0.1]) by dev.tarantool.org (Postfix) with ESMTP id E718A6EC41; Fri, 13 Aug 2021 02:34:15 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org E718A6EC41 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1628811256; bh=kvws5ksyhLa7jxaHxy33MzReRD8zaLemvqJk0ds0gwE=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=AUkSIfCxGELVk7BDSS0Cu0AfxThRndFumvOPIbUCzvPfxmLHNbzHdRuLJK5uLWZsS PQBGhtGRYUZSvwyXECPxbeE+bTUqKxATAh2E/TS6JpKMDyNLvbkbxGwVLHtDXZm9sR uAG1oT1UI3G5F0pScg9xzAClVQjgxBzcX4BwsNa4= Received: from smtp29.i.mail.ru (smtp29.i.mail.ru [94.100.177.89]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id AB3416EC40 for ; Fri, 13 Aug 2021 02:34:14 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org AB3416EC40 Received: by smtp29.i.mail.ru with esmtpa (envelope-from ) id 1mEKDF-0002HX-Jt; Fri, 13 Aug 2021 02:34:13 +0300 To: vdavydov@tarantool.org, sergos@tarantool.org Date: Fri, 13 Aug 2021 02:30:31 +0300 Message-Id: <3a954f7793e6356cefb8cd0151a6434382ec876c.1628810253.git.sergepetrenko@tarantool.org> X-Mailer: git-send-email 2.30.1 (Apple Git-130) In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-4EC0790: 10 X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD92087353F0EC44DD906AB4890CDABF0C5CB76CEE71D3E4007182A05F538085040783B2D0FC12A024DFBCD85838BAA4B568A54887E9498B647520049A17AD80AEB X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE7AB5815F4DE05345AEA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F790063738C1CCEC8FAC1CB98638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D861BDBFAEEDCA3C548C2F0A71AB495BD4117882F4460429724CE54428C33FAD305F5C1EE8F4F765FC2EE5AD8F952D28FBA471835C12D1D9774AD6D5ED66289B52BA9C0B312567BB23117882F446042972877693876707352033AC447995A7AD18E5D25F19253116ADD2E47CDBA5A96583BA9C0B312567BB231DD303D21008E29813377AFFFEAFD269A417C69337E82CC2E827F84554CEF50127C277FBC8AE2E8BA83251EDC214901ED5E8D9A59859A8B6D75B66E98413B381089D37D7C0E48F6C5571747095F342E88FB05168BE4CE3AF X-B7AD71C0: AC4F5C86D027EB782CDD5689AFBDA7A213B5FB47DCBC3458834459D11680B505DD70C060F881B3E53D39712A27491658 X-C1DE0DAB: C20DE7B7AB408E4181F030C43753B8186998911F362727C414F749A5E30D975C69415AB31670C86C140D1ECE3C317441D3626F53CAC8C26E9C2B6934AE262D3EE7EAB7254005DCED7532B743992DF240BDC6A1CF3F042BAD6DF99611D93F60EF3A74CE74F45F2162699F904B3F4130E343918A1A30D5E7FCCB5012B2E24CD356 X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D340A59E724FC7897F77C427A1D3E14C17610F81ECF93C6A5F23C4A4D62CA833E37609BC622890F65291D7E09C32AA3244C3FD89921999F76DF40CD1CD13E36D077BBA718C7E6A9E042927AC6DF5659F194 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2bioj0dLV0c3jbkxEJRMmYorWpw== X-Mailru-Sender: 3B9A0136629DC9125D61937A2360A446DB3F70C9C6E6E990E3996B0A2729B426657A256D324E2144424AE0EB1F3D1D21E2978F233C3FAE6EE63DB1732555E4A8EE80603BA4A5B0BC112434F685709FCF0DA7A0AF5A3A8387 X-Mras: Ok Subject: [Tarantool-patches] [PATCH v2 1/2] lua: introduce table.equals method X-BeenThere: tarantool-patches@dev.tarantool.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Serge Petrenko via Tarantool-patches Reply-To: Serge Petrenko Cc: tarantool-patches@dev.tarantool.org Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" Introduce table.equals for comparing tables. The method respects __eq metamethod, if provided. Needed-for #5894 --- src/lua/table.lua | 26 ++++++++++++++++++++++++++ test/app-tap/table.test.lua | 31 ++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/lua/table.lua b/src/lua/table.lua index 8fa9b876a..5f35a30f6 100644 --- a/src/lua/table.lua +++ b/src/lua/table.lua @@ -57,6 +57,31 @@ local function table_shallowcopy(orig) return copy end +--- Compare two lua tables +-- Supports __eq metamethod for comparing custom tables with metatables +-- @function equals +-- @return true when the two tables are equal (false otherwise). +local function table_equals(a, b) + if type(a) ~= 'table' or type(b) ~= 'table' then + return a == b + end + local mt = getmetatable(a) + if mt and mt.__eq then + return a == b + end + for k, v in pairs(a) do + if not table_equals(v, b[k]) then + return false + end + end + for k, _ in pairs(b) do + if not a[k] then + return false + end + end + return true +end + -- table library extension local table = require('table') -- require modifies global "table" module and adds "clear" function to it. @@ -65,3 +90,4 @@ require('table.clear') table.copy = table_shallowcopy table.deepcopy = table_deepcopy +table.equals = table_equals diff --git a/test/app-tap/table.test.lua b/test/app-tap/table.test.lua index 60c095fdf..a3c9aa123 100755 --- a/test/app-tap/table.test.lua +++ b/test/app-tap/table.test.lua @@ -8,7 +8,7 @@ yaml.cfg{ encode_invalid_as_nil = true, } local test = require('tap').test('table') -test:plan(31) +test:plan(38) do -- check basic table.copy (deepcopy) local example_table = { @@ -223,4 +223,33 @@ do -- check usage of not __copy metamethod on second level + shallow ) end +do -- check table.equals + test:ok(table.equals({}, {}), "table.equals for empty tables") + test:is(table.equals({}, {1}), false, "table.equals with one empty table") + test:is(table.equals({1}, {}), false, "table.equals with one empty table") + local tbl_a = { + first = { + 1, + 2, + {}, + }, + second = { + a = { + {'something'}, + }, + b = 'something else', + }, + [3] = 'some value', + } + local tbl_b = table.deepcopy(tbl_a) + local tbl_c = table.copy(tbl_a) + test:ok(table.equals(tbl_a, tbl_b), "table.equals for complex tables") + test:ok(table.equals(tbl_a, tbl_c), + "table.equals for shallow copied tables") + tbl_c.second.a = 'other thing' + test:ok(table.equals(tbl_a, tbl_c), + "table.equals for shallow copied tables after modification") + test:is(table.equals(tbl_a, tbl_b), false, "table.equals does a deep check") +end + os.exit(test:check() == true and 0 or 1) -- 2.30.1 (Apple Git-130)