VIM 参考手册 by Bram Moolenaar
译者: Willis
测试 Vim 和 Vim 脚本 testing-support
表达式求值见 eval.txt 。本文档详述如何使用 Vim 脚本编写测试。既可用于 Vim 自
身测试,也可用于插件测试。
1. 测试 Vim testing
2. 测试函数 test-functions-details
3. 断言函数 assert-functions-details
1. 测试 Vim testing
Vim 在编译完成后,可执行测试,通常使用 "make test"。测试文件位于目录 "src/testdir"。 在不同时间点,引入了两类测试: test20.in 老风格测试,仅用于精简编译版本 test_something.vim 新风格测试 new-style-testing 新增测试必须使用新风格。测试脚本命名方式为 test_<feature>.vim (<feature> 替换
为待测功能名)。这类测试脚本使用 assert_equal() 等函数,将测试命令和预期结果
放在一处。
old-style-testing
老风格测试仅用于测试不带 +eval 特性的 Vim。
更多信息详见 src/testdir/README.txt 文档。
2. 测试函数 test-functions-details
test_alloc_fail({id}, {countdown}, {repeat}) test_alloc_fail()
用于测试: 每次调用编号 {id} 的内存分配时,{countdown} 都会减
一,计数归零后,内存分配会失败 {repeat} 次。如果 {repeat} 小于
一,使用一次失败次数。
也可用作 method :
GetAllocId()->test_alloc_fail()
返回类型: 无
test_autochdir() test_autochdir()
设置标志位,在 Vim 启动完成前启用 'autochdir' 的效果。
返回类型: 无
test_feedinput({string}) test_feedinput()
将 {string} 中的字符加入输入队列,按照用户手动键入的方式进行处
理。此功能使用底层输入缓冲区。
{仅当编译时加入 +unix 或在 GUI 环境下可用}
也可用作 method :
GetText()->test_feedinput()
返回类型: 无
test_garbagecollect_now() test_garbagecollect_now()
类似 garbagecollect() ,但立即执行。只能直接调用,防止内部残
留数据结构,调用任何函数前必须先置位 v:testing 。 E1142
不能在 :def 函数内调用,因为栈变量会被释放。
返回类型: 无
test_garbagecollect_soon() test_garbagecollect_soon()
设置内部标志位,使垃圾回收器像在主循环中一样被调用。仅用于测
试。
返回类型: 无
test_getvalue({name}) test_getvalue()
获取内部变量值。目前支持以下 {name} 值:
need_fileinfo
也可用作 method :
GetName()->test_getvalue()
返回类型: Number
test_gui_event()
test_gui_event({event}, {args})
生成带参数 {args} 的 GUI {event},用于测试 Vim 功能。仅在 GUI
运行时可用。
{event} 为字符串,可选值是:
"dropfiles" 在窗口放置一或多个文件
"findrepl" 搜索和替代文本
"mouse" 鼠标按键点击
"scrollbar" 移动或拖动滚动条
"key" 底层键盘按放事件
"tabline" 鼠标点击选中标签页
"tabmenu" 选中标签栏菜单项
{args} 为存放事件所需参数的字典。
"dropfiles":
{仅当编译时加入 drop_file 特性才有效}
在指定窗口放置一或多个文件。{args} 可用项为:
files: 文件名列表
row: 窗口行号
col: 窗口列号
modifiers: 按键修饰符。可选值:
0x4 Shift
0x8 Alt
0x10 Ctrl
会将所有文件加入 argument-list ,窗口会编辑 {files} 中首个
文件。详见 drag-n-drop 。
"findrepl":
{仅当 GUI 提供查找/替代对话框时才可用}
执行文本搜索和替代。{args} 可用项为:
find_text: 待搜索文本
repl_text: 替代文本
flags: 搜索/替代控制标志位。可选值:
1 搜索下一项 (搜索对话框)
2 搜索下一项 (替代对话框)
3 单次替代
4 全部替代
8 仅匹配完整单词
16 区分大小写
forward: 为 1 则搜索方向为正向
"mouse":
鼠标按钮点击或鼠标移动。{args} 可用项为:
button: 鼠标按键。可选值:
0 鼠标左键
1 鼠标中键
2 鼠标右键
3 释放鼠标键
4 滚轮下滚
5 滚轮上滚
6 滚轮左滚
7 滚轮右滚
row: 点击行号。Vim 窗口首行为 1,末行为 'lines'
col: 点击列号。最大值为 'columns'
multiclick: 为 1 代表注入多次点击事件
modifiers: 按键修饰符。可选值:
4 按下 Shift
8 按下 Alt
16 按下 Ctrl
move: 可选;给出且为 TRUE 时,生成鼠标移动事件。
仅使用且必须提供 row 和 col 值,坐标单位由
"cell" 决定,可为像素或屏幕单元格。
仅当 'mousemoveevent' 开启,或有任意弹窗监听鼠
标移动事件时,此事件才会发送。
cell: 可选: 给出且为 TRUE 时,"move" 使用屏幕单元格
而非像素坐标
"scrollbar":
设置或拖动左侧、右侧或水平滚动条。仅当滚动条实际存在时才可
用。{args} 可用项为:
which: 选择滚动条。可选值:
left 当前窗口的左侧滚动条
right 当前窗口的右侧滚动条
hor 水平滚动条
value: 滚动量。对垂直滚动条,{value} 取值范围为 0 到
缓冲区总行数减一。假定 'wrap' 未置位,对水平滚
动条,{value} 取值范围为 1 到最长行长度
dragging: 为 1 则拖动滚动条,为 0 则点击滚动条
"key":
{仅支持 MS-Windows}
底层键盘事件 (如释放或按下按键)。
{args} 可用项为:
event: 可选值:
keyup 生成按键释放事件
keydown 生成按键按下事件
keycode: 用于按键释放/按下事件的键码
E1291
"tabline":
鼠标点击标签栏,选中标签页。{args} 可用项为:
tabnr: 标签页号
"tabmenu":
选中标签栏菜单项。{args} 可用项为:
tabnr: 标签页号
item: 标签页菜单项号。1 为首个菜单项,2 为第二个,依
此类推
注入 GUI 事件后,一般需要调用 feedkeys() 处理事件,示例:
call feedkeys("y", 'Lx!')
事件添加成功返回 TRUE,如果失败则返回 FALSE。
也可用作 method :
GetEvent()->test_gui_event({args})
返回类型: vim9-boolean
test_ignore_error({expr}) test_ignore_error()
忽略所有包含 {expr} 的错误。改为显示普通提示消息。
仅用于测试,适用于无法使用 try/catch 捕获错误的情况 (因为这样
会跳过后续代码)。
{expr} 按本义使用,不作为模式处理。
{expr} 为字符串 "RESET" 时,清空被忽略的错误列表。
也可用作 method :
GetErrorText()->test_ignore_error()
返回类型: 无
test_mswin_event({event}, {args}) test_mswin_event()
{仅支持 MS-Windows GUI 和控制台}
生成带参数 {args} 的底层 MS-Windows 事件 {event},用于测试 Vim
功能。
{event} 可选值:
"mouse" 鼠标事件
"key" 键盘事件
"set_keycode_trans_strategy"
修改键码转换方式
"mouse":
鼠标按钮点击或鼠标移动事件。{args} 可用项为:
button: 鼠标按键。可选值:
0 鼠标右键
1 鼠标中键
2 鼠标左键
3 释放鼠标键
4 滚轮下滚
5 滚轮上滚
6 滚轮左滚
7 滚轮右滚
row: 点击行号。Vim 窗口首行为 1,末行为 'lines'
col: 点击列号。最大值为 'columns'。
注意: 对控制台应用,row 和 col 总使用屏幕单元
格。而对 GUI,坐标单位由 "cell" 决定,可为像素
或屏幕单元格。
multiclick: 为 1 代表注入多次点击事件
modifiers: 按键修饰符。可选值:
4 按下 Shift
8 按下 Alt
16 按下 Ctrl
move: 可选;给出且为 TRUE 时,生成鼠标移动事件。
仅使用且必须提供 row 和 col 值。
仅当 'mousemoveevent' 开启,或有任意弹窗监听鼠
标移动事件时,此事件才会发送。
cell: GUI 可选: 给出且为 TRUE 时,"move" 使用屏幕单
元格而非像素坐标。控制台不使用此设置。
"key":
底层键盘事件 (如释放或按下按键)。
{args} 可用项为:
event: 可选值:
keyup 生成按键释放事件
keydown 生成按键按下事件
keycode: 用于按键释放/按下事件的键码
modifiers: 可选;按键修饰符。可选值:
2 按下 Shift
4 按下 Ctrl
8 按下 Alt
注意: 该修饰符数值与鼠标修饰符不同。
execute: 可选。类似 feedkeys() 的 x 模式。给出且为真
(非零) 时,Vim 会处理所有缓冲未处理 (预输入)
的键盘事件。此时其余 {args} 项目可选。
"set_keycode_trans_strategy":
w32-experimental-keycode-trans-strategy
修改键码转换方式。可选值:
experimental: v8.2.4807 补丁之后的方案,调用 Win API
ToUnicode()。
classic: v8.2.4807 补丁之前的方案,调用 Win API
TranslateMessage()。
事件添加或执行成功则返回 TRUE,如果失败则返回 FALSE。
也可用作 method :
GetEvent()->test_mswin_event({args})
返回类型: vim9-boolean
test_null_blob() test_null_blob()
返回 null Blob 。仅用于测试。
返回类型: Blob
test_null_channel() test_null_channel()
{仅当编译时加入 +channel 特性才有效}
返回 null Channel 。仅用于测试。
返回类型: Channel
test_null_dict() test_null_dict()
返回 null Dict 。仅用于测试。
返回类型: dict<any>
test_null_function() test_null_function()
返回 null Funcref 。仅用于测试。
返回类型: func(...): unknown
test_null_job() test_null_job()
{仅当编译时加入 +job 特性才有效}
返回 null Job 。仅用于测试。
返回类型: job
test_null_list() test_null_list()
返回 null List 。仅用于测试。
返回类型: list<any>
test_null_partial() test_null_partial()
返回 null Partial 。仅用于测试。
返回类型: func(...): unknown
test_null_string() test_null_string()
返回 null String 。仅用于测试。
返回类型: String
test_null_tuple() test_null_tuple()
返回 null Tuple 。仅用于测试。
返回类型: Tuple
test_option_not_set({name}) test_option_not_set()
复位指示选项 {name} 已设置的标志位。即使选项已有修改,其行为仍
视同缺省值。示例:
set ambiwidth=double
call test_option_not_set('ambiwidth')
此时 'ambiwidth' 选项实际值为 "double",但行为视同未被修改过。
仅用于测试!
也可用作 method :
GetOptionName()->test_option_not_set()
返回类型: 无
test_override({name}, {val}) test_override()
覆盖 Vim 部分内部逻辑,方便运行测试。仅用于 Vim 测试!
{val} 非零时,启用覆盖行为,{val} 为零时,关闭覆盖行为。
{name} 目前可用值为:
{name} {val} 非零时效果
alloc_lines 复制所有缓冲区行到分配内存,方便 valgrind 捕获内
存访问错误。
autoload `import autoload` 会立即加载脚本,不延迟到首次使
用时再加载。
char_avail 禁用 char_avail() 函数。
defcompile 加载脚本时,所有其中的 :def 函数会在定义时直接
编译。类似脚本内执行 :defcompile 命令。
nfa_fail 使 NFA 正则表达式引擎失败,强制回退到老式引擎
no_query_mouse "dec" 终端不查询鼠标位置。
no_wait_return 置位 "no_wait_return" (不等待回车) 标志位。不
会被 "ALL" 复位。
redraw 禁用 redrawing() 函数。
redraw_flag 忽略 RedrawingDisabled (暂停重绘) 标志位。
starting 复位 "starting" 变量,见下。
syn_idlist_cache
禁用语法 "contains"/簇列表解析缓存。
term_props 检测版本应答字符串时,复位所有终端属性。
ui_delay 设置 ui_delay() 的毫秒时长;对消息等待,覆盖缺省
3 秒超时。
unreachable :throw 和 :return 之后的代码不再报错。
uptime 覆盖 sysinfo.uptime。
vterm_title 禁止终端中运行的作业修改窗口标题。
ALL 清除 alloc_lines 外的所有覆盖项 (忽略 {val})。
(译者注: 除 alloc_lines 外,也不清除以下项目:
autoload、defcompile、no_wait_return、
unreachable、vert_title)
"starting" 用于让测试模拟初始化完成后的环境。测试执行时会加载
将 "starting" 变量设为非零值的脚本。此设置通常有助于加速测试,
但部分场景会改变实际行为,导致测试异常。以下操作:
call test_override('starting', 1)
会保存 "starting" 值,然后将其清零 (即初始化已完成)。以下操作
则恢复原值:
call test_override('starting', 0)
可用 :defer 保证标志位在使用后自动复位:
call test_override('unreachable', 1)
defer call test_override('unreachable', 0)
也可用作 method :
GetOverrideVal()-> test_override('starting')
返回类型: 无
test_refcount({expr}) test_refcount()
返回 {expr} 的引用计数。如果 {expr} 所属类型无引用计数,返回
-1。仅用于测试。
也可用作 method :
GetVarname()->test_refcount()
返回类型: Number
test_setmouse({row}, {col}) test_setmouse()
设置下次鼠标动作所用的鼠标位置。
{row} 和 {col} 从 1 开始计数。
示例:
call test_setmouse(4, 20)
call feedkeys("\<LeftMouse>", "xt")
返回类型: 无
test_settime({expr}) test_settime()
设置 Vim 内部使用的时间。当前仅用于历史记录的时间戳 (用于
viminfo) 以及撤销功能。
{expr} 计算结果必须为数值。
值为 1 时,Vim 在给出警告或错误信息后,不再休眠。
值为零则恢复默认行为。
也可用作 method :
GetTime()->test_settime()
返回类型: 无
test_srand_seed([{seed}]) test_srand_seed()
[seed] 给出时,设置 srand() 使用的种子值。省略时则删除测试用
种子。
返回类型: 无
test_unknown() test_unknown()
返回一个未知类型值。仅用于测试。
返回类型: unknown
test_void() test_void()
返回一个 void 类型值。仅用于测试。
返回类型: 无
3. 断言函数 assert-functions-details
assert_beeps({cmd}) assert_beeps()
执行 {cmd},命令 不 产生响铃或可视响铃时,向 v:errors 添加错
误信息。
另见 assert_fails() 、 assert_nobeep() 和 assert-return 。
也可用作 method :
GetCmd()->assert_beeps()
返回类型: Number
assert_equal()
assert_equal({expected}, {actual} [, {msg}])
{expected} 不等于 {actual} 时,向 v:errors 添加错误信息并返
回 1。否则返回零。 assert-return
错误信息格式为 "Expected {expected} but got {actual}"。{msg}
给出时,加到错误信息开头。从脚本调用时,开头还会附带断言所在位
置。
没有自动类型转换,字符串 "4" 不同于数值 4。数值 4 也不同于浮点
数 4.0。不使用 'ignorecase' 设置,大小写永远敏感。
示例:
call assert_equal('foo', 'bar', 'baz')
会向 v:errors 写入以下信息:
test.vim line 12: baz: Expected 'foo' but got 'bar'
也可用作 method ,基是作为第二个参数传递的:
mylist->assert_equal([1, 2, 3])
返回类型: Number
assert_equalfile()
assert_equalfile({fname-one}, {fname-two} [, {msg}])
文件 {fname-one} 和 {fname-two} 文本不完全一致时,向
v:errors 添加错误信息。另见 assert-return 。
如果文件 {fname-one} 或 {fname-two} 不存在,错误信息会指明该情
况。
主要配合 terminal-diff 使用。
也可用作 method :
GetLog()->assert_equalfile('expected.log')
返回类型: Number
assert_exception({error} [, {msg}]) assert_exception()
v:exception 不包含字符串 {error} 时,向 v:errors 添加错误
信息。另见 assert-return 。
用于断言命令抛出异常。建议使用错误号加冒号,可规避语言翻译带来
的匹配问题:
try
commandthatfails
call assert_false(1, '命令本应失败')
catch
call assert_exception('E492:')
endtry
返回类型: Number
assert_fails()
assert_fails({cmd} [, {error} [, {msg} [, {lnum} [, {context}]]]])
执行 {cmd},命令 不 产生错误或错误信息中找不到 {error} 时,向
v:errors 添加错误信息。另见 assert-return 。
E856
{error} 为字符串时,必须在第一条错误信息中按本义匹配。通常使用
错误码加冒号,例如 "E123:"。
call assert_fails('bad cmd', 'E987:')
{error} 为包含一到两个字符串的列表时,作为一对模式处理。第一个
模式需要匹配第一条错误信息:
call assert_fails('cmd', ['E987:.*预期 bool'])
第二个模式 (如有) 需要匹配最后一条错误信息。
仅产生一条错误信息时,两个模式必须都匹配。可用于检查是否仅出现
一条错误。
要只匹配最后一条错误信息,首错模式可用空串:
call assert_fails('cmd', ['', 'E987:'])
{msg} 为空时不使用。此参数传入空串可用于传入后面的 {lnum} 参数
并获取缺省信息。
E1115
{lnum} 给出且非负时,如果 {error} 参数给出且匹配成功,会比对错
误报告所在行号。行号可以是函数内或脚本内的行号。
E1116
{context} 给出时,会用作模式,匹配 {lnum} 所在上下文 (即脚本名
或函数名)。
注意 响铃不算错误,而部分失败命令只会触发响铃。这类场景可改用
assert_beeps() 断言。
也可用作 method :
GetCmd()->assert_fails('E99:')
返回类型: Number
assert_false({actual} [, {msg}]) assert_false()
{actual} 不为假时,向 v:errors 添加错误信息,其余行为类同
assert_equal() 。
错误信息格式为 "Expected False but got {actual}"。{msg} 给出
时,加到错误信息开头。从脚本调用时,开头还会附带断言所在位置。
另见 assert-return 。
零值视作假值。如果 {actual} 不是数值,断言失败。
也可用作 method :
GetResult()->assert_false()
返回类型: Number
assert_inrange({lower}, {upper}, {actual} [, {msg}]) assert_inrange()
对数值和 Float 值进行断言。{actual} 小于 {lower}、或大于
{upper} 时,向 v:errors 添加错误信息。另见 assert-return 。
错误信息格式为
"Expected range {lower} - {upper}, but got {actual}"。{msg} 给
出时,加到错误信息开头。
返回类型: Number
assert_match()
assert_match({pattern}, {actual} [, {msg}])
模式 {pattern} 不匹配 {actual} 时,向 v:errors 添加错误信
息。另见 assert-return 。
错误信息格式为 "Pattern {pattern} does not match {actual}"。
{msg} 给出时,加到错误信息开头。从脚本调用时,开头还会附带断言
所在位置。
{pattern} 的匹配规则同 =~ : 匹配总是假定 'magic' 置位而
'cpoptions' 为空,忽略 'magic' 或 'cpoptions' 的实际值。
{actual} 视为字符串,必要时会进行自动转换。
"^" 和 "$" 分别匹配文本的首尾。两者同时使用可匹配完整文本。
示例:
call assert_match('^f.*o$', 'foobar')
会向 v:errors 写入以下信息:
test.vim line 12: Pattern '^f.*o$' does not match 'foobar'
也可用作 method :
getFile()->assert_match('foo.*')
返回类型: Number
assert_nobeep({cmd}) assert_nobeep()
执行 {cmd},命令产生响铃或可视响铃时,向 v:errors 添加错误信
息。
另见 assert_beeps() 。
也可用作 method :
GetCmd()->assert_nobeep()
返回类型: Number
assert_notequal()
assert_notequal({expected}, {actual} [, {msg}])
assert_equal() 的反向断言: {expected} 等于 {actual} 时,向
v:errors 添加错误信息。
另见 assert-return 。
也可用作 method :
mylist->assert_notequal([1, 2, 3])
返回类型: Number
assert_notmatch()
assert_notmatch({pattern}, {actual} [, {msg}])
assert_match() 的反向断言: {pattern} 匹配 {actual} 时,向
v:errors 添加错误信息。
另见 assert-return 。
也可用作 method :
getFile()->assert_notmatch('bar.*')
返回类型: Number
assert_report({msg}) assert_report()
直接报告测试失败,错误信息使用字符串 {msg}。
总是返回一。
也可用作 method :
GetMessage()->assert_report()
返回类型: Number
assert_true({actual} [, {msg}]) assert_true()
{actual} 不为真时,向 v:errors 添加错误信息,其余行为类同
assert_equal() 。
另见 assert-return 。
非零值视作真值。如果 {actual} 不是数值,断言失败。
{msg} 给出时,加到缺省错误信息开头。从脚本调用时,开头还会附带
断言所在位置。
也可用作 method :
GetResult()->assert_true()
返回类型: Number
vim:tw=78:ts=8:noet:ft=help:norl: