-- lib-core.api-discovery-test — Test-lib for lib-core.api-discovery local api = require("lib-core.api-discovery") local M = {} function M.run_tests(ctx) -- Assertions added in plan tasks 2-7. -- ===== parse_lua_surface ===== do local src = [[ local M = {} M.foo = function(x) return x end M.bar = function() end M._private = function() end local function not_in_M() end return M ]] local surface = api.parse_lua_surface(src) engine.test.equals(#surface.public, 2, "parse_lua_surface: 2 public functions") engine.test.equals(surface.public[1], "foo", "parse_lua_surface: first public is foo") engine.test.equals(surface.public[2], "bar", "parse_lua_surface: second public is bar") engine.test.equals(#surface.private, 1, "parse_lua_surface: 1 private function") engine.test.equals(surface.private[1], "_private", "parse_lua_surface: private name = _private") -- Edge: empty source local empty = api.parse_lua_surface("local M = {}\nreturn M") engine.test.equals(#empty.public, 0, "parse_lua_surface: empty source = no public") engine.test.equals(#empty.private, 0, "parse_lua_surface: empty source = no private") end -- ===== parse_readme_api ===== do local md = [[ # lib-core.input Some abstract. ## API ### `input.bind(action_name, keys)` **Syntax:** `input.bind(action_name: string, keys: string[]) → void` ### `input.is_action_down(action) → bool` Description. ## Conventions Stuff. ]] local doc = api.parse_readme_api(md) engine.test.equals(#doc.documented, 2, "parse_readme_api: 2 documented functions") engine.test.equals(doc.documented[1], "bind", "parse_readme_api: first = bind") engine.test.equals(doc.documented[2], "is_action_down", "parse_readme_api: second = is_action_down") -- Edge: no API section local no_api = api.parse_readme_api("# Just abstract\nNothing else.") engine.test.equals(#no_api.documented, 0, "parse_readme_api: no API-section = empty") end -- ===== diff_surface ===== do -- Happy: surface == documented local surface = { public = {"foo","bar"}, private = {"_x"} } local readme = { documented = {"foo","bar"} } local diff = api.diff_surface(surface, readme) engine.test.equals(#diff.missing_docs, 0, "diff_surface: equal -> no missing") engine.test.equals(#diff.stale_docs, 0, "diff_surface: equal -> no stale") -- Surface > Doc -> missing local surface2 = { public = {"foo","bar","baz"}, private = {} } local readme2 = { documented = {"foo"} } local diff2 = api.diff_surface(surface2, readme2) engine.test.equals(#diff2.missing_docs, 2, "diff_surface: 2 missing docs") engine.test.assert(diff2.missing_docs[1] == "bar" or diff2.missing_docs[1] == "baz", "diff_surface: missing contains bar/baz") -- Doc > Surface -> stale local surface3 = { public = {"foo"}, private = {} } local readme3 = { documented = {"foo","gone","also_gone"} } local diff3 = api.diff_surface(surface3, readme3) engine.test.equals(#diff3.stale_docs, 2, "diff_surface: 2 stale docs") end -- ===== grep_engine_calls ===== do local src = [[ local input = require("lib-core.input") function update(ctx, dt) if engine.input.is_action_down("foo") then engine.render.text("hi") end engine.window.size() end ]] local calls = api.grep_engine_calls(src) -- Order not guaranteed; check set membership local set = {} for _, c in ipairs(calls) do set[c] = true end engine.test.assert(set["engine.input.is_action_down"], "grep_engine_calls: engine.input.is_action_down") engine.test.assert(set["engine.render.text"], "grep_engine_calls: engine.render.text") engine.test.assert(set["engine.window.size"], "grep_engine_calls: engine.window.size") engine.test.equals(#calls, 3, "grep_engine_calls: 3 unique calls") -- Edge: no engine calls local empty = api.grep_engine_calls("local M = {}\nreturn M") engine.test.equals(#empty, 0, "grep_engine_calls: empty -> 0") end -- ===== generate_topology_block ===== do -- Standard: lib with 1 dep + engine-calls local manifest = { id = "lib-core.foo", deps = { {id="lib-core.bar"} } } local engine_calls = {"engine.input.is_action_down"} local mermaid = api.generate_topology_block(manifest, engine_calls) engine.test.assert(string.find(mermaid, "graph LR") or string.find(mermaid, "graph TD"), "generate_topology_block: starts with graph directive") engine.test.assert(string.find(mermaid, "lib%-core%.foo", 1, false), "generate_topology_block: self-node present") engine.test.assert(string.find(mermaid, "lib%-core%.bar", 1, false), "generate_topology_block: dep-node present") engine.test.assert(string.find(mermaid, "engine%.%*", 1, false), "generate_topology_block: engine-node present") -- Asset-Lib: no deps, no engine-calls local asset = { id = "lib-asset.sprites", deps = {} } local asset_mermaid = api.generate_topology_block(asset, {}) engine.test.assert(string.find(asset_mermaid, "lib%-asset%.sprites", 1, false), "generate_topology_block: asset-lib has self-node") engine.test.assert(not string.find(asset_mermaid, "engine%.%*", 1, false), "generate_topology_block: asset-lib has no engine-node") end -- ===== validate_readme_structure ===== do local complete = [[ # lib-core.foo Abstract. | Field | Value | |---|---| | Version | 0.1.0 | ## API ### `foo.bar()` Sig. ## References - spec ]] local r = api.validate_readme_structure(complete, "core") engine.test.equals(#r.missing_sections, 0, "validate: complete README -> no missing") engine.test.assert(r.section_order_ok, "validate: complete README -> order ok") local missing_api = [[ # lib-core.foo Abstract. | F | V | ## References - spec ]] local r2 = api.validate_readme_structure(missing_api, "core") engine.test.assert(#r2.missing_sections > 0, "validate: missing API -> reports missing") local has_api_missing = false for _, s in ipairs(r2.missing_sections) do if s == "API" then has_api_missing = true end end engine.test.assert(has_api_missing, "validate: missing-sections list contains 'API'") -- Tier community: lockerer local r3 = api.validate_readme_structure(missing_api, "community") engine.test.equals(#r3.missing_sections, 0, "validate: tier=community -> no enforcement") end engine.exit(engine.test.failures()) end return M