Type the test environments for autocomplete

Building on the class annotations from the smoke test changes:

- The suite is generic over its environment: Framework.suite is
  @generic T : Stubs with the extension returning T, and Suite<T> passes T to
  every test function. A test file declares
  `local Suite = ... --- @type Suite<ExpRoles.TestEnv>` and env autocompletes
  from there.
- The stubs declare their recorded fields, add_player returns Stubs.Player,
  and the server is one.
- ExpRoles.TestEnv : Stubs declares the extension fields, so env.R returns
  ExpRoles.Role and env.Roles is the module.

The typing immediately paid for itself by flagging real drift in the tests,
now fixed: _script_data is package private so the env exposes script_data()
instead, the join event carries its name and tick, the assignment record type
admits is_deleted, admin_state is a file local rather than an undeclared
field, and the event assertions which indexed [1] without a nil check compare
the whole event list.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
bbassie
2026-09-01 06:09:40 +00:00
co-authored by Claude Fable 5
parent 59df8bdff3
commit 08fe6b688e
8 changed files with 109 additions and 37 deletions
+7 -5
View File
@@ -26,19 +26,21 @@ local function repr(value, depth)
end
--- Create a suite of tests, one is made per test file
--- @param extend_env fun(env: table): table Extends the stubs given to each test
--- @generic T : Stubs
--- @param extend_env fun(env: Stubs): T Extends the stubs given to each test
--- @return Suite<T>
function Framework.suite(extend_env)
--- @class Suite
--- @class Suite<T>
local Suite = {
tests = {}, -- { name, fn } in declaration order
results = {}, -- { name, ok, detail? } accumulated across tests
tests = {}, --- @type { name: string, fn: fun(env: T) }[] In declaration order
results = {}, --- @type { name: string, ok: boolean, detail: string? }[] Accumulated across tests
}
local current_test --- @type string?
--- Declare a named test, its function receives a fresh environment
--- @param name string
--- @param fn fun(env: table)
--- @param fn fun(env: T)
function Suite.test(name, fn)
Suite.tests[#Suite.tests + 1] = { name = name, fn = fn }
end