
Eu gostaria de escrever alguns testes unitários para o código Lua usado pelo ConTeXt e gostaria de saber se alguém mais fez isso e o que pode ser necessário na configuração do framework.
O código Lua em particular está sendo armazenado em arquivos separados (por exemplo, numbering.lua
), o que significa que um executor de teste (por exemplo,Pego) pode apenas incluí-los com require
.
Pode valer a pena notar (mas provavelmente não importa) que estou usando o unittest do Python como executor de testes comlunático-python.
O problema inerente é que os globais definidos por LuaTeX e ConTeXt não estão naturalmente em Lua. Tabelas como context
e texio
simplesmente não são acessíveis sem um require
arquivo que as importe de seus arquivos correspondentes. (O que parece ser tex/texmf-context/tex/context/base/trac-log.lua
e ...quem sabe, respectivamente).
Alguém já fez testes unitários do ConTeXt + Lua? Quais arquivos Lua podem ser necessários para obter as variáveis? Eu esperaria que houvesse um ponto de entrada em algum lugar que cuidasse da maior parte da configuração.
Parece que os .lua
arquivos relevantes geralmente estariam presentes, ./tex/texmf-context/tex/context/base/
mas estou apenas supondo, e como existem cerca de 840 .lua
arquivos, ficaria grato por qualquer orientação sobre por onde começar.
Responder1
Seguindo os ótimos comentários de @Aditya e @phg, fiz o seguinte:
Eu criei um conjunto de testes usando o muito legalestrutura mais lunar. É trivial de configurar porque basta fazê-lo require('lunatest')
, e há um conjunto útil de exemplos emtest.lua
.
Depois de criar o meu, my_tests.lua
eu o executo com:
context my_tests.lua --purgeall --batchmode --once
Meu executor de testes python verifica o código de retorno do processo de contexto (que seria diferente de zero em caso de falha).
Depois de experimentar isso um pouco, achei um desafio capturar a saída de context
e texio
de outras funções. Para resolver isso, deixei de fazer o ConTeXt iniciar a lua e estou usando vanilla lua com stubs como este:
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
Onde M.setup
é chamado pelo lunatest
corredor antes de cada teste. O resultado é que agora posso testar Lua para as chamadas que ela faria texio
e context
assim (com um pouco mais, mas não muito, de configuração envolvida):
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
No final, como não há nada de especial nesta configuração (ou seja, nenhuma luatex
variável é necessária), é fácil invocar com a python-lunatic
ou outra ponte de intérprete, se desejar.