Vendor libs/hump, sfxrlua, json4lua, narrator as real files
These were committed as empty submodule gitlinks with no .gitmodules, so the folders were never populated and the game could not load (require of libs/hump/timer, libs/sfxrlua/sfxr, narrator.narrator). Checked out each at its pinned commit and vendored the files, matching the existing bundled-libs convention. Removed the junk libs/libs/ tree. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
e73f63b5d4
commit
03532d29e4
219 changed files with 20254 additions and 252 deletions
252
libs/narrator/test/run.lua
Normal file
252
libs/narrator/test/run.lua
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
--
|
||||
-- Testing with Busted library
|
||||
|
||||
--
|
||||
-- Dependencies
|
||||
|
||||
local import = require
|
||||
import('busted.runner')()
|
||||
|
||||
if os.getenv('LOCAL_LUA_DEBUGGER_VSCODE') == '1' then
|
||||
import('lldebugger').start()
|
||||
end
|
||||
|
||||
local bot = require('bot')
|
||||
local narrator = require('narrator.narrator')
|
||||
local lume = require('narrator.libs.lume')
|
||||
|
||||
--
|
||||
-- Constants
|
||||
|
||||
local folder_separator = package.config:sub(1, 1)
|
||||
local tests_folder = 'test' .. folder_separator
|
||||
|
||||
--- Make path for a .lua file
|
||||
-- @param case string: an runtime test case
|
||||
-- @return string: a .lua path
|
||||
local function lua_path(case)
|
||||
return tests_folder .. case .. '.lua'
|
||||
end
|
||||
|
||||
--- Make path for an .ink file
|
||||
-- @param case string: an Ink test case
|
||||
-- @return string: an .ink path
|
||||
local function ink_path(case)
|
||||
return tests_folder .. case .. '.ink'
|
||||
end
|
||||
|
||||
--- Make path for a .txt file
|
||||
-- @param case string: an Ink test case
|
||||
-- @param answers table: a sequence of answers (numbers)
|
||||
-- @return string: a .txt path
|
||||
local function txt_path(case, answers)
|
||||
local path = tests_folder .. case
|
||||
if answers and #answers > 0 then
|
||||
path = path .. folder_separator .. table.concat(answers, '-')
|
||||
end
|
||||
path = path .. '.txt'
|
||||
return path
|
||||
end
|
||||
|
||||
--- Get all possible sequences and logs of the case
|
||||
-- @param case string: an Ink test case
|
||||
-- @return table: an array of possible games { sequence, log }
|
||||
local function get_possible_results(case)
|
||||
local path = ink_path(case)
|
||||
local book = narrator.parse_file(path)
|
||||
|
||||
local results = { }
|
||||
local sequences = { { } }
|
||||
local seq_index
|
||||
|
||||
local function instructor(choices, step)
|
||||
local cur_seq = sequences[seq_index]
|
||||
local answer = cur_seq[step]
|
||||
|
||||
if not answer then
|
||||
-- Transform a current sequence to branches for each available choice
|
||||
table.remove(sequences, seq_index)
|
||||
|
||||
for index, _ in ipairs(choices) do
|
||||
local new_seq = lume.concat(cur_seq, { index })
|
||||
table.insert(sequences, new_seq)
|
||||
end
|
||||
|
||||
-- Set a stop signal for the bot
|
||||
answer = -1
|
||||
end
|
||||
|
||||
return answer
|
||||
end
|
||||
|
||||
while #sequences > 0 do
|
||||
-- Iterate sequences and play them
|
||||
for index = 1, #sequences do
|
||||
local sequence = sequences[index]
|
||||
seq_index = index
|
||||
|
||||
-- Play the sequence
|
||||
local story = narrator.init_story(book)
|
||||
local log = bot.play(story, instructor)
|
||||
|
||||
-- If the sequence was finished then save the result and mark it as finished
|
||||
if log then
|
||||
local result = { sequence = sequence, log = log }
|
||||
table.insert(results, result)
|
||||
sequences[index] = { is_finished = true }
|
||||
end
|
||||
end
|
||||
|
||||
-- Remove finished sequences
|
||||
for index = #sequences, 1, -1 do
|
||||
local sequence = sequences[index]
|
||||
if sequence.is_finished then
|
||||
table.remove(sequences, index)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return results
|
||||
end
|
||||
|
||||
--- Create possible results for an Ink test case and save them to txt files
|
||||
-- @param case string: an Ink test case
|
||||
-- @param override boolean: override a txt file if it already exists.
|
||||
local function create_txt_for_ink_case(case, override)
|
||||
local override = override ~= nil and override or false
|
||||
local results = get_possible_results(case)
|
||||
|
||||
for _, result in ipairs(results) do
|
||||
local txt_path = txt_path(case, #results > 1 and result.sequence or nil)
|
||||
local file = io.open(txt_path, 'r')
|
||||
local is_file_exists = file ~= nil
|
||||
if is_file_exists then io.close(file) end
|
||||
|
||||
if not is_file_exists or override then
|
||||
local folder_path = txt_path:match('(.*' .. folder_separator .. ')')
|
||||
local folder = io.open(folder_path, 'r')
|
||||
local is_folder_exists = folder ~= nil
|
||||
if is_folder_exists then
|
||||
io.close(folder)
|
||||
else
|
||||
os.execute('mkdir ' .. folder_path)
|
||||
end
|
||||
|
||||
file = io.open(txt_path, 'w')
|
||||
assert(file, 'Has no access to the file at path \'' .. txt_path .. '\'.')
|
||||
|
||||
file:write(result.log)
|
||||
file:close()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Create possible results for Ink test cases and save them to txt files
|
||||
-- @param cases table: an array of Ink test cases
|
||||
-- @param override bool: override the txt file if it already exists
|
||||
local function create_txt_for_ink_cases(cases, override)
|
||||
for _, case in ipairs(cases) do
|
||||
create_txt_for_ink_case(case, override)
|
||||
end
|
||||
end
|
||||
|
||||
--- Test an Ink case
|
||||
-- @param case string: an Ink test case
|
||||
local function test_ink_case(case)
|
||||
describe('Test an Ink case \'' .. case .. '\'.', function()
|
||||
local path = ink_path(case)
|
||||
local book = narrator.parse_file(path)
|
||||
|
||||
local results = get_possible_results(case)
|
||||
for _, result in ipairs(results) do
|
||||
describe('Sequence is [' .. table.concat(result.sequence, '-') .. '].', function()
|
||||
local txt_path = txt_path(case, #results > 1 and result.sequence or nil)
|
||||
local file = io.open(txt_path, 'r')
|
||||
|
||||
it('Checking results.', function()
|
||||
assert.is_not_nil(file)
|
||||
|
||||
local expected = file:read('*all')
|
||||
file:close()
|
||||
|
||||
assert.are.same(expected, result.log)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
--- Test Ink cases
|
||||
-- @param cases table: an array of test cases
|
||||
local function test_ink_cases(cases)
|
||||
for _, case in ipairs(cases) do
|
||||
test_ink_case(case)
|
||||
end
|
||||
end
|
||||
|
||||
--- Test a runtime case
|
||||
-- @param case string: a runtime test case
|
||||
local function test_lua_case(case)
|
||||
describe('Test a runtime case \'' .. case .. '\'.', function()
|
||||
local lua_path = lua_path(case)
|
||||
loadfile(lua_path)(narrator, describe, it, assert)
|
||||
end)
|
||||
end
|
||||
|
||||
--- Test runtime cases
|
||||
-- @param cases table: an array of runtime test cases
|
||||
local function test_lua_cases(cases)
|
||||
for _, case in ipairs(cases) do
|
||||
test_lua_case(case)
|
||||
end
|
||||
end
|
||||
|
||||
--- Override math.random functions to prevent different results beetween machines and pass test-cases.
|
||||
local function override_random()
|
||||
local test_seed
|
||||
local original_random = math.random
|
||||
|
||||
math.randomseed = function(x)
|
||||
test_seed = x
|
||||
end
|
||||
|
||||
math.random = function(x, y)
|
||||
if test_seed then
|
||||
local result = math.max(x, math.min(test_seed, y))
|
||||
test_seed = nil
|
||||
return result
|
||||
else
|
||||
return original_random(x, y)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--
|
||||
-- Main
|
||||
|
||||
local case = nil
|
||||
local cases = require('test.cases')
|
||||
local override_case_results = false
|
||||
|
||||
override_random()
|
||||
|
||||
if override_case_results then
|
||||
if case then
|
||||
create_txt_for_ink_case(case, true)
|
||||
else
|
||||
create_txt_for_ink_cases(cases.units, true)
|
||||
create_txt_for_ink_cases(cases.stories, true)
|
||||
end
|
||||
end
|
||||
|
||||
if case then
|
||||
if case:find('runtime/', 1, 8) then
|
||||
test_lua_case(case)
|
||||
else
|
||||
test_ink_case(case)
|
||||
end
|
||||
else
|
||||
test_lua_cases(cases.runtime)
|
||||
test_ink_cases(cases.units)
|
||||
test_ink_cases(cases.stories)
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue