tv_clear_spec.lua (3495B)
1 local t = require('test.unit.testutil') 2 local itp = t.gen_itp(it) 3 local t_eval = require('test.unit.eval.testutil') 4 5 local alloc_log_new = t.alloc_log_new 6 local cimport = t.cimport 7 local ffi = t.ffi 8 local eq = t.eq 9 10 local a = t_eval.alloc_logging_t 11 local type_key = t_eval.type_key 12 local list_type = t_eval.list_type 13 local list_items = t_eval.list_items 14 local dict_items = t_eval.dict_items 15 local lua2typvalt = t_eval.lua2typvalt 16 17 local lib = cimport('./src/nvim/eval/typval.h', './src/nvim/eval.h') 18 19 local alloc_log = alloc_log_new() 20 21 before_each(function() 22 alloc_log:before_each() 23 end) 24 25 after_each(function() 26 alloc_log:after_each() 27 end) 28 29 describe('tv_clear()', function() 30 itp('successfully frees all lists in [&l [1], *l, *l]', function() 31 local l_inner = { 1 } 32 local list = { l_inner, l_inner, l_inner } 33 local list_tv = ffi.gc(lua2typvalt(list), nil) 34 local list_p = list_tv.vval.v_list 35 local lis = list_items(list_p) 36 local list_inner_p = lis[1].li_tv.vval.v_list 37 local lis_inner = list_items(list_inner_p) 38 alloc_log:check({ 39 a.list(list_p), 40 a.list(list_inner_p), 41 a.li(lis_inner[1]), 42 a.li(lis[1]), 43 a.li(lis[2]), 44 a.li(lis[3]), 45 }) 46 eq(3, list_inner_p.lv_refcount) 47 lib.tv_clear(list_tv) 48 alloc_log:check({ 49 a.freed(lis_inner[1]), 50 a.freed(list_inner_p), 51 a.freed(lis[1]), 52 a.freed(lis[2]), 53 a.freed(lis[3]), 54 a.freed(list_p), 55 }) 56 end) 57 itp('successfully frees all lists in [&l [], *l, *l]', function() 58 local l_inner = { [type_key] = list_type } 59 local list = { l_inner, l_inner, l_inner } 60 local list_tv = ffi.gc(lua2typvalt(list), nil) 61 local list_p = list_tv.vval.v_list 62 local lis = list_items(list_p) 63 local list_inner_p = lis[1].li_tv.vval.v_list 64 alloc_log:check({ 65 a.list(list_p), 66 a.list(list_inner_p), 67 a.li(lis[1]), 68 a.li(lis[2]), 69 a.li(lis[3]), 70 }) 71 eq(3, list_inner_p.lv_refcount) 72 lib.tv_clear(list_tv) 73 alloc_log:check({ 74 a.freed(list_inner_p), 75 a.freed(lis[1]), 76 a.freed(lis[2]), 77 a.freed(lis[3]), 78 a.freed(list_p), 79 }) 80 end) 81 itp('successfully frees all dictionaries in [&d {}, *d]', function() 82 local d_inner = {} 83 local list = { d_inner, d_inner } 84 local list_tv = ffi.gc(lua2typvalt(list), nil) 85 local list_p = list_tv.vval.v_list 86 local lis = list_items(list_p) 87 local dict_inner_p = lis[1].li_tv.vval.v_dict 88 alloc_log:check({ 89 a.list(list_p), 90 a.dict(dict_inner_p), 91 a.li(lis[1]), 92 a.li(lis[2]), 93 }) 94 eq(2, dict_inner_p.dv_refcount) 95 lib.tv_clear(list_tv) 96 alloc_log:check({ 97 a.freed(dict_inner_p), 98 a.freed(lis[1]), 99 a.freed(lis[2]), 100 a.freed(list_p), 101 }) 102 end) 103 itp('successfully frees all dictionaries in [&d {a: 1}, *d]', function() 104 local d_inner = { a = 1 } 105 local list = { d_inner, d_inner } 106 local list_tv = ffi.gc(lua2typvalt(list), nil) 107 local list_p = list_tv.vval.v_list 108 local lis = list_items(list_p) 109 local dict_inner_p = lis[1].li_tv.vval.v_dict 110 local dis = dict_items(dict_inner_p) 111 alloc_log:check({ 112 a.list(list_p), 113 a.dict(dict_inner_p), 114 a.di(dis.a, 1), 115 a.li(lis[1]), 116 a.li(lis[2]), 117 }) 118 eq(2, dict_inner_p.dv_refcount) 119 lib.tv_clear(list_tv) 120 alloc_log:check({ 121 a.freed(dis.a), 122 a.freed(dict_inner_p), 123 a.freed(lis[1]), 124 a.freed(lis[2]), 125 a.freed(list_p), 126 }) 127 end) 128 end)