1--SPDX-License-Identifier: MIT 2--[[ 3--***************************************************************************** 4--* Copyright (C) 1994-2016 Lua.org, PUC-Rio. 5--* 6--* Permission is hereby granted, free of charge, to any person obtaining 7--* a copy of this software and associated documentation files (the 8--* "Software"), to deal in the Software without restriction, including 9--* without limitation the rights to use, copy, modify, merge, publish, 10--* distribute, sublicense, and/or sell copies of the Software, and to 11--* permit persons to whom the Software is furnished to do so, subject to 12--* the following conditions: 13--* 14--* The above copyright notice and this permission notice shall be 15--* included in all copies or substantial portions of the Software. 16--* 17--* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18--* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19--* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20--* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21--* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22--* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23--* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24--***************************************************************************** 25--]] 26 27-- testing table library 28 29-- workaround missing pcall in zfs lua implementation 30local function tuple(...) 31 return {n=select('#', ...), ...} 32end 33 34function pcall(f, ...) 35 local co = coroutine.create(f) 36 local res = tuple(coroutine.resume(co, ...)) 37 if res[1] and coroutine.status(co) == "suspended" then 38 res[1] = false 39 end 40 return table.unpack(res, 1, res.n) 41end 42 43 44-- workaround missing math lib in zfs lua implementation 45local A1, A2 = 727595, 798405 -- 5^17=D20*A1+A2 46local D20, D40 = 1048576, 1099511627776 -- 2^20, 2^40 47local X1, X2 = 0, 1 48function rand() 49 local U = X2*A2 50 local V = (X1*A2 + X2*A1) % D20 51 V = (V*D20 + U) % D40 52 X1 = V/D20 53 X2 = V - X1*D20 54 return V*100/D40 55end 56 57 58-- testing unpack 59 60local unpack = table.unpack 61 62local x,y,z,a,n 63a = {}; lim = 2000 64for i=1, lim do a[i]=i end 65assert(select(lim, unpack(a)) == lim and select('#', unpack(a)) == lim) 66x = unpack(a) 67assert(x == 1) 68x = {unpack(a)} 69assert(#x == lim and x[1] == 1 and x[lim] == lim) 70x = {unpack(a, lim-2)} 71assert(#x == 3 and x[1] == lim-2 and x[3] == lim) 72x = {unpack(a, 10, 6)} 73assert(next(x) == nil) -- no elements 74x = {unpack(a, 11, 10)} 75assert(next(x) == nil) -- no elements 76x,y = unpack(a, 10, 10) 77assert(x == 10 and y == nil) 78x,y,z = unpack(a, 10, 11) 79assert(x == 10 and y == 11 and z == nil) 80a,x = unpack{1} 81assert(a==1 and x==nil) 82a,x = unpack({1,2}, 1, 1) 83assert(a==1 and x==nil) 84 85if not _no32 then 86 assert(not pcall(unpack, {}, 0, 2^31-1)) 87 assert(not pcall(unpack, {}, 1, 2^31-1)) 88 assert(not pcall(unpack, {}, -(2^31), 2^31-1)) 89 assert(not pcall(unpack, {}, -(2^31 - 1), 2^31-1)) 90 assert(pcall(unpack, {}, 2^31-1, 0)) 91 assert(pcall(unpack, {}, 2^31-1, 1)) 92 pcall(unpack, {}, 1, 2^31) 93 a, b = unpack({[2^31-1] = 20}, 2^31-1, 2^31-1) 94 assert(a == 20 and b == nil) 95 a, b = unpack({[2^31-1] = 20}, 2^31-2, 2^31-1) 96 assert(a == nil and b == 20) 97end 98 99-- testing pack 100 101a = table.pack() 102assert(a[1] == nil and a.n == 0) 103 104a = table.pack(table) 105assert(a[1] == table and a.n == 1) 106 107a = table.pack(nil, nil, nil, nil) 108assert(a[1] == nil and a.n == 4) 109 110 111-- testing sort 112 113 114-- test checks for invalid order functions 115local function check (t) 116 local function f(a, b) assert(a and b); return true end 117 local s, e = pcall(table.sort, t, f) 118 assert(not s and e:find("invalid order function")) 119end 120 121check{1,2,3,4} 122check{1,2,3,4,5} 123check{1,2,3,4,5,6} 124 125 126function check (a, f) 127 f = f or function (x,y) return x<y end; 128 for n = #a, 2, -1 do 129 assert(not f(a[n], a[n-1])) 130 end 131end 132 133a = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", 134 "Oct", "Nov", "Dec"} 135 136table.sort(a) 137check(a) 138 139function perm (s, n) 140 n = n or #s 141 if n == 1 then 142 local t = {unpack(s)} 143 table.sort(t) 144 check(t) 145 else 146 for i = 1, n do 147 s[i], s[n] = s[n], s[i] 148 perm(s, n - 1) 149 s[i], s[n] = s[n], s[i] 150 end 151 end 152end 153 154perm{} 155perm{1} 156perm{1,2} 157perm{1,2,3} 158perm{1,2,3,4} 159perm{2,2,3,4} 160perm{1,2,3,4,5} 161perm{1,2,3,3,5} 162perm{1,2,3,4,5,6} 163perm{2,2,3,3,5,6} 164 165limit = 5000 166 167a = {} 168for i=1,limit do 169 a[i] = rand() 170end 171 172table.sort(a) 173check(a) 174 175table.sort(a) 176check(a) 177 178a = {} 179for i=1,limit do 180 a[i] = rand() 181end 182 183i=0 184table.sort(a, function(x,y) i=i+1; return y<x end) 185check(a, function(x,y) return y<x end) 186 187 188table.sort{} -- empty array 189 190for i=1,limit do a[i] = false end 191table.sort(a, function(x,y) return nil end) 192check(a, function(x,y) return nil end) 193for i,v in pairs(a) do assert(not v or i=='n' and v==limit) end 194 195A = {"�lo", "\0first :-)", "alo", "then this one", "45", "and a new"} 196table.sort(A) 197check(A) 198 199tt = {__lt = function (a,b) return a.val < b.val end} 200a = {} 201for i=1,10 do a[i] = {val=rand(100)}; setmetatable(a[i], tt); end 202table.sort(a) 203check(a, tt.__lt) 204check(a) 205 206 207-- test remove 208local function test (a) 209 table.insert(a, 10); table.insert(a, 2, 20); 210 table.insert(a, 1, -1); table.insert(a, 40); 211 table.insert(a, #a+1, 50) 212 table.insert(a, 2, -2) 213 assert(table.remove(a,1) == -1) 214 assert(table.remove(a,1) == -2) 215 assert(table.remove(a,1) == 10) 216 assert(table.remove(a,1) == 20) 217 assert(table.remove(a,1) == 40) 218 assert(table.remove(a,1) == 50) 219 assert(table.remove(a,1) == nil) 220end 221 222a = {n=0, [-7] = "ban"} 223test(a) 224assert(a.n == 0 and a[-7] == "ban") 225 226a = {[-7] = "ban"}; 227test(a) 228assert(a.n == nil and #a == 0 and a[-7] == "ban") 229 230 231table.insert(a, 1, 10); table.insert(a, 1, 20); table.insert(a, 1, -1) 232assert(table.remove(a) == 10) 233assert(table.remove(a) == 20) 234assert(table.remove(a) == -1) 235 236a = {'c', 'd'} 237table.insert(a, 3, 'a') 238table.insert(a, 'b') 239assert(table.remove(a, 1) == 'c') 240assert(table.remove(a, 1) == 'd') 241assert(table.remove(a, 1) == 'a') 242assert(table.remove(a, 1) == 'b') 243assert(#a == 0 and a.n == nil) 244 245a = {10,20,30,40} 246assert(a[#a] == 40) 247assert(table.remove(a, #a) == 40) 248assert(a[#a] == 30) 249assert(table.remove(a, 2) == 20) 250assert(a[#a] == 30 and #a == 2) 251 252 253return "OK" 254