testutil.lua (4453B)
1 local t = require('test.unit.testutil') 2 local t_eval = require('test.unit.eval.testutil') 3 4 local cimport = t.cimport 5 local to_cstr = t.to_cstr 6 local ffi = t.ffi 7 8 local list_type = t_eval.list_type 9 local dict_type = t_eval.dict_type 10 local func_type = t_eval.func_type 11 local nil_value = t_eval.nil_value 12 local int_type = t_eval.int_type 13 local flt_type = t_eval.flt_type 14 local type_key = t_eval.type_key 15 16 local api = cimport( 17 './src/nvim/api/private/defs.h', 18 './src/nvim/api/private/helpers.h', 19 './src/nvim/memory.h' 20 ) 21 22 local obj2lua 23 24 local obj2lua_tab = nil 25 26 local function init_obj2lua_tab() 27 if obj2lua_tab then 28 return 29 end 30 obj2lua_tab = { 31 [tonumber(api.kObjectTypeArray)] = function(obj) 32 local ret = { [type_key] = list_type } 33 for i = 1, tonumber(obj.data.array.size) do 34 ret[i] = obj2lua(obj.data.array.items[i - 1]) 35 end 36 if ret[1] then 37 ret[type_key] = nil 38 end 39 return ret 40 end, 41 [tonumber(api.kObjectTypeDict)] = function(obj) 42 local ret = {} 43 for i = 1, tonumber(obj.data.dict.size) do 44 local kv_pair = obj.data.dict.items[i - 1] 45 ret[ffi.string(kv_pair.key.data, kv_pair.key.size)] = obj2lua(kv_pair.value) 46 end 47 return ret 48 end, 49 [tonumber(api.kObjectTypeBoolean)] = function(obj) 50 if obj.data.boolean == false then 51 return false 52 else 53 return true 54 end 55 end, 56 [tonumber(api.kObjectTypeNil)] = function(_) 57 return nil_value 58 end, 59 [tonumber(api.kObjectTypeFloat)] = function(obj) 60 return tonumber(obj.data.floating) 61 end, 62 [tonumber(api.kObjectTypeInteger)] = function(obj) 63 return { [type_key] = int_type, value = tonumber(obj.data.integer) } 64 end, 65 [tonumber(api.kObjectTypeString)] = function(obj) 66 return ffi.string(obj.data.string.data, obj.data.string.size) 67 end, 68 } 69 end 70 71 obj2lua = function(obj) 72 init_obj2lua_tab() 73 return ( 74 (obj2lua_tab[tonumber(obj['type'])] or function(obj_inner) 75 assert( 76 false, 77 'Converting ' .. tostring(tonumber(obj_inner['type'])) .. ' is not implementing yet' 78 ) 79 end)(obj) 80 ) 81 end 82 83 local obj = function(typ, data) 84 return ffi.gc(ffi.new('Object', { ['type'] = typ, data = data }), api.api_free_object) 85 end 86 87 local lua2obj 88 89 local lua2obj_type_tab = { 90 [int_type] = function(l) 91 return obj(api.kObjectTypeInteger, { integer = l.value }) 92 end, 93 [flt_type] = function(l) 94 return obj(api.kObjectTypeFloat, { floating = l }) 95 end, 96 [list_type] = function(l) 97 local len = #l 98 local arr = obj(api.kObjectTypeArray, { 99 array = { 100 size = len, 101 capacity = len, 102 items = ffi.cast('Object *', api.xmalloc(len * ffi.sizeof('Object'))), 103 }, 104 }) 105 for i = 1, len do 106 arr.data.array.items[i - 1] = ffi.gc(lua2obj(l[i]), nil) 107 end 108 return arr 109 end, 110 [dict_type] = function(l) 111 local kvs = {} 112 for k, v in pairs(l) do 113 if type(k) == 'string' then 114 kvs[#kvs + 1] = { k, v } 115 end 116 end 117 local len = #kvs 118 local dct = obj(api.kObjectTypeDict, { 119 dict = { 120 size = len, 121 capacity = len, 122 items = ffi.cast('KeyValuePair *', api.xmalloc(len * ffi.sizeof('KeyValuePair'))), 123 }, 124 }) 125 for i = 1, len do 126 local key, val = unpack(kvs[i]) 127 dct.data.dict.items[i - 1] = ffi.new( 128 'KeyValuePair', 129 { key = ffi.gc(lua2obj(key), nil).data.string, value = ffi.gc(lua2obj(val), nil) } 130 ) 131 end 132 return dct 133 end, 134 } 135 136 lua2obj = function(l) 137 if type(l) == 'table' then 138 if l[type_key] then 139 return lua2obj_type_tab[l[type_key]](l) 140 else 141 if l[1] then 142 return lua2obj_type_tab[list_type](l) 143 else 144 return lua2obj_type_tab[dict_type](l) 145 end 146 end 147 elseif type(l) == 'number' then 148 return lua2obj_type_tab[flt_type](l) 149 elseif type(l) == 'boolean' then 150 return obj(api.kObjectTypeBoolean, { boolean = l }) 151 elseif type(l) == 'string' then 152 return obj( 153 api.kObjectTypeString, 154 { string = { 155 size = #l, 156 data = api.xmemdupz(to_cstr(l), #l), 157 } } 158 ) 159 elseif l == nil or l == nil_value then 160 return obj(api.kObjectTypeNil, { integer = 0 }) 161 end 162 end 163 164 return { 165 list_type = list_type, 166 dict_type = dict_type, 167 func_type = func_type, 168 int_type = int_type, 169 flt_type = flt_type, 170 171 nil_value = nil_value, 172 173 type_key = type_key, 174 175 obj2lua = obj2lua, 176 lua2obj = lua2obj, 177 }