## Luaをインストール
[[LuaRocks]]が必要らしいのでまずはそちらをインストール。[[Lua]]をインストールしたらついてきた。
```console
mise use -g
[email protected]
```
> [!warning]
> バージョンを指定しないと[[Neovim]]の[[Lua]]バージョンと一致しなくなるので注意。[[Neovim]] 10.0.2は[[Lua]] 5.1を使っていた。 `:lua print(_VERSION)` で確認。
## vustedインストール
READMEを参考に。
<div class="link-card">
<div class="link-card-header">
<img src="https://github.githubassets.com/favicons/favicon.svg" class="link-card-site-icon"/>
<span class="link-card-site-name">GitHub</span>
</div>
<div class="link-card-body">
<div class="link-card-content">
<p class="link-card-title">GitHub - notomo/vusted: A busted wrapper for testing neovim plugin</p>
<p class="link-card-description">A busted wrapper for testing neovim plugin. Contribute to notomo/vusted development by creating an account on GitHub.</p>
</div>
<img src="https://opengraph.githubassets.com/f5671a955d41d6aecd9054e6fdc7db1ce87ba7fb30aea4f66f9d1c62f088e02e/notomo/vusted" class="link-card-image" />
</div>
<a href="https://github.com/notomo/vusted?tab=readme-ov-file"></a>
</div>
```console
luarocks --lua-version=5.1 install vusted
```
> [!caution]
> `--lua-version` を指定しないと[[Neovim]]の[[Lua]]バージョンと一致しなくなる恐れがあるので注意。
`/home/tadashi-aikawa/.local/share/mise/installs/lua/5.1/luarocks` がインストールされた。依存関係も色々ありそうだが一旦省略。
## 適当なテストコードを書く
[[busted]]のREADMEを参考に適当なテストケースを追加。`lua/ghostwriter/utils/strings.lua`と同じ階層に`strings_spec.lua`を追加。
> [!info]
> [[Lua]]のテストでは`_spec.lua`のsuffixにするのが慣習ぽい。
```lua
describe("Busted unit testing framework", function()
describe("should be awesome", function()
it("should be easy to use", function()
assert.truthy("Yup.")
end)
it("should have lots of features", function()
-- deep check comparisons!
assert.same({ table = "great" }, { table = "great" })
-- or check by reference!
assert.is_not.equals({ table = "great" }, { table = "great" })
assert.falsy(nil)
assert.error(function()
error("Wat")
end)
end)
it("should provide some shortcuts to common functions", function()
assert.unique({ { thing = 1 }, { thing = 2 }, { thing = 3 } })
end)
end)
end)
```
## 実行する
`lua`配下を指定して実行。テストは実行されてそう。
```console
$ vusted lua
ok 1 - Busted unit testing framework should be awesome should be easy to use
ok 2 - Busted unit testing framework should be awesome should have lots of features
ok 3 - Busted unit testing framework should be awesome should provide some shortcuts to common functions
1..3
# Success: 3
```
## LSPで警告になる
`describe` をはじめとした `vusted` のパラメータが解決しないからっぽい。かといって`require`するとそれはそれで`nil`になってしまう。
```lua
-- これはNG
local assert = require("vusted.assert").assert
local describe = require("vusted.assert").describe
local it = require("vusted.assert").it
```
色々調べたが、良い解決方法が見つからなかったので以下を追加して一時期的に無理やり解決する。
```lua
-- WARNING: 実行に影響を与えずLSPエラーを抑制する回避策
local assert = require("luassert.assert")
local describe = describe ---@diagnostic disable-line: undefined-global
local it = it ---@diagnostic disable-line: undefined-global
```
## ghostwriter.nvimのちゃんとしたテストを書く
当初の目的だった[[🦉ghostwriter.nvim]]のテストコードをちゃんと書く。最終的には以下のようになった。
```lua
-- WARNING: 実行に影響を与えずLSPエラーを抑制する回避策
local assert = require("luassert.assert")
local describe = describe ---@diagnostic disable-line: undefined-global
local it = it ---@diagnostic disable-line: undefined-global
local strings = require("ghostwriter.utils.strings")
describe("strings.replace", function()
it("replaces RegExp", function()
assert.same("XXX", strings.replace("abc", "[a-z]", "X"))
end)
it("does not replace an unescaped RegExp correctly", function()
assert.same("[true-true]", strings.replace("[a-z]", "[a-z]", "true"))
end)
it("replaces an unescaped RegExp correctly", function()
assert.same("true", strings.replace("[a-z]", "%[a%-z%]", "true"))
end)
end)
describe("strings.convert_link", function()
it("does not convert plain text", function()
assert.same("hogehoge", strings.convert_link("hogehoge", {}))
end)
it("does not convert a URL", function()
assert.same("https://sample.com", strings.convert_link("https://sample.com", {}))
end)
it("does not convert a Wiki link", function()
assert.same("[[hogehoge]]", strings.convert_link("[[hogehoge]]", {}))
end)
describe("(link.disabled: false)", function()
it("converts a Markdown link to a Slack link", function()
assert.same("<https://title.com|title>", strings.convert_link("[title](https://title.com)", {}))
end)
it(
"converts a Markdown link with square brackets, parentheses, or hyphens in the title to a Slack link",
function()
assert.same(
"<https://title.com|[title] desc - (note) - >",
strings.convert_link("[\\[title\\] desc \\- \\(note\\) \\- ](https://title.com)", {})
)
end
)
end)
describe("(link.disabled: true)", function()
it("converts a Markdown link to just its title", function()
assert.same("title", strings.convert_link("[title](https://title.com)", { disabled = true }))
end)
it(
"converts a Markdown link with square brackets, parentheses, or hyphens in the title to just its title",
function()
assert.same(
"[title] desc - (note) - ",
strings.convert_link(
"[\\[title\\] desc \\- \\(note\\) \\- ](https://title.com)",
{ disabled = true }
)
)
end
)
end)
end)
describe("strings.convert_header", function()
it("converts an H1 header to bold text", function()
assert.same("*head*", strings.convert_header("# head"))
end)
it("converts an H2 header to bold text", function()
assert.same("*head*", strings.convert_header("## head"))
end)
it("converts an H3 header to bold text", function()
assert.same("*head*", strings.convert_header("### head"))
end)
it("converts an H4 header to bold text", function()
assert.same("*head*", strings.convert_header("#### head"))
end)
it("converts an H5 header to bold text", function()
assert.same("*head*", strings.convert_header("##### head"))
end)
it("converts an H6 header to bold text", function()
assert.same("*head*", strings.convert_header("###### head"))
end)
describe("(before_blank_lines: 2)", function()
it("converts a header to bold text and adds two line breaks before it", function()
assert.same("\n\n*head*", strings.convert_header("# head", 2))
end)
end)
end)
```
## GitHub Actionsでテストを実行
ちょっと違うだけでも動かなくて、思ったよりデリケートだった。
```yaml
name: "Tests"
on:
push:
paths:
- ".github/**/*"
- "lua/*"
- "lua/**/*"
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Neovimをインストール
- uses: rhysd/action-setup-vim@v1
with:
neovim: true
# luaのactionはluarocksが入っていなかったのでmiseで入れる
- uses: jdx/mise-action@v2
with:
tool_versions: |
lua 5.1
# --localでインストールするとvusted/runが見つからないエラーになる
- run: luarocks --lua-version=5.1 install vusted
# vustedでは解決しなかった... PATHが更新されてないからな気がする
- run: /home/runner/.local/share/mise/installs/lua/5.1/luarocks/bin/vusted lua
```