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
+16
View File
@@ -47,7 +47,17 @@ for _, record in ipairs(role_records()) do
role_ids[record.name] = record.id
end
--- The environment given to each test: the stubs extended with a fresh copy
--- of the roles module and the fixture helpers
--- @class ExpRoles.TestEnv : Stubs
--- @field Roles ExpRoles A fresh copy of the roles module
--- @field R fun(name: string): ExpRoles.Role Get a fixture role by name
--- @field assignment fun(player_name: string, role_names: string[]): { name: string, role_ids: number[], is_deleted: boolean? }
--- @field script_data fun(): ExpRoles.ScriptData The module's script data, for asserting on internal state
--- @field initialise fun(assignments: table[]?) Load the standard fixture and the given assignments
return Framework.suite(function(env)
--- @cast env ExpRoles.TestEnv
env.Roles = assert(loadfile(plugin_root .. "/module/control.lua"))() --- @type ExpRoles
env.Roles.on_server_startup()
@@ -70,6 +80,12 @@ return Framework.suite(function(env)
return { name = player_name, role_ids = ids }
end
--- The module's script data, for asserting on internal state
function env.script_data()
--- @diagnostic disable-next-line: access-invisible
return env.Roles._script_data()
end
--- Load the standard fixture and the given assignments
function env.initialise(assignments)
env.Roles.initialise{