Problem:
The magic globals `it`, `describe`, etc., are more trouble than they are
worth.
- Hooking into `after_each` requires `getfenv()` hacks.
- They confuse luals/emmylua, because the top-level `.luarc.json` isn't
merged with `test/.luarc.json` (apparently a luals limitation?)
- They totally defeat discoverability because the user just has to
"know" about the various magic symbols.
So they harm DX, which means they serve no purpose at all.
Solution:
- Expose the test API from `testutil`, so tests can call `t.it()`,
`t.describe()`, etc., in the conventional way.
- Drop `getfenv()` hacks.
- Drop the `setfenv()` injection in `load_chunk`.
- Drop `test/_meta.lua`.
when running `zig build functionaltest`, it might
take a while until the test harness nvim instance checks
for interrupts, which causes a lot of tests to keep running after
CTRL+C. Check after each test instead
This is in preparation of zig 0.17 where b.install_path is no
longer known inside `pub fn build()`.
Builds which should hardcode a runtime path into the binary has to specify it.
We could use a nlua0 helper to encode the install path at build time but
I think this is cleaner anyway. (like currently the appimage still
encodes a temporary build path which is nonsensical, it is better to
just include none)
Similarily b.args will not be available anymore (there will just
be an opaque pass-through)
Replace the busted-based Lua test runner with a repo-local harness.
The new harness runs spec files directly under `nvim -ll`, ships its own
reporter and lightweight `luassert` shim, and keeps the helper/preload
flow used by the functional and unit test suites.
Keep the file boundary model shallow and busted-like by restoring `_G`,
`package.loaded`, `package.preload`, `arg`, and the process environment
between files, without carrying extra reset APIs or custom assertion
machinery.
Update the build and test entrypoints to use the new runner, add
black-box coverage for the harness itself, and drop the bundled
busted/luacheck dependency path.
AI-assisted: Codex