在 ConTeXt 中为 Lua 编写单元测试

在 ConTeXt 中为 Lua 编写单元测试

我想为 ConTeXt 使用的 Lua 代码编写一些单元测试,并且想知道是否有其他人做过这件事,以及设置框架时可能需要做什么。

Lua 代码特别存储在单独的文件中(例如numbering.lua),这意味着测试运行器(例如破获) 可以直接用 来包含它们require

值得注意的是(但可能并不重要),我使用 Python 的 unittest 作为测试运行器疯子蟒

固有的问题是 LuaTeX 和 ConTeXt 定义的全局变量在 Lua 中并不自然。如果没有从其相应文件导入这些表,则无法访问诸如context和之类的表。(这看起来像是和...texiorequiretex/texmf-context/tex/context/base/trac-log.lua谁知道, 分别)。

有人做过 ConTeXt + Lua 的单元测试吗?需要包含哪些 Lua 文件才能获取变量?我希望在某个地方有一个入口点,可以处理大部分设置。

看起来.lua相关文件通常会在里面,./tex/texmf-context/tex/context/base/但我只是猜测,而且由于大约有 840 个.lua文件,我将非常感激任何关于从哪里开始的指导。

答案1

根据@Aditya 和@phg 的精彩评论,我做了以下事情:

我使用非常酷的lunatest框架. 设置起来很简单,因为只需要设置require('lunatest'),并且有一组有用的示例test.lua

一旦我创建了自己的,my_tests.lua我就会运行它:

context my_tests.lua --purgeall --batchmode --once

然后,我的 python 测试运行器检查上下文进程的返回代码(如果失败则为非零)。


context经过一段时间的试验,我发现捕获和和其他函数的输出很有挑战性texio。为了解决这个问题,我不再让 ConTeXt 启动 lua,而是使用带有存根的 vanilla lua,如下所示:

local function stub(name)
  local stubbed = {}
  local calls = {}
  local metatable = {
      __call = function(meta, ...)
        local call = {}
        call.method = nil
        call.args = arg
        table.insert(calls, call)
      end,
      __index = function(meta, ...)
        local method = arg[1]
        return function(...)
          local call = {}
          call.method = method
          call.args = arg
          table.insert(calls, call)
         end
      end
   }
   stubbed._calls = calls
   setmetatable(stubbed, metatable)
   _G[name] = stubbed
end

function M.setup()
  stub('context')
  stub('texio')
end

M.setup运行器在每次测试之前调用Where lunatest。结果是,我现在可以测试 Lua 的调用,如下所示texiocontext涉及更多设置,但不会太多):

lt = require('lunatest')

function suite.test_double_indent()
  test_double_indent()
  lt.assert_len(5, context._calls) 
  lt.assert_equal('\\startitemize\\sym{}\\startitemize\\sym{}',
    context._calls[1].args[1])
  lt.assert_equal('\n\\stopitemize\n\\stopitemize\n\\stopitemize',
    context._calls[5].args[1])
end

最后,因为这个设置没有什么特殊之处(即不需要变量),所以如果愿意的话,luatex可以很容易地使用或其他解释器桥来调用。python-lunatic

相关内容