mirror of
https://github.com/neovim/neovim.git
synced 2024-09-17 20:58:20 -04:00
refactor(typval)!: remove distinction of binary and nonbinary strings
This is a breaking change which will make refactor of typval and shada code a lot easier. In particular, code that would use or check for v:msgpack_types.binary in the wild would be broken. This appears to be rarely used in existing plugins. Also some cases where v:msgpack_type.string would be used to represent a binary string of "string" type, we use a BLOB instead, which is vimscripts native type for binary blobs, and already was used for BIN formats when necessary. msgpackdump(msgpackparse(data)) no longer preserves the distinction of BIN and STR strings. This is very common behavior for language-specific msgpack bindings. Nvim uses msgpack as a tool to serialize its data. Nvim is not a tool to bit-perfectly manipulate arbitrary msgpack data out in the wild. The changed tests should indicate how behavior changes in various edge cases.
This commit is contained in:
parent
9e436251de
commit
bda63d5b97
@ -361,7 +361,7 @@ endfunction
|
||||
let s:MSGPACK_STANDARD_TYPES = {
|
||||
\type(0): 'integer',
|
||||
\type(0.0): 'float',
|
||||
\type(''): 'binary',
|
||||
\type(''): 'string',
|
||||
\type([]): 'array',
|
||||
\type({}): 'map',
|
||||
\type(v:true): 'boolean',
|
||||
@ -412,9 +412,15 @@ endfunction
|
||||
""
|
||||
" Dump |msgpack-special-dict| that represents a string. If any additional
|
||||
" parameter is given then it dumps binary string.
|
||||
function s:msgpack_dump_string(v, ...) abort
|
||||
let ret = [a:0 ? '"' : '="']
|
||||
for v in a:v._VAL
|
||||
function s:msgpack_dump_string(v) abort
|
||||
if type(a:v) == type({})
|
||||
let val = a:v
|
||||
else
|
||||
let val = {'_VAL': split(a:v, "\n", 1)}
|
||||
end
|
||||
|
||||
let ret = ['"']
|
||||
for v in val._VAL
|
||||
call add(
|
||||
\ret,
|
||||
\substitute(
|
||||
@ -426,16 +432,6 @@ function s:msgpack_dump_string(v, ...) abort
|
||||
return join(ret, '')
|
||||
endfunction
|
||||
|
||||
""
|
||||
" Dump binary string.
|
||||
function s:msgpack_dump_binary(v) abort
|
||||
if type(a:v) == type({})
|
||||
return s:msgpack_dump_string(a:v, 1)
|
||||
else
|
||||
return s:msgpack_dump_string({'_VAL': split(a:v, "\n", 1)}, 1)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
""
|
||||
" Dump array value.
|
||||
function s:msgpack_dump_array(v) abort
|
||||
@ -449,7 +445,7 @@ function s:msgpack_dump_map(v) abort
|
||||
let ret = ['{']
|
||||
if msgpack#special_type(a:v) is 0
|
||||
for [k, v] in items(a:v)
|
||||
let ret += [s:msgpack_dump_string({'_VAL': split(k, "\n", 1)}),
|
||||
let ret += [s:msgpack_dump_string({'_VAL': split(k, "\n")}),
|
||||
\': ',
|
||||
\msgpack#string(v),
|
||||
\', ']
|
||||
@ -479,7 +475,7 @@ endfunction
|
||||
" Dump extension value.
|
||||
function s:msgpack_dump_ext(v) abort
|
||||
return printf('+(%i)%s', a:v._VAL[0],
|
||||
\s:msgpack_dump_string({'_VAL': a:v._VAL[1]}, 1))
|
||||
\s:msgpack_dump_string({'_VAL': a:v._VAL[1]}))
|
||||
endfunction
|
||||
|
||||
""
|
||||
@ -619,9 +615,7 @@ function msgpack#eval(s, special_objs) abort
|
||||
throw '"-invalid:Invalid string: ' . s
|
||||
endif
|
||||
call add(expr, '{''_TYPE'': v:msgpack_types.')
|
||||
if empty(match[1])
|
||||
call add(expr, 'binary')
|
||||
elseif match[1] is# '='
|
||||
if empty(match[1]) || match[1] is# '='
|
||||
call add(expr, 'string')
|
||||
else
|
||||
call add(expr, 'ext')
|
||||
@ -772,7 +766,7 @@ function msgpack#equal(a, b)
|
||||
let a = aspecial is 0 ? a:a : a:a._VAL
|
||||
let b = bspecial is 0 ? a:b : a:b._VAL
|
||||
return msgpack#equal(a, b)
|
||||
elseif atype is# 'binary'
|
||||
elseif atype is# 'string'
|
||||
let a = (aspecial is 0 ? split(a:a, "\n", 1) : a:a._VAL)
|
||||
let b = (bspecial is 0 ? split(a:b, "\n", 1) : a:b._VAL)
|
||||
return a ==# b
|
||||
@ -787,13 +781,17 @@ function msgpack#equal(a, b)
|
||||
" Non-special mapping cannot have non-string keys
|
||||
return 0
|
||||
endif
|
||||
if (empty(k._VAL)
|
||||
\|| k._VAL ==# [""]
|
||||
\|| !empty(filter(copy(k._VAL), 'stridx(v:val, "\n") != -1')))
|
||||
" Non-special mapping cannot have zero byte in key or an empty key
|
||||
return 0
|
||||
if type(k) == type({})
|
||||
if (empty(k._VAL)
|
||||
\|| k._VAL ==# [""]
|
||||
\|| !empty(filter(copy(k._VAL), 'stridx(v:val, "\n") != -1')))
|
||||
" Non-special mapping cannot have zero byte in key or an empty key
|
||||
return 0
|
||||
endif
|
||||
let kstr = join(k._VAL, "\n")
|
||||
else
|
||||
let kstr = k
|
||||
endif
|
||||
let kstr = join(k._VAL, "\n")
|
||||
if !has_key(akeys, kstr)
|
||||
" Protects from both missing and duplicate keys
|
||||
return 0
|
||||
|
@ -230,7 +230,7 @@ function s:shada_check_type(type, val) abort
|
||||
return 0
|
||||
elseif a:type is# 'bin'
|
||||
" Binary string without zero bytes
|
||||
if type isnot# 'binary'
|
||||
if type isnot# 'string'
|
||||
return 'Expected binary string'
|
||||
elseif (type(a:val) == type({})
|
||||
\&& !empty(filter(copy(a:val._VAL), 'stridx(v:val, "\n") != -1')))
|
||||
@ -247,7 +247,7 @@ function s:shada_check_type(type, val) abort
|
||||
if type isnot# 'array'
|
||||
return 'Expected array value'
|
||||
elseif !empty(filter(copy(type(a:val) == type({}) ? a:val._VAL : a:val),
|
||||
\'msgpack#type(v:val) isnot# "binary"'))
|
||||
\'msgpack#type(v:val) isnot# "string"'))
|
||||
return 'Expected array of binary strings'
|
||||
else
|
||||
for element in (type(a:val) == type({}) ? a:val._VAL : a:val)
|
||||
|
7
runtime/doc/builtin.txt
generated
7
runtime/doc/builtin.txt
generated
@ -5152,12 +5152,7 @@ msgpackparse({data}) *msgpackparse()*
|
||||
C parser does not support such values.
|
||||
float |Float|. This value cannot possibly appear in
|
||||
|msgpackparse()| output.
|
||||
string |readfile()|-style list of strings. This value will
|
||||
appear in |msgpackparse()| output if string contains
|
||||
zero byte or if string is a mapping key and mapping is
|
||||
being represented as special dictionary for other
|
||||
reasons.
|
||||
binary |String|, or |Blob| if binary string contains zero
|
||||
string |String|, or |Blob| if binary string contains zero
|
||||
byte. This value cannot appear in |msgpackparse()|
|
||||
output since blobs were introduced.
|
||||
array |List|. This value cannot appear in |msgpackparse()|
|
||||
|
@ -50,6 +50,12 @@ EDITOR
|
||||
• |hl-CurSearch| now behaves the same as Vim and no longer updates on every
|
||||
cursor movement.
|
||||
|
||||
VIM SCRIPT
|
||||
|
||||
• |v:msgpack_types| has the type "binary" removed. |msgpackparse()| no longer
|
||||
treats BIN, STR and FIXSTR as separate types. Any of these is returned as a
|
||||
string if possible, or a |blob| if the value contained embedded NUL:s.
|
||||
|
||||
EVENTS
|
||||
|
||||
• TODO
|
||||
|
7
runtime/lua/vim/_meta/vimfn.lua
generated
7
runtime/lua/vim/_meta/vimfn.lua
generated
@ -6177,12 +6177,7 @@ function vim.fn.msgpackdump(list, type) end
|
||||
--- C parser does not support such values.
|
||||
--- float |Float|. This value cannot possibly appear in
|
||||
--- |msgpackparse()| output.
|
||||
--- string |readfile()|-style list of strings. This value will
|
||||
--- appear in |msgpackparse()| output if string contains
|
||||
--- zero byte or if string is a mapping key and mapping is
|
||||
--- being represented as special dictionary for other
|
||||
--- reasons.
|
||||
--- binary |String|, or |Blob| if binary string contains zero
|
||||
--- string |String|, or |Blob| if binary string contains zero
|
||||
--- byte. This value cannot appear in |msgpackparse()|
|
||||
--- output since blobs were introduced.
|
||||
--- array |List|. This value cannot appear in |msgpackparse()|
|
||||
|
@ -7,7 +7,9 @@
|
||||
#include "nvim/api/private/converter.h"
|
||||
#include "nvim/api/private/defs.h"
|
||||
#include "nvim/api/private/helpers.h"
|
||||
#include "nvim/ascii_defs.h"
|
||||
#include "nvim/assert_defs.h"
|
||||
#include "nvim/eval/decode.h"
|
||||
#include "nvim/eval/typval.h"
|
||||
#include "nvim/eval/typval_defs.h"
|
||||
#include "nvim/eval/userfunc.h"
|
||||
@ -302,15 +304,11 @@ void object_to_vim_take_luaref(Object *obj, typval_T *tv, bool take_luaref, Erro
|
||||
tv->vval.v_float = obj->data.floating;
|
||||
break;
|
||||
|
||||
case kObjectTypeString:
|
||||
tv->v_type = VAR_STRING;
|
||||
if (obj->data.string.data == NULL) {
|
||||
tv->vval.v_string = NULL;
|
||||
} else {
|
||||
tv->vval.v_string = xmemdupz(obj->data.string.data,
|
||||
obj->data.string.size);
|
||||
}
|
||||
case kObjectTypeString: {
|
||||
String s = obj->data.string;
|
||||
*tv = decode_string(s.data, s.size, false, false);
|
||||
break;
|
||||
}
|
||||
|
||||
case kObjectTypeArray: {
|
||||
list_T *const list = tv_list_alloc((ptrdiff_t)obj->data.array.size);
|
||||
|
@ -331,7 +331,6 @@ static const char *const msgpack_type_names[] = {
|
||||
[kMPInteger] = "integer",
|
||||
[kMPFloat] = "float",
|
||||
[kMPString] = "string",
|
||||
[kMPBinary] = "binary",
|
||||
[kMPArray] = "array",
|
||||
[kMPMap] = "map",
|
||||
[kMPExt] = "ext",
|
||||
@ -342,7 +341,6 @@ const list_T *eval_msgpack_type_lists[] = {
|
||||
[kMPInteger] = NULL,
|
||||
[kMPFloat] = NULL,
|
||||
[kMPString] = NULL,
|
||||
[kMPBinary] = NULL,
|
||||
[kMPArray] = NULL,
|
||||
[kMPMap] = NULL,
|
||||
[kMPExt] = NULL,
|
||||
|
@ -7444,12 +7444,7 @@ M.funcs = {
|
||||
C parser does not support such values.
|
||||
float |Float|. This value cannot possibly appear in
|
||||
|msgpackparse()| output.
|
||||
string |readfile()|-style list of strings. This value will
|
||||
appear in |msgpackparse()| output if string contains
|
||||
zero byte or if string is a mapping key and mapping is
|
||||
being represented as special dictionary for other
|
||||
reasons.
|
||||
binary |String|, or |Blob| if binary string contains zero
|
||||
string |String|, or |Blob| if binary string contains zero
|
||||
byte. This value cannot appear in |msgpackparse()|
|
||||
output since blobs were introduced.
|
||||
array |List|. This value cannot appear in |msgpackparse()|
|
||||
|
@ -247,45 +247,29 @@ list_T *decode_create_map_special_dict(typval_T *const ret_tv, const ptrdiff_t l
|
||||
///
|
||||
/// @param[in] s String to decode.
|
||||
/// @param[in] len String length.
|
||||
/// @param[in] hasnul Whether string has NUL byte, not or it was not yet
|
||||
/// determined.
|
||||
/// @param[in] binary Determines decode type if string has NUL bytes.
|
||||
/// If true convert string to VAR_BLOB, otherwise to the
|
||||
/// kMPString special type.
|
||||
/// @param[in] force_blob whether string always should be decoded as a blob,
|
||||
/// or only when embedded NUL bytes were present
|
||||
/// @param[in] s_allocated If true, then `s` was allocated and can be saved in
|
||||
/// a returned structure. If it is not saved there, it
|
||||
/// will be freed.
|
||||
///
|
||||
/// @return Decoded string.
|
||||
typval_T decode_string(const char *const s, const size_t len, const TriState hasnul,
|
||||
const bool binary, const bool s_allocated)
|
||||
typval_T decode_string(const char *const s, const size_t len, bool force_blob,
|
||||
const bool s_allocated)
|
||||
FUNC_ATTR_WARN_UNUSED_RESULT
|
||||
{
|
||||
assert(s != NULL || len == 0);
|
||||
const bool really_hasnul = (hasnul == kNone
|
||||
? ((s != NULL) && (memchr(s, NUL, len) != NULL))
|
||||
: (bool)hasnul);
|
||||
if (really_hasnul) {
|
||||
const bool use_blob = force_blob || ((s != NULL) && (memchr(s, NUL, len) != NULL));
|
||||
if (use_blob) {
|
||||
typval_T tv;
|
||||
tv.v_lock = VAR_UNLOCKED;
|
||||
if (binary) {
|
||||
tv_blob_alloc_ret(&tv);
|
||||
ga_concat_len(&tv.vval.v_blob->bv_ga, s, len);
|
||||
blob_T *b = tv_blob_alloc_ret(&tv);
|
||||
if (s_allocated) {
|
||||
b->bv_ga.ga_data = (void *)s;
|
||||
b->bv_ga.ga_len = (int)len;
|
||||
b->bv_ga.ga_maxlen = (int)len;
|
||||
} else {
|
||||
list_T *const list = tv_list_alloc(kListLenMayKnow);
|
||||
tv_list_ref(list);
|
||||
create_special_dict(&tv, kMPString,
|
||||
(typval_T){ .v_type = VAR_LIST,
|
||||
.v_lock = VAR_UNLOCKED,
|
||||
.vval = { .v_list = list } });
|
||||
const int elw_ret = encode_list_write((void *)list, s, len);
|
||||
if (s_allocated) {
|
||||
xfree((void *)s);
|
||||
}
|
||||
if (elw_ret == -1) {
|
||||
tv_clear(&tv);
|
||||
return (typval_T) { .v_type = VAR_UNKNOWN, .v_lock = VAR_UNLOCKED };
|
||||
}
|
||||
ga_concat_len(&b->bv_ga, s, len);
|
||||
}
|
||||
return tv;
|
||||
}
|
||||
@ -405,7 +389,6 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
|
||||
char *str = xmalloc(len + 1);
|
||||
int fst_in_pair = 0;
|
||||
char *str_end = str;
|
||||
bool hasnul = false;
|
||||
#define PUT_FST_IN_PAIR(fst_in_pair, str_end) \
|
||||
do { \
|
||||
if ((fst_in_pair) != 0) { \
|
||||
@ -426,9 +409,6 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
|
||||
uvarnumber_T ch;
|
||||
vim_str2nr(ubuf, NULL, NULL,
|
||||
STR2NR_HEX | STR2NR_FORCE, NULL, &ch, 4, true, NULL);
|
||||
if (ch == 0) {
|
||||
hasnul = true;
|
||||
}
|
||||
if (SURROGATE_HI_START <= ch && ch <= SURROGATE_HI_END) {
|
||||
PUT_FST_IN_PAIR(fst_in_pair, str_end);
|
||||
fst_in_pair = (int)ch;
|
||||
@ -476,10 +456,7 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
|
||||
PUT_FST_IN_PAIR(fst_in_pair, str_end);
|
||||
#undef PUT_FST_IN_PAIR
|
||||
*str_end = NUL;
|
||||
typval_T obj = decode_string(str, (size_t)(str_end - str), hasnul ? kTrue : kFalse, false, true);
|
||||
if (obj.v_type == VAR_UNKNOWN) {
|
||||
goto parse_json_string_fail;
|
||||
}
|
||||
typval_T obj = decode_string(str, (size_t)(str_end - str), false, true);
|
||||
POP(obj, obj.v_type != VAR_STRING);
|
||||
goto parse_json_string_ret;
|
||||
parse_json_string_fail:
|
||||
@ -982,18 +959,8 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
|
||||
};
|
||||
break;
|
||||
case MSGPACK_OBJECT_STR:
|
||||
*rettv = decode_string(mobj.via.bin.ptr, mobj.via.bin.size, kTrue, false,
|
||||
false);
|
||||
if (rettv->v_type == VAR_UNKNOWN) {
|
||||
return FAIL;
|
||||
}
|
||||
break;
|
||||
case MSGPACK_OBJECT_BIN:
|
||||
*rettv = decode_string(mobj.via.bin.ptr, mobj.via.bin.size, kNone, true,
|
||||
false);
|
||||
if (rettv->v_type == VAR_UNKNOWN) {
|
||||
return FAIL;
|
||||
}
|
||||
*rettv = decode_string(mobj.via.bin.ptr, mobj.via.bin.size, false, false);
|
||||
break;
|
||||
case MSGPACK_OBJECT_ARRAY: {
|
||||
list_T *const list = tv_list_alloc((ptrdiff_t)mobj.via.array.size);
|
||||
@ -1016,7 +983,8 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
|
||||
}
|
||||
case MSGPACK_OBJECT_MAP: {
|
||||
for (size_t i = 0; i < mobj.via.map.size; i++) {
|
||||
if (mobj.via.map.ptr[i].key.type != MSGPACK_OBJECT_STR
|
||||
if ((mobj.via.map.ptr[i].key.type != MSGPACK_OBJECT_STR
|
||||
&& mobj.via.map.ptr[i].key.type != MSGPACK_OBJECT_BIN)
|
||||
|| mobj.via.map.ptr[i].key.via.str.size == 0
|
||||
|| memchr(mobj.via.map.ptr[i].key.via.str.ptr, NUL,
|
||||
mobj.via.map.ptr[i].key.via.str.size) != NULL) {
|
||||
|
@ -776,8 +776,7 @@ bool encode_check_json_key(const typval_T *const tv)
|
||||
const dictitem_T *val_di;
|
||||
if ((type_di = tv_dict_find(spdict, S_LEN("_TYPE"))) == NULL
|
||||
|| type_di->di_tv.v_type != VAR_LIST
|
||||
|| (type_di->di_tv.vval.v_list != eval_msgpack_type_lists[kMPString]
|
||||
&& type_di->di_tv.vval.v_list != eval_msgpack_type_lists[kMPBinary])
|
||||
|| type_di->di_tv.vval.v_list != eval_msgpack_type_lists[kMPString]
|
||||
|| (val_di = tv_dict_find(spdict, S_LEN("_VAL"))) == NULL
|
||||
|| val_di->di_tv.v_type != VAR_LIST) {
|
||||
return false;
|
||||
|
@ -501,9 +501,7 @@ static int TYPVAL_ENCODE_CONVERT_ONE_VALUE(
|
||||
}
|
||||
TYPVAL_ENCODE_CONV_FLOAT(tv, val_di->di_tv.vval.v_float);
|
||||
break;
|
||||
case kMPString:
|
||||
case kMPBinary: {
|
||||
const bool is_string = ((MessagePackType)i == kMPString);
|
||||
case kMPString: {
|
||||
if (val_di->di_tv.v_type != VAR_LIST) {
|
||||
goto _convert_one_value_regular_dict;
|
||||
}
|
||||
@ -513,11 +511,7 @@ static int TYPVAL_ENCODE_CONVERT_ONE_VALUE(
|
||||
&buf)) {
|
||||
goto _convert_one_value_regular_dict;
|
||||
}
|
||||
if (is_string) {
|
||||
TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len);
|
||||
} else {
|
||||
TYPVAL_ENCODE_CONV_STRING(tv, buf, len);
|
||||
}
|
||||
TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len);
|
||||
xfree(buf);
|
||||
break;
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ typedef enum {
|
||||
kMPInteger,
|
||||
kMPFloat,
|
||||
kMPString,
|
||||
kMPBinary,
|
||||
kMPArray,
|
||||
kMPMap,
|
||||
kMPExt,
|
||||
|
@ -219,12 +219,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
|
||||
if (cur.special) {
|
||||
list_T *const kv_pair = tv_list_alloc(2);
|
||||
|
||||
typval_T s_tv = decode_string(s, len, kTrue, false, false);
|
||||
if (s_tv.v_type == VAR_UNKNOWN) {
|
||||
ret = false;
|
||||
tv_list_unref(kv_pair);
|
||||
continue;
|
||||
}
|
||||
typval_T s_tv = decode_string(s, len, true, false);
|
||||
tv_list_append_owned_tv(kv_pair, s_tv);
|
||||
|
||||
// Value: not populated yet, need to create list item to push.
|
||||
@ -280,10 +275,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
|
||||
case LUA_TSTRING: {
|
||||
size_t len;
|
||||
const char *s = lua_tolstring(lstate, -1, &len);
|
||||
*cur.tv = decode_string(s, len, kNone, true, false);
|
||||
if (cur.tv->v_type == VAR_UNKNOWN) {
|
||||
ret = false;
|
||||
}
|
||||
*cur.tv = decode_string(s, len, false, false);
|
||||
break;
|
||||
}
|
||||
case LUA_TNUMBER: {
|
||||
|
@ -1571,9 +1571,9 @@ describe('API', function()
|
||||
eq(val2, request('vim_del_var', 'lua'))
|
||||
end)
|
||||
|
||||
it('truncates values with NULs in them', function()
|
||||
it('preserves values with NULs in them', function()
|
||||
api.nvim_set_var('xxx', 'ab\0cd')
|
||||
eq('ab', api.nvim_get_var('xxx'))
|
||||
eq('ab\000cd', api.nvim_get_var('xxx'))
|
||||
end)
|
||||
end)
|
||||
|
||||
|
@ -72,9 +72,9 @@ describe('luaeval()', function()
|
||||
end)
|
||||
it('are successfully converted to special dictionaries in table keys', function()
|
||||
command([[let d = luaeval('{["\0"]=1}')]])
|
||||
eq({_TYPE={}, _VAL={{{_TYPE={}, _VAL={'\n'}}, 1}}}, api.nvim_get_var('d'))
|
||||
eq({_TYPE={}, _VAL={{'\000', 1}}}, api.nvim_get_var('d'))
|
||||
eq(1, fn.eval('d._TYPE is v:msgpack_types.map'))
|
||||
eq(1, fn.eval('d._VAL[0][0]._TYPE is v:msgpack_types.string'))
|
||||
eq(eval('v:t_blob'), fn.eval('type(d._VAL[0][0])'))
|
||||
end)
|
||||
it('are successfully converted to blobs from a list', function()
|
||||
command([[let l = luaeval('{"abc", "a\0b", "c\0d", "def"}')]])
|
||||
@ -125,11 +125,11 @@ describe('luaeval()', function()
|
||||
local level = 30
|
||||
eq(nested_by_level[level].o, fn.luaeval(nested_by_level[level].s))
|
||||
|
||||
eq({_TYPE={}, _VAL={{{_TYPE={}, _VAL={'\n', '\n'}}, '\000\n\000\000'}}},
|
||||
eq({_TYPE={}, _VAL={{'\000\n\000', '\000\n\000\000'}}},
|
||||
fn.luaeval([[{['\0\n\0']='\0\n\0\0'}]]))
|
||||
eq(1, eval([[luaeval('{["\0\n\0"]="\0\n\0\0"}')._TYPE is v:msgpack_types.map]]))
|
||||
eq(1, eval([[luaeval('{["\0\n\0"]="\0\n\0\0"}')._VAL[0][0]._TYPE is v:msgpack_types.string]]))
|
||||
eq({nested={{_TYPE={}, _VAL={{{_TYPE={}, _VAL={'\n', '\n'}}, '\000\n\000\000'}}}}},
|
||||
eq(eval("v:t_blob"), eval([[type(luaeval('{["\0\n\0"]="\0\n\0\0"}')._VAL[0][0])]]))
|
||||
eq({nested={{_TYPE={}, _VAL={{'\000\n\000', '\000\n\000\000'}}}}},
|
||||
fn.luaeval([[{nested={{['\0\n\0']='\0\n\0\0'}}}]]))
|
||||
end)
|
||||
|
||||
@ -177,12 +177,10 @@ describe('luaeval()', function()
|
||||
end
|
||||
|
||||
it('correctly passes special dictionaries', function()
|
||||
eq({0, '\000\n\000'}, luaevalarg(sp('binary', '["\\n", "\\n"]')))
|
||||
eq({0, '\000\n\000'}, luaevalarg(sp('string', '["\\n", "\\n"]')))
|
||||
eq({0, true}, luaevalarg(sp('boolean', 1)))
|
||||
eq({0, false}, luaevalarg(sp('boolean', 0)))
|
||||
eq({0, NIL}, luaevalarg(sp('nil', 0)))
|
||||
eq({0, {[""]=""}}, luaevalarg(mapsp(sp('binary', '[""]'), '""')))
|
||||
eq({0, {[""]=""}}, luaevalarg(mapsp(sp('string', '[""]'), '""')))
|
||||
end)
|
||||
|
||||
|
@ -58,23 +58,11 @@ describe('autoload/msgpack.vim', function()
|
||||
msgpack_eq(1, '"abc\\ndef"', '"abc\\ndef"')
|
||||
msgpack_eq(0, '"abc\\ndef"', '"abc\\nghi"')
|
||||
end)
|
||||
it('compares binary specials correctly', function()
|
||||
msgpack_eq(1, sp('binary', '["abc\\n", "def"]'), sp('binary', '["abc\\n", "def"]'))
|
||||
msgpack_eq(0, sp('binary', '["abc", "def"]'), sp('binary', '["abc\\n", "def"]'))
|
||||
end)
|
||||
it('compares binary specials with raw binaries correctly', function()
|
||||
msgpack_eq(1, sp('binary', '["abc", "def"]'), '"abc\\ndef"')
|
||||
msgpack_eq(0, sp('binary', '["abc", "def"]'), '"abcdef"')
|
||||
end)
|
||||
it('compares string specials correctly', function()
|
||||
msgpack_eq(1, sp('string', '["abc\\n", "def"]'), sp('string', '["abc\\n", "def"]'))
|
||||
msgpack_eq(0, sp('string', '["abc", "def"]'), sp('string', '["abc\\n", "def"]'))
|
||||
end)
|
||||
it('compares string specials with binary correctly', function()
|
||||
msgpack_eq(0, sp('string', '["abc\\n", "def"]'), sp('binary', '["abc\\n", "def"]'))
|
||||
msgpack_eq(0, sp('string', '["abc", "def"]'), '"abc\\ndef"')
|
||||
msgpack_eq(0, sp('binary', '["abc\\n", "def"]'), sp('string', '["abc\\n", "def"]'))
|
||||
msgpack_eq(0, '"abc\\ndef"', sp('string', '["abc", "def"]'))
|
||||
msgpack_eq(1, sp('string', '["abc", "def"]'), '"abc\\ndef"')
|
||||
msgpack_eq(1, '"abc\\ndef"', sp('string', '["abc", "def"]'))
|
||||
end)
|
||||
it('compares ext specials correctly', function()
|
||||
msgpack_eq(1, sp('ext', '[1, ["", "ac"]]'), sp('ext', '[1, ["", "ac"]]'))
|
||||
@ -92,20 +80,16 @@ describe('autoload/msgpack.vim', function()
|
||||
end)
|
||||
it('compares map specials correctly', function()
|
||||
msgpack_eq(1, mapsp(), mapsp())
|
||||
msgpack_eq(1, mapsp(sp('binary', '[""]'), '""'), mapsp(sp('binary', '[""]'), '""'))
|
||||
msgpack_eq(
|
||||
1,
|
||||
mapsp(mapsp('1', '1'), mapsp('1', '1')),
|
||||
mapsp(mapsp('1', '1'), mapsp('1', '1'))
|
||||
)
|
||||
msgpack_eq(0, mapsp(), mapsp('1', '1'))
|
||||
msgpack_eq(0, mapsp(sp('binary', '["a"]'), '""'), mapsp(sp('binary', '[""]'), '""'))
|
||||
msgpack_eq(0, mapsp(sp('binary', '[""]'), '"a"'), mapsp(sp('binary', '[""]'), '""'))
|
||||
msgpack_eq(0, mapsp(sp('binary', '["a"]'), '"a"'), mapsp(sp('binary', '[""]'), '""'))
|
||||
msgpack_eq(
|
||||
0,
|
||||
mapsp(mapsp('1', '1'), mapsp('1', '1')),
|
||||
mapsp(sp('binary', '[""]'), mapsp('1', '1'))
|
||||
mapsp(sp('string', '[""]'), mapsp('1', '1'))
|
||||
)
|
||||
msgpack_eq(
|
||||
0,
|
||||
@ -138,7 +122,7 @@ describe('autoload/msgpack.vim', function()
|
||||
msgpack_eq(1, mapsp(sp('string', '["1"]'), '1'), '{"1": 1}')
|
||||
msgpack_eq(1, mapsp(sp('string', '["1"]'), sp('integer', '[1, 0, 0, 1]')), '{"1": 1}')
|
||||
msgpack_eq(0, mapsp(sp('integer', '[1, 0, 0, 1]'), sp('string', '["1"]')), '{1: "1"}')
|
||||
msgpack_eq(0, mapsp('"1"', sp('integer', '[1, 0, 0, 1]')), '{"1": 1}')
|
||||
msgpack_eq(1, mapsp('"1"', sp('integer', '[1, 0, 0, 1]')), '{"1": 1}')
|
||||
msgpack_eq(0, mapsp(sp('string', '["1"]'), '1', sp('string', '["2"]'), '2'), '{"1": 1}')
|
||||
msgpack_eq(0, mapsp(sp('string', '["1"]'), '1'), '{"1": 1, "2": 2}')
|
||||
end)
|
||||
@ -290,7 +274,6 @@ describe('autoload/msgpack.vim', function()
|
||||
|
||||
it('works for special dictionaries', function()
|
||||
type_eq('string', sp('string', '[""]'))
|
||||
type_eq('binary', sp('binary', '[""]'))
|
||||
type_eq('ext', sp('ext', '[1, [""]]'))
|
||||
type_eq('array', sp('array', '[]'))
|
||||
type_eq('map', sp('map', '[]'))
|
||||
@ -301,7 +284,7 @@ describe('autoload/msgpack.vim', function()
|
||||
end)
|
||||
|
||||
it('works for regular values', function()
|
||||
type_eq('binary', '""')
|
||||
type_eq('string', '""')
|
||||
type_eq('array', '[]')
|
||||
type_eq('map', '{}')
|
||||
type_eq('integer', '1')
|
||||
@ -319,7 +302,6 @@ describe('autoload/msgpack.vim', function()
|
||||
|
||||
it('works for special dictionaries', function()
|
||||
sp_type_eq('string', sp('string', '[""]'))
|
||||
sp_type_eq('binary', sp('binary', '[""]'))
|
||||
sp_type_eq('ext', sp('ext', '[1, [""]]'))
|
||||
sp_type_eq('array', sp('array', '[]'))
|
||||
sp_type_eq('map', sp('map', '[]'))
|
||||
@ -347,12 +329,9 @@ describe('autoload/msgpack.vim', function()
|
||||
end
|
||||
|
||||
it('works for special dictionaries', function()
|
||||
string_eq('=""', sp('string', '[""]'))
|
||||
string_eq('="\\n"', sp('string', '["", ""]'))
|
||||
string_eq('="ab\\0c\\nde"', sp('string', '["ab\\nc", "de"]'))
|
||||
string_eq('""', sp('binary', '[""]'))
|
||||
string_eq('"\\n"', sp('binary', '["", ""]'))
|
||||
string_eq('"ab\\0c\\nde"', sp('binary', '["ab\\nc", "de"]'))
|
||||
string_eq('""', sp('string', '[""]'))
|
||||
string_eq('"\\n"', sp('string', '["", ""]'))
|
||||
string_eq('"ab\\0c\\nde"', sp('string', '["ab\\nc", "de"]'))
|
||||
string_eq('+(2)""', sp('ext', '[2, [""]]'))
|
||||
string_eq('+(2)"\\n"', sp('ext', '[2, ["", ""]]'))
|
||||
string_eq('+(2)"ab\\0c\\nde"', sp('ext', '[2, ["ab\\nc", "de"]]'))
|
||||
@ -397,8 +376,8 @@ describe('autoload/msgpack.vim', function()
|
||||
string_eq('[]', '[]')
|
||||
string_eq('[[[{}]]]', '[[[{}]]]')
|
||||
string_eq('{}', '{}')
|
||||
string_eq('{="2": 10}', '{2: 10}')
|
||||
string_eq('{="2": [{}]}', '{2: [{}]}')
|
||||
string_eq('{"2": 10}', '{2: 10}')
|
||||
string_eq('{"2": [{}]}', '{2: [{}]}')
|
||||
string_eq('1', '1')
|
||||
string_eq('0.0', '0.0')
|
||||
string_eq('inf', '(1.0/0.0)')
|
||||
@ -422,7 +401,6 @@ describe('autoload/msgpack.vim', function()
|
||||
nvim_command('let spflt = ' .. sp('float', '1.0'))
|
||||
nvim_command('let spext = ' .. sp('ext', '[2, ["abc", "def"]]'))
|
||||
nvim_command('let spstr = ' .. sp('string', '["abc", "def"]'))
|
||||
nvim_command('let spbin = ' .. sp('binary', '["abc", "def"]'))
|
||||
nvim_command('let spbln = ' .. sp('boolean', '0'))
|
||||
nvim_command('let spnil = ' .. sp('nil', '0'))
|
||||
|
||||
@ -432,7 +410,6 @@ describe('autoload/msgpack.vim', function()
|
||||
nvim_command('let spflt2 = msgpack#deepcopy(spflt)')
|
||||
nvim_command('let spext2 = msgpack#deepcopy(spext)')
|
||||
nvim_command('let spstr2 = msgpack#deepcopy(spstr)')
|
||||
nvim_command('let spbin2 = msgpack#deepcopy(spbin)')
|
||||
nvim_command('let spbln2 = msgpack#deepcopy(spbln)')
|
||||
nvim_command('let spnil2 = msgpack#deepcopy(spnil)')
|
||||
|
||||
@ -442,7 +419,6 @@ describe('autoload/msgpack.vim', function()
|
||||
eq('float', nvim_eval('msgpack#type(spflt2)'))
|
||||
eq('ext', nvim_eval('msgpack#type(spext2)'))
|
||||
eq('string', nvim_eval('msgpack#type(spstr2)'))
|
||||
eq('binary', nvim_eval('msgpack#type(spbin2)'))
|
||||
eq('boolean', nvim_eval('msgpack#type(spbln2)'))
|
||||
eq('nil', nvim_eval('msgpack#type(spnil2)'))
|
||||
|
||||
@ -457,7 +433,6 @@ describe('autoload/msgpack.vim', function()
|
||||
nvim_command('let spext._VAL[0] = 3')
|
||||
nvim_command('let spext._VAL[1][0] = "gh"')
|
||||
nvim_command('let spstr._VAL[0] = "gh"')
|
||||
nvim_command('let spbin._VAL[0] = "gh"')
|
||||
nvim_command('let spbln._VAL = 1')
|
||||
nvim_command('let spnil._VAL = 1')
|
||||
|
||||
@ -467,7 +442,6 @@ describe('autoload/msgpack.vim', function()
|
||||
eq({ _TYPE = {}, _VAL = 1.0 }, nvim_eval('spflt2'))
|
||||
eq({ _TYPE = {}, _VAL = { 2, { 'abc', 'def' } } }, nvim_eval('spext2'))
|
||||
eq({ _TYPE = {}, _VAL = { 'abc', 'def' } }, nvim_eval('spstr2'))
|
||||
eq({ _TYPE = {}, _VAL = { 'abc', 'def' } }, nvim_eval('spbin2'))
|
||||
eq({ _TYPE = {}, _VAL = 0 }, nvim_eval('spbln2'))
|
||||
eq({ _TYPE = {}, _VAL = 0 }, nvim_eval('spnil2'))
|
||||
|
||||
@ -477,7 +451,6 @@ describe('autoload/msgpack.vim', function()
|
||||
nvim_command('let spflt._TYPE = []')
|
||||
nvim_command('let spext._TYPE = []')
|
||||
nvim_command('let spstr._TYPE = []')
|
||||
nvim_command('let spbin._TYPE = []')
|
||||
nvim_command('let spbln._TYPE = []')
|
||||
nvim_command('let spnil._TYPE = []')
|
||||
|
||||
@ -487,7 +460,6 @@ describe('autoload/msgpack.vim', function()
|
||||
eq('float', nvim_eval('msgpack#special_type(spflt2)'))
|
||||
eq('ext', nvim_eval('msgpack#special_type(spext2)'))
|
||||
eq('string', nvim_eval('msgpack#special_type(spstr2)'))
|
||||
eq('binary', nvim_eval('msgpack#special_type(spbin2)'))
|
||||
eq('boolean', nvim_eval('msgpack#special_type(spbln2)'))
|
||||
eq('nil', nvim_eval('msgpack#special_type(spnil2)'))
|
||||
end)
|
||||
@ -509,7 +481,7 @@ describe('autoload/msgpack.vim', function()
|
||||
eq('map', nvim_eval('msgpack#type(map2)'))
|
||||
eq('integer', nvim_eval('msgpack#type(int2)'))
|
||||
eq('float', nvim_eval('msgpack#type(flt2)'))
|
||||
eq('binary', nvim_eval('msgpack#type(bin2)'))
|
||||
eq('string', nvim_eval('msgpack#type(bin2)'))
|
||||
|
||||
nvim_command('call add(arr, 0)')
|
||||
nvim_command('call add(arr[0], 0)')
|
||||
@ -566,21 +538,6 @@ describe('autoload/msgpack.vim', function()
|
||||
nvim_command('unlet g:__val')
|
||||
end
|
||||
|
||||
it('correctly loads binary strings', function()
|
||||
eval_eq('binary', { 'abcdef' }, '"abcdef"')
|
||||
eval_eq('binary', { 'abc', 'def' }, '"abc\\ndef"')
|
||||
eval_eq('binary', { 'abc\ndef' }, '"abc\\0def"')
|
||||
eval_eq('binary', { '\nabc\ndef\n' }, '"\\0abc\\0def\\0"')
|
||||
eval_eq('binary', { 'abc\n\n\ndef' }, '"abc\\0\\0\\0def"')
|
||||
eval_eq('binary', { 'abc\n', '\ndef' }, '"abc\\0\\n\\0def"')
|
||||
eval_eq('binary', { 'abc', '', '', 'def' }, '"abc\\n\\n\\ndef"')
|
||||
eval_eq('binary', { 'abc', '', '', 'def', '' }, '"abc\\n\\n\\ndef\\n"')
|
||||
eval_eq('binary', { '', 'abc', '', '', 'def' }, '"\\nabc\\n\\n\\ndef"')
|
||||
eval_eq('binary', { '' }, '""')
|
||||
eval_eq('binary', { '"' }, '"\\""')
|
||||
eval_eq('binary', { 'py3 print(sys.version_info)' }, '"py3 print(sys.version_info)"')
|
||||
end)
|
||||
|
||||
it('correctly loads strings', function()
|
||||
eval_eq('string', { 'abcdef' }, '="abcdef"')
|
||||
eval_eq('string', { 'abc', 'def' }, '="abc\\ndef"')
|
||||
|
@ -68,7 +68,7 @@ describe('autoload/shada.vim', function()
|
||||
endfor
|
||||
return ret
|
||||
elseif type(a:val) == type('')
|
||||
return {'_TYPE': v:msgpack_types.binary, '_VAL': split(a:val, "\n", 1)}
|
||||
return {'_TYPE': v:msgpack_types.string, '_VAL': split(a:val, "\n", 1)}
|
||||
else
|
||||
return a:val
|
||||
endif
|
||||
@ -253,8 +253,7 @@ describe('autoload/shada.vim', function()
|
||||
' + sm magic value "TRUE"',
|
||||
' # Expected integer',
|
||||
' + so offset value "TRUE"',
|
||||
' # Expected binary string',
|
||||
' + sp pattern ="abc"',
|
||||
' + sp pattern "abc"',
|
||||
},
|
||||
([[ [{'type': 1, 'timestamp': 0, 'data': {
|
||||
'sm': 'TRUE',
|
||||
@ -267,7 +266,7 @@ describe('autoload/shada.vim', function()
|
||||
'n': -0x40,
|
||||
'l': -10,
|
||||
'c': 'abc',
|
||||
'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["abc\ndef"]},
|
||||
'f': {'_TYPE': v:msgpack_types.string, '_VAL': ["abc\ndef"]},
|
||||
}}] ]]):gsub('\n', '')
|
||||
)
|
||||
sd2strings_eq(
|
||||
@ -276,15 +275,14 @@ describe('autoload/shada.vim', function()
|
||||
' % Key Description Value',
|
||||
' # Expected no NUL bytes',
|
||||
' + f file name "abc\\0def"',
|
||||
' # Expected array of binary strings',
|
||||
' + rc contents ["abc", ="abc"]',
|
||||
' + rc contents ["abc", "abc"]',
|
||||
' # Expected integer',
|
||||
' + rt type "ABC"',
|
||||
},
|
||||
([[ [{'type': 1, 'timestamp': 0, 'data': {
|
||||
'rt': 'ABC',
|
||||
'rc': ["abc", {'_TYPE': v:msgpack_types.string, '_VAL': ["abc"]}],
|
||||
'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["abc\ndef"]},
|
||||
'f': {'_TYPE': v:msgpack_types.string, '_VAL': ["abc\ndef"]},
|
||||
}}] ]]):gsub('\n', '')
|
||||
)
|
||||
sd2strings_eq(
|
||||
@ -295,7 +293,7 @@ describe('autoload/shada.vim', function()
|
||||
' + rc contents ["abc", "a\\nd\\0"]',
|
||||
},
|
||||
([[ [{'type': 1, 'timestamp': 0, 'data': {
|
||||
'rc': ["abc", {'_TYPE': v:msgpack_types.binary, '_VAL': ["a", "d\n"]}],
|
||||
'rc': ["abc", {'_TYPE': v:msgpack_types.string, '_VAL': ["a", "d\n"]}],
|
||||
}}] ]]):gsub('\n', '')
|
||||
)
|
||||
end)
|
||||
@ -468,7 +466,7 @@ describe('autoload/shada.vim', function()
|
||||
sd2strings_eq({
|
||||
'Replacement string with timestamp ' .. epoch .. ':',
|
||||
' # Unexpected type: map instead of array',
|
||||
' = {="a": [10]}',
|
||||
' = {"a": [10]}',
|
||||
}, { { type = 3, timestamp = 0, data = { a = { 10 } } } })
|
||||
sd2strings_eq(
|
||||
{
|
||||
@ -498,7 +496,7 @@ describe('autoload/shada.vim', function()
|
||||
' - :s replacement string "abc\\0def"',
|
||||
},
|
||||
([[ [{'type': 3, 'timestamp': 0, 'data': [
|
||||
{'_TYPE': v:msgpack_types.binary, '_VAL': ["abc\ndef"]},
|
||||
{'_TYPE': v:msgpack_types.string, '_VAL': ["abc\ndef"]},
|
||||
]}] ]]):gsub('\n', '')
|
||||
)
|
||||
sd2strings_eq(
|
||||
@ -508,7 +506,7 @@ describe('autoload/shada.vim', function()
|
||||
' - :s replacement string "abc\\ndef"',
|
||||
},
|
||||
([[ [{'type': 3, 'timestamp': 0, 'data': [
|
||||
{'_TYPE': v:msgpack_types.binary, '_VAL': ["abc", "def"]},
|
||||
{'_TYPE': v:msgpack_types.string, '_VAL': ["abc", "def"]},
|
||||
]}] ]]):gsub('\n', '')
|
||||
)
|
||||
sd2strings_eq(
|
||||
@ -519,7 +517,7 @@ describe('autoload/shada.vim', function()
|
||||
' - 0',
|
||||
},
|
||||
([[ [{'type': 3, 'timestamp': 0, 'data': [
|
||||
{'_TYPE': v:msgpack_types.binary, '_VAL': ["abc", "def"]},
|
||||
{'_TYPE': v:msgpack_types.string, '_VAL': ["abc", "def"]},
|
||||
0,
|
||||
]}] ]]):gsub('\n', '')
|
||||
)
|
||||
@ -529,7 +527,7 @@ describe('autoload/shada.vim', function()
|
||||
sd2strings_eq({
|
||||
'History entry with timestamp ' .. epoch .. ':',
|
||||
' # Unexpected type: map instead of array',
|
||||
' = {="a": [10]}',
|
||||
' = {"a": [10]}',
|
||||
}, { { type = 4, timestamp = 0, data = { a = { 10 } } } })
|
||||
sd2strings_eq(
|
||||
{
|
||||
@ -682,7 +680,7 @@ describe('autoload/shada.vim', function()
|
||||
},
|
||||
([[ [{'type': 4, 'timestamp': 0, 'data': [
|
||||
4,
|
||||
{'_TYPE': v:msgpack_types.binary, '_VAL': ["abc\ndef"]},
|
||||
{'_TYPE': v:msgpack_types.string, '_VAL': ["abc\ndef"]},
|
||||
]}] ]]):gsub('\n', '')
|
||||
)
|
||||
sd2strings_eq(
|
||||
@ -909,7 +907,7 @@ describe('autoload/shada.vim', function()
|
||||
sd2strings_eq({
|
||||
'Variable with timestamp ' .. epoch .. ':',
|
||||
' # Unexpected type: map instead of array',
|
||||
' = {="a": [10]}',
|
||||
' = {"a": [10]}',
|
||||
}, { { type = 6, timestamp = 0, data = { a = { 10 } } } })
|
||||
sd2strings_eq(
|
||||
{
|
||||
@ -941,7 +939,7 @@ describe('autoload/shada.vim', function()
|
||||
' # Expected more elements in list',
|
||||
},
|
||||
([[ [{'type': 6, 'timestamp': 0, 'data': [
|
||||
{'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]},
|
||||
{'_TYPE': v:msgpack_types.string, '_VAL': ["\n"]},
|
||||
]}] ]]):gsub('\n', '')
|
||||
)
|
||||
sd2strings_eq(
|
||||
@ -952,7 +950,7 @@ describe('autoload/shada.vim', function()
|
||||
' # Expected more elements in list',
|
||||
},
|
||||
([[ [{'type': 6, 'timestamp': 0, 'data': [
|
||||
{'_TYPE': v:msgpack_types.binary, '_VAL': ["foo"]},
|
||||
{'_TYPE': v:msgpack_types.string, '_VAL': ["foo"]},
|
||||
]}] ]]):gsub('\n', '')
|
||||
)
|
||||
sd2strings_eq(
|
||||
@ -963,7 +961,7 @@ describe('autoload/shada.vim', function()
|
||||
' - value NIL',
|
||||
},
|
||||
([[ [{'type': 6, 'timestamp': 0, 'data': [
|
||||
{'_TYPE': v:msgpack_types.binary, '_VAL': ["foo"]},
|
||||
{'_TYPE': v:msgpack_types.string, '_VAL': ["foo"]},
|
||||
{'_TYPE': v:msgpack_types.nil, '_VAL': ["foo"]},
|
||||
]}] ]]):gsub('\n', '')
|
||||
)
|
||||
@ -976,7 +974,7 @@ describe('autoload/shada.vim', function()
|
||||
' - NIL',
|
||||
},
|
||||
([[ [{'type': 6, 'timestamp': 0, 'data': [
|
||||
{'_TYPE': v:msgpack_types.binary, '_VAL': ["foo"]},
|
||||
{'_TYPE': v:msgpack_types.string, '_VAL': ["foo"]},
|
||||
{'_TYPE': v:msgpack_types.nil, '_VAL': ["foo"]},
|
||||
{'_TYPE': v:msgpack_types.nil, '_VAL': ["foo"]},
|
||||
]}] ]]):gsub('\n', '')
|
||||
@ -1041,7 +1039,7 @@ describe('autoload/shada.vim', function()
|
||||
},
|
||||
([[ [{'type': 7, 'timestamp': 0, 'data': {
|
||||
'n': -10,
|
||||
'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]},
|
||||
'f': {'_TYPE': v:msgpack_types.string, '_VAL': ["\n"]},
|
||||
}}] ]]):gsub('\n', '')
|
||||
)
|
||||
sd2strings_eq(
|
||||
@ -1174,7 +1172,7 @@ describe('autoload/shada.vim', function()
|
||||
},
|
||||
([[ [{'type': 8, 'timestamp': 0, 'data': {
|
||||
'n': -10,
|
||||
'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]},
|
||||
'f': {'_TYPE': v:msgpack_types.string, '_VAL': ["\n"]},
|
||||
}}] ]]):gsub('\n', '')
|
||||
)
|
||||
sd2strings_eq(
|
||||
@ -1237,7 +1235,7 @@ describe('autoload/shada.vim', function()
|
||||
sd2strings_eq({
|
||||
'Buffer list with timestamp ' .. epoch .. ':',
|
||||
' # Unexpected type: map instead of array',
|
||||
' = {="a": [10]}',
|
||||
' = {"a": [10]}',
|
||||
}, { { type = 9, timestamp = 0, data = { a = { 10 } } } })
|
||||
sd2strings_eq({
|
||||
'Buffer list with timestamp ' .. epoch .. ':',
|
||||
@ -1247,7 +1245,7 @@ describe('autoload/shada.vim', function()
|
||||
sd2strings_eq({
|
||||
'Buffer list with timestamp ' .. epoch .. ':',
|
||||
' # Expected array of maps',
|
||||
' = [{="a": 10}, []]',
|
||||
' = [{"a": 10}, []]',
|
||||
}, { { type = 9, timestamp = 0, data = { { a = 10 }, {} } } })
|
||||
sd2strings_eq({
|
||||
'Buffer list with timestamp ' .. epoch .. ':',
|
||||
@ -1322,7 +1320,7 @@ describe('autoload/shada.vim', function()
|
||||
},
|
||||
([[ [{'type': 9, 'timestamp': 0, 'data': [
|
||||
{'f': 10},
|
||||
{'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]}},
|
||||
{'f': {'_TYPE': v:msgpack_types.string, '_VAL': ["\n"]}},
|
||||
]}] ]]):gsub('\n', '')
|
||||
)
|
||||
end)
|
||||
@ -1385,7 +1383,7 @@ describe('autoload/shada.vim', function()
|
||||
},
|
||||
([[ [{'type': 10, 'timestamp': 0, 'data': {
|
||||
'n': -10,
|
||||
'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]},
|
||||
'f': {'_TYPE': v:msgpack_types.string, '_VAL': ["\n"]},
|
||||
}}] ]]):gsub('\n', '')
|
||||
)
|
||||
sd2strings_eq(
|
||||
@ -1504,7 +1502,7 @@ describe('autoload/shada.vim', function()
|
||||
},
|
||||
([[ [{'type': 11, 'timestamp': 0, 'data': {
|
||||
'n': -10,
|
||||
'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]},
|
||||
'f': {'_TYPE': v:msgpack_types.string, '_VAL': ["\n"]},
|
||||
}}] ]]):gsub('\n', '')
|
||||
)
|
||||
sd2strings_eq(
|
||||
@ -1616,7 +1614,7 @@ describe('autoload/shada.vim', function()
|
||||
timestamp = 0,
|
||||
data = {
|
||||
c = 'abc',
|
||||
f = { '!binary', { 'abc\ndef' } },
|
||||
f = { '!string', { 'abc\ndef' } },
|
||||
l = -10,
|
||||
n = -64,
|
||||
rc = '10',
|
||||
@ -1711,7 +1709,7 @@ describe('autoload/shada.vim', function()
|
||||
timestamp = 0,
|
||||
data = {
|
||||
c = 'abc',
|
||||
f = { '!binary', { 'abc\ndef' } },
|
||||
f = { '!string', { 'abc\ndef' } },
|
||||
l = -10,
|
||||
n = -64,
|
||||
rc = '10',
|
||||
@ -1892,7 +1890,7 @@ describe('autoload/shada.vim', function()
|
||||
} } }, {
|
||||
'Replacement string with timestamp ' .. epoch .. ':',
|
||||
' # Unexpected type: map instead of array',
|
||||
' = {="a": [10]}',
|
||||
' = {"a": [10]}',
|
||||
})
|
||||
strings2sd_eq({ { type = 3, timestamp = 0, data = {} } }, {
|
||||
'Replacement string with timestamp ' .. epoch .. ':',
|
||||
@ -1934,7 +1932,7 @@ describe('autoload/shada.vim', function()
|
||||
} } }, {
|
||||
'History entry with timestamp ' .. epoch .. ':',
|
||||
' # Unexpected type: map instead of array',
|
||||
' = {="a": [10]}',
|
||||
' = {"a": [10]}',
|
||||
})
|
||||
strings2sd_eq({ { type = 4, timestamp = 0, data = {} } }, {
|
||||
'History entry with timestamp ' .. epoch .. ':',
|
||||
@ -2184,7 +2182,7 @@ describe('autoload/shada.vim', function()
|
||||
} } }, {
|
||||
'Variable with timestamp ' .. epoch .. ':',
|
||||
' # Unexpected type: map instead of array',
|
||||
' = {="a": [10]}',
|
||||
' = {"a": [10]}',
|
||||
})
|
||||
strings2sd_eq({ { type = 6, timestamp = 0, data = {} } }, {
|
||||
'Variable with timestamp ' .. epoch .. ':',
|
||||
@ -2315,7 +2313,7 @@ describe('autoload/shada.vim', function()
|
||||
} } }, {
|
||||
'Buffer list with timestamp ' .. epoch .. ':',
|
||||
' # Unexpected type: map instead of array',
|
||||
' = {="a": [10]}',
|
||||
' = {"a": [10]}',
|
||||
})
|
||||
strings2sd_eq(
|
||||
{ { type = 9, timestamp = 0, data = {
|
||||
@ -2325,7 +2323,7 @@ describe('autoload/shada.vim', function()
|
||||
{
|
||||
'Buffer list with timestamp ' .. epoch .. ':',
|
||||
' # Expected array of maps',
|
||||
' = [{="a": 10}, []]',
|
||||
' = [{"a": 10}, []]',
|
||||
}
|
||||
)
|
||||
strings2sd_eq({ { type = 9, timestamp = 0, data = {
|
||||
@ -2421,7 +2419,7 @@ describe('autoload/shada.vim', function()
|
||||
timestamp = 0,
|
||||
data = {
|
||||
{ f = 10 },
|
||||
{ f = { '!binary', { '\n' } } },
|
||||
{ f = { '!string', { '\n' } } },
|
||||
},
|
||||
},
|
||||
}, {
|
||||
@ -2955,7 +2953,7 @@ describe('ftplugin/shada.vim', function()
|
||||
' - :s replacement string "abc\\ndef"',
|
||||
' Buffer list with timestamp ' .. epoch .. ':',
|
||||
' # Expected array of maps',
|
||||
'= [{="a": 10}, []]',
|
||||
'= [{"a": 10}, []]',
|
||||
' Buffer list with timestamp ' .. epoch .. ':',
|
||||
' % Key Description Value',
|
||||
' # Expected binary string',
|
||||
@ -2992,7 +2990,7 @@ describe('ftplugin/shada.vim', function()
|
||||
' - :s replacement string "abc\\ndef"',
|
||||
'Buffer list with timestamp ' .. epoch .. ':',
|
||||
' # Expected array of maps',
|
||||
' = [{="a": 10}, []]',
|
||||
' = [{"a": 10}, []]',
|
||||
'Buffer list with timestamp ' .. epoch .. ':',
|
||||
' % Key Description Value',
|
||||
' # Expected binary string',
|
||||
@ -3083,7 +3081,7 @@ describe('syntax/shada.vim', function()
|
||||
' - :s replacement string DEBUG',
|
||||
'Buffer list with timestamp ' .. epoch .. ':',
|
||||
' # Expected array of maps',
|
||||
' = [{="a": +(10)"ac\\0df\\ngi\\"tt\\.", TRUE: FALSE}, [NIL, +(-10)""]]',
|
||||
' = [{"a": +(10)"ac\\0df\\ngi\\"tt\\.", TRUE: FALSE}, [NIL, +(-10)""]]',
|
||||
'Buffer list with timestamp ' .. epoch .. ':',
|
||||
' % Key Description Value',
|
||||
'',
|
||||
@ -3119,8 +3117,8 @@ describe('syntax/shada.vim', function()
|
||||
{1: -} {4::s replacement string} {1:DEBUG} |
|
||||
{1:Buffer list} with timestamp 1970{1:-}01{1:-}01{1:T}00{1::}00{1::}00: |
|
||||
{4: # Expected array of maps} |
|
||||
= {1:[{="}{3:a}{1:":} {1:+(}{5:10}{1:)"}{3:ac}{6:\0}{3:df}{6:\n}{3:gi}{6:\"}{3:tt\.}{1:",} {1:TRUE:} {1:FALSE},} {1:[NIL,} {1:+(}{5:-}|
|
||||
{5:10}{1:)""]]} |
|
||||
= {1:[{"}{3:a}{1:":} {1:+(}{5:10}{1:)"}{3:ac}{6:\0}{3:df}{6:\n}{3:gi}{6:\"}{3:tt\.}{1:",} {1:TRUE:} {1:FALSE},} {1:[NIL,} {1:+(}{5:-1}|
|
||||
{5:0}{1:)""]]} |
|
||||
{1:Buffer list} with timestamp 1970{1:-}01{1:-}01{1:T}00{1::}00{1::}00: |
|
||||
{2: % Key Description Value} |
|
||||
|
|
||||
@ -3464,7 +3462,6 @@ describe('syntax/shada.vim', function()
|
||||
{ { 'ShaDaEntryRawMsgpack' }, ' = ' },
|
||||
{ { 'ShaDaMsgpackArray', 'ShaDaMsgpackArrayBraces' }, '[' },
|
||||
{ { 'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackMapBraces' }, '{' },
|
||||
{ { 'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackString' }, '=' },
|
||||
{
|
||||
{
|
||||
'ShaDaMsgpackArray',
|
||||
|
@ -502,9 +502,9 @@ describe('json_decode() function', function()
|
||||
end
|
||||
|
||||
it('parses strings with NUL properly', function()
|
||||
sp_decode_eq({ _TYPE = 'string', _VAL = { '\n' } }, '"\\u0000"')
|
||||
sp_decode_eq({ _TYPE = 'string', _VAL = { '\n', '\n' } }, '"\\u0000\\n\\u0000"')
|
||||
sp_decode_eq({ _TYPE = 'string', _VAL = { '\n«\n' } }, '"\\u0000\\u00AB\\u0000"')
|
||||
sp_decode_eq('\000', '"\\u0000"')
|
||||
sp_decode_eq('\000\n\000', '"\\u0000\\n\\u0000"')
|
||||
sp_decode_eq('\000«\000', '"\\u0000\\u00AB\\u0000"')
|
||||
end)
|
||||
|
||||
it('parses dictionaries with duplicate keys to special maps', function()
|
||||
@ -580,14 +580,8 @@ describe('json_decode() function', function()
|
||||
end)
|
||||
|
||||
it('parses dictionaries with keys with NUL bytes to special maps', function()
|
||||
sp_decode_eq(
|
||||
{ _TYPE = 'map', _VAL = { { { _TYPE = 'string', _VAL = { 'a\n', 'b' } }, 4 } } },
|
||||
'{"a\\u0000\\nb": 4}'
|
||||
)
|
||||
sp_decode_eq(
|
||||
{ _TYPE = 'map', _VAL = { { { _TYPE = 'string', _VAL = { 'a\n', 'b', '' } }, 4 } } },
|
||||
'{"a\\u0000\\nb\\n": 4}'
|
||||
)
|
||||
sp_decode_eq({ _TYPE = 'map', _VAL = { { 'a\000\nb', 4 } } }, '{"a\\u0000\\nb": 4}')
|
||||
sp_decode_eq({ _TYPE = 'map', _VAL = { { 'a\000\nb\n', 4 } } }, '{"a\\u0000\\nb\\n": 4}')
|
||||
sp_decode_eq({
|
||||
_TYPE = 'map',
|
||||
_VAL = {
|
||||
@ -595,10 +589,7 @@ describe('json_decode() function', function()
|
||||
{ 'a', 1 },
|
||||
{ 'c', 4 },
|
||||
{ 'd', 2 },
|
||||
{
|
||||
{ _TYPE = 'string', _VAL = { '\n' } },
|
||||
4,
|
||||
},
|
||||
{ '\000', 4 },
|
||||
},
|
||||
}, '{"b": 3, "a": 1, "c": 4, "d": 2, "\\u0000": 4}')
|
||||
end)
|
||||
@ -738,22 +729,11 @@ describe('json_encode() function', function()
|
||||
eq('{"\\u0000": 1}', eval('json_encode(todump)'))
|
||||
end)
|
||||
|
||||
it('can dump generic mapping with BIN special key and NUL', function()
|
||||
command('let todump = {"_TYPE": v:msgpack_types.binary, "_VAL": ["\\n"]}')
|
||||
command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[todump, 1]]}')
|
||||
eq('{"\\u0000": 1}', eval('json_encode(todump)'))
|
||||
end)
|
||||
|
||||
it('can dump STR special mapping with NUL and NL', function()
|
||||
command('let todump = {"_TYPE": v:msgpack_types.string, "_VAL": ["\\n", ""]}')
|
||||
eq('"\\u0000\\n"', eval('json_encode(todump)'))
|
||||
end)
|
||||
|
||||
it('can dump BIN special mapping with NUL and NL', function()
|
||||
command('let todump = {"_TYPE": v:msgpack_types.binary, "_VAL": ["\\n", ""]}')
|
||||
eq('"\\u0000\\n"', eval('json_encode(todump)'))
|
||||
end)
|
||||
|
||||
it('cannot dump special ext mapping', function()
|
||||
command('let todump = {"_TYPE": v:msgpack_types.ext, "_VAL": [5, ["",""]]}')
|
||||
eq('Vim(call):E474: Unable to convert EXT string to JSON', exc_exec('call json_encode(todump)'))
|
||||
|
@ -371,13 +371,14 @@ describe('msgpack*() functions', function()
|
||||
eq(1, eval('dumped ==# dumped2'))
|
||||
end)
|
||||
|
||||
it('can restore and dump STR string with zero byte', function()
|
||||
it('can restore and dump STR string contents with zero byte', function()
|
||||
command('let dumped = ["\\xA1\\n"]')
|
||||
command('let parsed = msgpackparse(dumped)')
|
||||
command('let dumped2 = msgpackdump(parsed)')
|
||||
eq({ { _TYPE = {}, _VAL = { '\n' } } }, eval('parsed'))
|
||||
eq(1, eval('parsed[0]._TYPE is v:msgpack_types.string'))
|
||||
eq(1, eval('dumped ==# dumped2'))
|
||||
eq({ '\000' }, eval('parsed'))
|
||||
eq(eval('v:t_blob'), eval('type(parsed[0])'))
|
||||
-- type is not preserved: prefer BIN for binary contents
|
||||
eq(0, eval('dumped ==# dumped2'))
|
||||
end)
|
||||
|
||||
it('can restore and dump BIN string with NL', function()
|
||||
@ -428,9 +429,8 @@ describe('msgpackparse() function', function()
|
||||
parse_eq({ true }, { '\195' })
|
||||
end)
|
||||
|
||||
it('restores FIXSTR as special dict', function()
|
||||
parse_eq({ { _TYPE = {}, _VAL = { 'ab' } } }, { '\162ab' })
|
||||
eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.string'))
|
||||
it('restores FIXSTR as string', function()
|
||||
parse_eq({ 'ab' }, { '\162ab' })
|
||||
end)
|
||||
|
||||
it('restores BIN 8 as string', function()
|
||||
@ -442,9 +442,8 @@ describe('msgpackparse() function', function()
|
||||
eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.ext'))
|
||||
end)
|
||||
|
||||
it('restores MAP with BIN key as special dictionary', function()
|
||||
parse_eq({ { _TYPE = {}, _VAL = { { 'a', '' } } } }, { '\129\196\001a\196\n' })
|
||||
eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.map'))
|
||||
it('restores MAP with BIN key as ordinary dictionary', function()
|
||||
parse_eq({ { a = '' } }, { '\129\196\001a\196\n' })
|
||||
end)
|
||||
|
||||
it('restores MAP with duplicate STR keys as special dictionary', function()
|
||||
@ -455,14 +454,14 @@ describe('msgpackparse() function', function()
|
||||
{
|
||||
_TYPE = {},
|
||||
_VAL = {
|
||||
{ { _TYPE = {}, _VAL = { 'a' } }, '' },
|
||||
{ { _TYPE = {}, _VAL = { 'a' } }, '' },
|
||||
{ 'a', '' },
|
||||
{ 'a', '' },
|
||||
},
|
||||
},
|
||||
}, eval('parsed'))
|
||||
eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.map'))
|
||||
eq(1, eval('g:parsed[0]._VAL[0][0]._TYPE is v:msgpack_types.string'))
|
||||
eq(1, eval('g:parsed[0]._VAL[1][0]._TYPE is v:msgpack_types.string'))
|
||||
eq(eval('v:t_string'), eval('type(g:parsed[0]._VAL[0][0])'))
|
||||
eq(eval('v:t_string'), eval('type(g:parsed[0]._VAL[1][0])'))
|
||||
end)
|
||||
|
||||
it('restores MAP with MAP key as special dictionary', function()
|
||||
@ -802,7 +801,7 @@ describe('msgpackdump() function', function()
|
||||
|
||||
it('can dump NULL string', function()
|
||||
dump_eq({ '\196\n' }, '[$XXX_UNEXISTENT_VAR_XXX]')
|
||||
dump_eq({ '\196\n' }, '[{"_TYPE": v:msgpack_types.binary, "_VAL": [$XXX_UNEXISTENT_VAR_XXX]}]')
|
||||
dump_eq({ '\196\n' }, '[v:_null_blob]')
|
||||
dump_eq({ '\160' }, '[{"_TYPE": v:msgpack_types.string, "_VAL": [$XXX_UNEXISTENT_VAR_XXX]}]')
|
||||
end)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user