From b52231f37d1d518e668318ee5c67f04e3efe15e5 Mon Sep 17 00:00:00 2001 From: FourierTransformer Date: Thu, 23 Apr 2026 21:33:42 -0500 Subject: [PATCH 01/13] should do the nested tests --- build/tested/file_loader.lua | 1 + src/tested/file_loader.tl | 1 + tests/import_test.tl | 13 +++++++++++++ tests/nested_import.tl | 1 + tests/tl_to_import.tl | 2 ++ 5 files changed, 18 insertions(+) create mode 100644 tests/import_test.tl create mode 100644 tests/nested_import.tl create mode 100644 tests/tl_to_import.tl diff --git a/build/tested/file_loader.lua b/build/tested/file_loader.lua index 0e5dc06..dff793b 100644 --- a/build/tested/file_loader.lua +++ b/build/tested/file_loader.lua @@ -51,6 +51,7 @@ if tl_ok then return load_function end file_loader.loader[".tl"] = load_teal_file + end return file_loader diff --git a/src/tested/file_loader.tl b/src/tested/file_loader.tl index a20f349..81fd3f9 100644 --- a/src/tested/file_loader.tl +++ b/src/tested/file_loader.tl @@ -51,6 +51,7 @@ if tl_ok then return load_function end file_loader.loader[".tl"] = load_teal_file + -- tl.loader() end return file_loader \ No newline at end of file diff --git a/tests/import_test.tl b/tests/import_test.tl new file mode 100644 index 0000000..b09a44a --- /dev/null +++ b/tests/import_test.tl @@ -0,0 +1,13 @@ +local tested = require("tested") +local str = require("tests.tl_to_import") + +tested.test("imported files should work", function() + tested.assert({ + given = "a nested string", + should = "be equivalent to imported string", + expected = "somewhat nested", + actual = str + }) +end) + +return tested \ No newline at end of file diff --git a/tests/nested_import.tl b/tests/nested_import.tl new file mode 100644 index 0000000..1c401c7 --- /dev/null +++ b/tests/nested_import.tl @@ -0,0 +1 @@ +return "somewhat nested" \ No newline at end of file diff --git a/tests/tl_to_import.tl b/tests/tl_to_import.tl new file mode 100644 index 0000000..44012e6 --- /dev/null +++ b/tests/tl_to_import.tl @@ -0,0 +1,2 @@ +local deeply_nested = require("tests.nested_import") +return deeply_nested \ No newline at end of file From 1f436b0484f298bd6a80c4b2a88a30e2040b92d8 Mon Sep 17 00:00:00 2001 From: FourierTransformer Date: Thu, 23 Apr 2026 21:37:38 -0500 Subject: [PATCH 02/13] re-enable the comment and the tests will hopefully work now! --- build/tested/file_loader.lua | 2 +- src/tested/file_loader.tl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/tested/file_loader.lua b/build/tested/file_loader.lua index dff793b..1b4b057 100644 --- a/build/tested/file_loader.lua +++ b/build/tested/file_loader.lua @@ -51,7 +51,7 @@ if tl_ok then return load_function end file_loader.loader[".tl"] = load_teal_file - + tl.loader() end return file_loader diff --git a/src/tested/file_loader.tl b/src/tested/file_loader.tl index 81fd3f9..dfce41e 100644 --- a/src/tested/file_loader.tl +++ b/src/tested/file_loader.tl @@ -51,7 +51,7 @@ if tl_ok then return load_function end file_loader.loader[".tl"] = load_teal_file - -- tl.loader() + tl.loader() end return file_loader \ No newline at end of file From 7fe52f103584b61efde3a16efdfac4faa7a22db5 Mon Sep 17 00:00:00 2001 From: FourierTransformer Date: Fri, 24 Apr 2026 20:10:01 -0500 Subject: [PATCH 03/13] try without lanes --- .github/workflows/tests-and-coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests-and-coverage.yml b/.github/workflows/tests-and-coverage.yml index 4a4cb29..1caa21b 100644 --- a/.github/workflows/tests-and-coverage.yml +++ b/.github/workflows/tests-and-coverage.yml @@ -52,7 +52,7 @@ jobs: - name: Run tests continue-on-error: true run: | - tested -c + tested -c -n 0 - name: Save Cache uses: actions/cache/save@v5 From d8961b15936ac3004c4fc6a532571d8d170fe16c Mon Sep 17 00:00:00 2001 From: FourierTransformer Date: Fri, 24 Apr 2026 20:11:41 -0500 Subject: [PATCH 04/13] seeing if this breaks the tests --- src/tested/file_loader.tl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tested/file_loader.tl b/src/tested/file_loader.tl index dfce41e..81fd3f9 100644 --- a/src/tested/file_loader.tl +++ b/src/tested/file_loader.tl @@ -51,7 +51,7 @@ if tl_ok then return load_function end file_loader.loader[".tl"] = load_teal_file - tl.loader() + -- tl.loader() end return file_loader \ No newline at end of file From 7fc78450013ddf7f0bf081c9587c752a6da8341a Mon Sep 17 00:00:00 2001 From: FourierTransformer Date: Mon, 4 May 2026 20:28:07 -0500 Subject: [PATCH 05/13] moving the tl.loader into test runner itself --- src/tested/test_runner.tl | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/tested/test_runner.tl b/src/tested/test_runner.tl index 46c7294..76f708e 100644 --- a/src/tested/test_runner.tl +++ b/src/tested/test_runner.tl @@ -16,9 +16,9 @@ function test_runner.run_with_cleanup(file_loader: types.FileLoader, test_file: assert(type(test_module) == "table" and type(test_module.tests) == "table" and type(test_module.run_only_tests) == "boolean", "It does not appear that '" .. test_file .."' returns the 'tested' module") local test_results = test_module:run(test_file, options) - + logger:info("%s: Clearing out any packages that were loaded", test_file) - for package_name, _ in pairs(package.loaded) do + for package_name, _ in pairs(package.loaded) do if not pre_test_loaded_packages[package_name] then logger:debug("%s: Clearing out package: %s", test_file, package_name) package.loaded[package_name] = nil @@ -37,6 +37,9 @@ function test_runner.run_tests( -- these get called in here to avoid weirdness with lanes -- if they are called outside, the lanes will sometimes hang. + local tl_ok, tl_mod = pcall(require, "tl") + if tl_ok then (tl_mod as any).loader() end + local luacov_loaded, luacov_runner = pcall(require, "luacov.runner") if options and options.coverage and not luacov_loaded then error("Code coverage requires the luacov module to be installed") @@ -71,7 +74,7 @@ function test_runner.run_tests( if options.coverage then luacov_runner.resume() end local test_output = test_runner.run_with_cleanup(file_loader, test_files[i], options) - if options.coverage then + if options.coverage then coverage = luacov_runner.data luacov_runner.resume() end @@ -129,11 +132,11 @@ local function run_parallel_tests( end pool:shutdown() - -- future note: should probably save off the individual coverage results + -- future note: should probably save off the individual coverage results -- before running the combine stats, or do a deep copy or something. -- since the old stats get destroyed during the merge if options.coverage then - + -- mostly code from luacov to help merge stats together. local luacov = require("luacov.runner") luacov.data = {} From 61b72e7ad5ce14d07c413201945769828d86b3dc Mon Sep 17 00:00:00 2001 From: FourierTransformer Date: Mon, 4 May 2026 20:31:41 -0500 Subject: [PATCH 06/13] run tests both sequentually and parallel in gha --- .github/workflows/tests-and-coverage.yml | 35 ++++++++++++++---------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/.github/workflows/tests-and-coverage.yml b/.github/workflows/tests-and-coverage.yml index 1caa21b..6838191 100644 --- a/.github/workflows/tests-and-coverage.yml +++ b/.github/workflows/tests-and-coverage.yml @@ -10,21 +10,21 @@ jobs: os: [linux, macos, macos-arm64] lua: [lua=5.1, lua=5.2, lua=5.3, lua=5.4, luajit=@v2.0, luajit=@v2.1] include: - - os: linux - runner: ubuntu-latest - - os: macos - runner: macos-15-intel - - os: macos-arm64 - runner: macos-latest + - os: linux + runner: ubuntu-latest + - os: macos + runner: macos-15-intel + - os: macos-arm64 + runner: macos-latest exclude: - - os: macos-arm64 - lua: luajit=@v2.0 + - os: macos-arm64 + lua: luajit=@v2.0 name: ${{ matrix.os }} (${{ matrix.lua }}) runs-on: ${{ matrix.runner }} steps: # Checks-out the repository under $GITHUB_WORKSPACE. - uses: actions/checkout@v6 - - name: Install libreadline + - name: Install libreadline if: runner.os == 'Linux' run: | sudo apt-get install -y libreadline-dev @@ -43,17 +43,22 @@ jobs: echo lua_install/bin >> $GITHUB_PATH env: MACOSX_DEPLOYMENT_TARGET: 11.0 - + - name: Build tested run: | luarocks make luarocks install luacov-coveralls - - - name: Run tests + + - name: Run tests (sequentially) continue-on-error: true run: | tested -c -n 0 - + + - name: Run tests (parallel) + continue-on-error: true + run: | + tested -c + - name: Save Cache uses: actions/cache/save@v5 with: @@ -73,7 +78,7 @@ jobs: fail-fast: false matrix: lua: [lua=5.1, lua=5.2, lua=5.3, lua=5.4, luajit=@v2.0, luajit=@v2.1] - target: [mingw,vs] + target: [mingw, vs] runs-on: windows-2022 steps: # Checks-out the repository under $GITHUB_WORKSPACE. @@ -90,7 +95,7 @@ jobs: run: | pip install git+https://github.com/luarocks/hererocks hererocks lua_install -r^ --${{ matrix.lua }} --target ${{ matrix.target }} - + - name: Build tested run: | .\lua_install\bin\activate From 7d2348b2c7e54457c49e5bb6c6567f746ad33b28 Mon Sep 17 00:00:00 2001 From: FourierTransformer Date: Mon, 4 May 2026 20:37:26 -0500 Subject: [PATCH 07/13] built the files and will run both sequentually and parallel on windows --- .github/workflows/tests-and-coverage.yml | 9 ++++++++- build/tested/file_loader.lua | 2 +- build/tested/test_runner.lua | 3 +++ src/tested/test_runner.tl | 2 +- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests-and-coverage.yml b/.github/workflows/tests-and-coverage.yml index 6838191..afd6cf6 100644 --- a/.github/workflows/tests-and-coverage.yml +++ b/.github/workflows/tests-and-coverage.yml @@ -101,7 +101,14 @@ jobs: .\lua_install\bin\activate luarocks make luarocks install luacov-coveralls - - name: Run tests + + - name: Run tests (sequentially) + continue-on-error: true + run: | + .\lua_install\bin\activate + tested -c -n 0 + + - name: Run tests (parallel) continue-on-error: true run: | .\lua_install\bin\activate diff --git a/build/tested/file_loader.lua b/build/tested/file_loader.lua index 1b4b057..dff793b 100644 --- a/build/tested/file_loader.lua +++ b/build/tested/file_loader.lua @@ -51,7 +51,7 @@ if tl_ok then return load_function end file_loader.loader[".tl"] = load_teal_file - tl.loader() + end return file_loader diff --git a/build/tested/test_runner.lua b/build/tested/test_runner.lua index 9642660..39dad81 100644 --- a/build/tested/test_runner.lua +++ b/build/tested/test_runner.lua @@ -37,6 +37,9 @@ function test_runner.run_tests( + local tl_ok, tl_mod = pcall(require, "tl") + if tl_ok then tl_mod.loader() end + local luacov_loaded, luacov_runner = pcall(require, "luacov.runner") if options and options.coverage and not luacov_loaded then error("Code coverage requires the luacov module to be installed") diff --git a/src/tested/test_runner.tl b/src/tested/test_runner.tl index 76f708e..f1ed125 100644 --- a/src/tested/test_runner.tl +++ b/src/tested/test_runner.tl @@ -38,7 +38,7 @@ function test_runner.run_tests( -- these get called in here to avoid weirdness with lanes -- if they are called outside, the lanes will sometimes hang. local tl_ok, tl_mod = pcall(require, "tl") - if tl_ok then (tl_mod as any).loader() end + if tl_ok then tl_mod.loader() end local luacov_loaded, luacov_runner = pcall(require, "luacov.runner") if options and options.coverage and not luacov_loaded then From cff3234c1fa44a3ead66a622666afa1e7c1b72d5 Mon Sep 17 00:00:00 2001 From: FourierTransformer Date: Mon, 4 May 2026 20:46:09 -0500 Subject: [PATCH 08/13] also added tl.load to ThreadPool --- build/tested/libs/ThreadPool.lua | 5 +++++ build/tested/test_runner.lua | 4 ++-- src/tested/libs/ThreadPool.tl | 25 +++++++++++++++---------- src/tested/test_runner.tl | 4 ++-- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/build/tested/libs/ThreadPool.lua b/build/tested/libs/ThreadPool.lua index 5de62c8..a63303a 100644 --- a/build/tested/libs/ThreadPool.lua +++ b/build/tested/libs/ThreadPool.lua @@ -38,6 +38,11 @@ local _unpack = unpack or table.unpack local function worker(num, run_coverage, linda) logger:info("Starting worker %d", num) + + + local tl_ok, tl = pcall(require, "tl") + if tl_ok then tl.loader() end + local luacov if run_coverage then diff --git a/build/tested/test_runner.lua b/build/tested/test_runner.lua index 39dad81..534e3b8 100644 --- a/build/tested/test_runner.lua +++ b/build/tested/test_runner.lua @@ -37,8 +37,8 @@ function test_runner.run_tests( - local tl_ok, tl_mod = pcall(require, "tl") - if tl_ok then tl_mod.loader() end + local tl_ok, tl = pcall(require, "tl") + if tl_ok then tl.loader() end local luacov_loaded, luacov_runner = pcall(require, "luacov.runner") if options and options.coverage and not luacov_loaded then diff --git a/src/tested/libs/ThreadPool.tl b/src/tested/libs/ThreadPool.tl index 7e2247b..c4d818f 100644 --- a/src/tested/libs/ThreadPool.tl +++ b/src/tested/libs/ThreadPool.tl @@ -37,7 +37,12 @@ end -- waits for a task, then executes it local function worker(num: integer, run_coverage: boolean, linda: lanes.Linda) logger:info("Starting worker %d", num) - + + -- also not a fan of having to call this over here, but likely required to ensure that + -- each lane loads the tl loader stuff correctly. + local tl_ok, tl = pcall(require, "tl") + if tl_ok then tl.loader() end + local luacov: luacov_type if run_coverage then @@ -50,7 +55,7 @@ local function worker(num: integer, run_coverage: boolean, linda: lanes.Linda) luacov_runner.pause() luacov = luacov_runner end - + while true do logger:debug("Worker %d waiting for task", num) -- Get a task from the queue should be a blocking call @@ -63,9 +68,9 @@ local function worker(num: integer, run_coverage: boolean, linda: lanes.Linda) if run_coverage then luacov.pause() end local coverage_data = {} - if run_coverage then - coverage_data = luacov.data - luacov.data = {} + if run_coverage then + coverage_data = luacov.data + luacov.data = {} end if success then @@ -93,9 +98,9 @@ function ThreadPool.init(workers: integer, run_coverage: boolean): ThreadPool end function ThreadPool:map( - func: function(...: any): T, - args_list: {{any}}, - display_func: function(T), + func: function(...: any): T, + args_list: {{any}}, + display_func: function(T), _timeout?: number ): {ThreadPool.Result} @@ -103,7 +108,7 @@ function ThreadPool:map( logger:info("Sending %d tasks", total_calls) for i = 1, total_calls do local task_data = { - order = i, + order = i, func = func, args = args_list[i] } @@ -126,7 +131,7 @@ function ThreadPool:map( return output end end - + end function ThreadPool:shutdown(timeout?: number) diff --git a/src/tested/test_runner.tl b/src/tested/test_runner.tl index f1ed125..9831ff9 100644 --- a/src/tested/test_runner.tl +++ b/src/tested/test_runner.tl @@ -37,8 +37,8 @@ function test_runner.run_tests( -- these get called in here to avoid weirdness with lanes -- if they are called outside, the lanes will sometimes hang. - local tl_ok, tl_mod = pcall(require, "tl") - if tl_ok then tl_mod.loader() end + local tl_ok, tl = pcall(require, "tl") + if tl_ok then tl.loader() end local luacov_loaded, luacov_runner = pcall(require, "luacov.runner") if options and options.coverage and not luacov_loaded then From 3e44b2bb441445321ee7ead4557463814dd8868c Mon Sep 17 00:00:00 2001 From: FourierTransformer Date: Mon, 4 May 2026 21:04:57 -0500 Subject: [PATCH 09/13] trying the kitchen sink --- build/tested/libs/ThreadPool.lua | 28 +++++++++++++++++++++++-- src/tested/libs/ThreadPool.tl | 35 ++++++++++++++++++++++++++++---- 2 files changed, 57 insertions(+), 6 deletions(-) diff --git a/build/tested/libs/ThreadPool.lua b/build/tested/libs/ThreadPool.lua index a63303a..7ea89a1 100644 --- a/build/tested/libs/ThreadPool.lua +++ b/build/tested/libs/ThreadPool.lua @@ -40,8 +40,32 @@ local function worker(num, run_coverage, linda) - local tl_ok, tl = pcall(require, "tl") - if tl_ok then tl.loader() end + local tl_ok, tl_mod = pcall(require, "tl") + if tl_ok then + local tl_load = tl_mod.load + local function tl_fallback_loader(modname) + local modpath = modname:gsub("%.", "/") + for template in package.path:gmatch("[^;]+") do + local basepath = template:gsub("%?", modpath) + local tlpath = basepath:gsub("%.lua$", ".tl") + if tlpath ~= basepath then + local f = io.open(tlpath, "rb") + if f then + local code = f:read("*all") + f:close() + local fn, err = tl_load(code, "@" .. tlpath) + if fn then return fn end + return nil, "Error compiling '" .. tlpath .. "': " .. tostring(err) + end + end + end + end + if package.searchers then + table.insert(package.searchers, tl_fallback_loader) + else + table.insert(package.loaders, tl_fallback_loader) + end + end local luacov diff --git a/src/tested/libs/ThreadPool.tl b/src/tested/libs/ThreadPool.tl index c4d818f..bc35d49 100644 --- a/src/tested/libs/ThreadPool.tl +++ b/src/tested/libs/ThreadPool.tl @@ -38,10 +38,37 @@ end local function worker(num: integer, run_coverage: boolean, linda: lanes.Linda) logger:info("Starting worker %d", num) - -- also not a fan of having to call this over here, but likely required to ensure that - -- each lane loads the tl loader stuff correctly. - local tl_ok, tl = pcall(require, "tl") - if tl_ok then tl.loader() end + -- Register a low-priority Teal fallback loader so nested `require()` calls inside + -- test files can find .tl modules. We intentionally append to the END of + -- package.loaders (not position 2 like tl.loader() does) so that compiled .lua + -- versions of framework modules are still found first, avoiding expensive + -- tl.new_env()+tl.check() calls on framework internals across all worker threads. + local tl_ok, tl_mod = pcall(require, "tl") + if tl_ok then + local tl_load = (tl_mod as any).load + local function tl_fallback_loader(modname: string): function, string + local modpath = modname:gsub("%.", "/") + for template in package.path:gmatch("[^;]+") do + local basepath = template:gsub("%?", modpath) + local tlpath = basepath:gsub("%.lua$", ".tl") + if tlpath ~= basepath then + local f = io.open(tlpath, "rb") + if f then + local code = f:read("*all") + f:close() + local fn, err = (tl_load as function(string, string): (function, string))(code, "@" .. tlpath) + if fn then return fn end + return nil, "Error compiling '" .. tlpath .. "': " .. tostring(err) + end + end + end + end + if (package as any).searchers then + table.insert((package as any).searchers, tl_fallback_loader) + else + table.insert((package as any).loaders, tl_fallback_loader) + end + end local luacov: luacov_type From 1973e40a8ff3c250d1879598501e4adf82d8f73d Mon Sep 17 00:00:00 2001 From: FourierTransformer Date: Mon, 4 May 2026 21:12:03 -0500 Subject: [PATCH 10/13] trying to add compat53 directly --- build/tested/libs/ThreadPool.lua | 57 +++++++++++++++++--------------- src/tested/libs/ThreadPool.tl | 54 +++++++++++++++--------------- 2 files changed, 57 insertions(+), 54 deletions(-) diff --git a/build/tested/libs/ThreadPool.lua b/build/tested/libs/ThreadPool.lua index 7ea89a1..f04e1ae 100644 --- a/build/tested/libs/ThreadPool.lua +++ b/build/tested/libs/ThreadPool.lua @@ -40,32 +40,35 @@ local function worker(num, run_coverage, linda) - local tl_ok, tl_mod = pcall(require, "tl") - if tl_ok then - local tl_load = tl_mod.load - local function tl_fallback_loader(modname) - local modpath = modname:gsub("%.", "/") - for template in package.path:gmatch("[^;]+") do - local basepath = template:gsub("%?", modpath) - local tlpath = basepath:gsub("%.lua$", ".tl") - if tlpath ~= basepath then - local f = io.open(tlpath, "rb") - if f then - local code = f:read("*all") - f:close() - local fn, err = tl_load(code, "@" .. tlpath) - if fn then return fn end - return nil, "Error compiling '" .. tlpath .. "': " .. tostring(err) - end - end - end - end - if package.searchers then - table.insert(package.searchers, tl_fallback_loader) - else - table.insert(package.loaders, tl_fallback_loader) - end - end + + + + + + + + + + + + + + + + + + + + + + + + + + + + + local luacov @@ -115,7 +118,7 @@ function ThreadPool.init(workers, run_coverage) for i = 1, workers do - local worker_lane = lanes.gen("*", worker) + local worker_lane = lanes.gen("*", { required = { "compat54" } }, worker) instance.workers[i] = worker_lane(i, run_coverage, instance.linda) end return instance diff --git a/src/tested/libs/ThreadPool.tl b/src/tested/libs/ThreadPool.tl index bc35d49..109d97f 100644 --- a/src/tested/libs/ThreadPool.tl +++ b/src/tested/libs/ThreadPool.tl @@ -43,32 +43,32 @@ local function worker(num: integer, run_coverage: boolean, linda: lanes.Linda) -- package.loaders (not position 2 like tl.loader() does) so that compiled .lua -- versions of framework modules are still found first, avoiding expensive -- tl.new_env()+tl.check() calls on framework internals across all worker threads. - local tl_ok, tl_mod = pcall(require, "tl") - if tl_ok then - local tl_load = (tl_mod as any).load - local function tl_fallback_loader(modname: string): function, string - local modpath = modname:gsub("%.", "/") - for template in package.path:gmatch("[^;]+") do - local basepath = template:gsub("%?", modpath) - local tlpath = basepath:gsub("%.lua$", ".tl") - if tlpath ~= basepath then - local f = io.open(tlpath, "rb") - if f then - local code = f:read("*all") - f:close() - local fn, err = (tl_load as function(string, string): (function, string))(code, "@" .. tlpath) - if fn then return fn end - return nil, "Error compiling '" .. tlpath .. "': " .. tostring(err) - end - end - end - end - if (package as any).searchers then - table.insert((package as any).searchers, tl_fallback_loader) - else - table.insert((package as any).loaders, tl_fallback_loader) - end - end + -- local tl_ok, tl_mod = pcall(require, "tl") + -- if tl_ok then + -- local tl_load = (tl_mod as any).load + -- local function tl_fallback_loader(modname: string): function, string + -- local modpath = modname:gsub("%.", "/") + -- for template in package.path:gmatch("[^;]+") do + -- local basepath = template:gsub("%?", modpath) + -- local tlpath = basepath:gsub("%.lua$", ".tl") + -- if tlpath ~= basepath then + -- local f = io.open(tlpath, "rb") + -- if f then + -- local code = f:read("*all") + -- f:close() + -- local fn, err = (tl_load as function(string, string): (function, string))(code, "@" .. tlpath) + -- if fn then return fn end + -- return nil, "Error compiling '" .. tlpath .. "': " .. tostring(err) + -- end + -- end + -- end + -- end + -- if (package as any).searchers then + -- table.insert((package as any).searchers, tl_fallback_loader) + -- else + -- table.insert((package as any).loaders, tl_fallback_loader) + -- end + -- end local luacov: luacov_type @@ -118,7 +118,7 @@ function ThreadPool.init(workers: integer, run_coverage: boolean): ThreadPool for i = 1, workers do -- Create worker lanes with separate state - local worker_lane = lanes.gen("*", worker) + local worker_lane = lanes.gen("*", {required = {"compat54"}}, worker) instance.workers[i] = worker_lane(i, run_coverage, instance.linda) end return instance From 12b01192726f30b59db7256b4fa6e18f7811b021 Mon Sep 17 00:00:00 2001 From: FourierTransformer Date: Mon, 4 May 2026 21:18:26 -0500 Subject: [PATCH 11/13] here we go! --- build/tested/libs/ThreadPool.lua | 2 +- src/tested/libs/ThreadPool.tl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/tested/libs/ThreadPool.lua b/build/tested/libs/ThreadPool.lua index f04e1ae..5f29358 100644 --- a/build/tested/libs/ThreadPool.lua +++ b/build/tested/libs/ThreadPool.lua @@ -118,7 +118,7 @@ function ThreadPool.init(workers, run_coverage) for i = 1, workers do - local worker_lane = lanes.gen("*", { required = { "compat54" } }, worker) + local worker_lane = lanes.gen("*", { required = { "compat53" } }, worker) instance.workers[i] = worker_lane(i, run_coverage, instance.linda) end return instance diff --git a/src/tested/libs/ThreadPool.tl b/src/tested/libs/ThreadPool.tl index 109d97f..fe59a1b 100644 --- a/src/tested/libs/ThreadPool.tl +++ b/src/tested/libs/ThreadPool.tl @@ -118,7 +118,7 @@ function ThreadPool.init(workers: integer, run_coverage: boolean): ThreadPool for i = 1, workers do -- Create worker lanes with separate state - local worker_lane = lanes.gen("*", {required = {"compat54"}}, worker) + local worker_lane = lanes.gen("*", {required = {"compat53"}}, worker) instance.workers[i] = worker_lane(i, run_coverage, instance.linda) end return instance From f28ffc5ab9237bc8ed3c000958e2ea7672949044 Mon Sep 17 00:00:00 2001 From: FourierTransformer Date: Mon, 4 May 2026 21:36:23 -0500 Subject: [PATCH 12/13] trying teal searcher instead --- build/tested/libs/ThreadPool.lua | 48 ++++++++++++++------------------ src/tested/libs/ThreadPool.tl | 48 ++++++++++++++------------------ 2 files changed, 42 insertions(+), 54 deletions(-) diff --git a/build/tested/libs/ThreadPool.lua b/build/tested/libs/ThreadPool.lua index 5f29358..2bd176e 100644 --- a/build/tested/libs/ThreadPool.lua +++ b/build/tested/libs/ThreadPool.lua @@ -43,32 +43,26 @@ local function worker(num, run_coverage, linda) - - - - - - - - - - - - - - - - - - - - - - - - - - + local tl_ok, tl_mod = pcall(require, "tl") + if tl_ok then + local tl_load = tl_mod.load + local function tl_fallback_loader(modname) + + local found, fd = tl_mod.search_module(modname, false) + if not found then return end + + local code = fd:read("*all") + fd:close() + local fn, err = (tl_load)(code, "@" .. found) + if fn then return fn end + return nil, "Error compiling '" .. found .. "': " .. tostring(err) + end + if package.searchers then + table.insert(package.searchers, tl_fallback_loader) + else + table.insert(package.loaders, tl_fallback_loader) + end + end local luacov @@ -118,7 +112,7 @@ function ThreadPool.init(workers, run_coverage) for i = 1, workers do - local worker_lane = lanes.gen("*", { required = { "compat53" } }, worker) + local worker_lane = lanes.gen("*", worker) instance.workers[i] = worker_lane(i, run_coverage, instance.linda) end return instance diff --git a/src/tested/libs/ThreadPool.tl b/src/tested/libs/ThreadPool.tl index fe59a1b..644c857 100644 --- a/src/tested/libs/ThreadPool.tl +++ b/src/tested/libs/ThreadPool.tl @@ -43,32 +43,26 @@ local function worker(num: integer, run_coverage: boolean, linda: lanes.Linda) -- package.loaders (not position 2 like tl.loader() does) so that compiled .lua -- versions of framework modules are still found first, avoiding expensive -- tl.new_env()+tl.check() calls on framework internals across all worker threads. - -- local tl_ok, tl_mod = pcall(require, "tl") - -- if tl_ok then - -- local tl_load = (tl_mod as any).load - -- local function tl_fallback_loader(modname: string): function, string - -- local modpath = modname:gsub("%.", "/") - -- for template in package.path:gmatch("[^;]+") do - -- local basepath = template:gsub("%?", modpath) - -- local tlpath = basepath:gsub("%.lua$", ".tl") - -- if tlpath ~= basepath then - -- local f = io.open(tlpath, "rb") - -- if f then - -- local code = f:read("*all") - -- f:close() - -- local fn, err = (tl_load as function(string, string): (function, string))(code, "@" .. tlpath) - -- if fn then return fn end - -- return nil, "Error compiling '" .. tlpath .. "': " .. tostring(err) - -- end - -- end - -- end - -- end - -- if (package as any).searchers then - -- table.insert((package as any).searchers, tl_fallback_loader) - -- else - -- table.insert((package as any).loaders, tl_fallback_loader) - -- end - -- end + local tl_ok, tl_mod = pcall(require, "tl") + if tl_ok then + local tl_load = tl_mod.load + local function tl_fallback_loader(modname: string): function, string + -- search_all=false: finds only .tl files (not .lua), and respects TL_PATH + local found, fd = tl_mod.search_module(modname, false) + if not found then return end + + local code = fd:read("*all") + fd:close() + local fn, err = (tl_load as function(string, string): (function, string))(code, "@" .. found) + if fn then return fn end + return nil, "Error compiling '" .. found .. "': " .. tostring(err) + end + if package.searchers then + table.insert(package.searchers, tl_fallback_loader) + else + table.insert(package.loaders, tl_fallback_loader) + end + end local luacov: luacov_type @@ -118,7 +112,7 @@ function ThreadPool.init(workers: integer, run_coverage: boolean): ThreadPool for i = 1, workers do -- Create worker lanes with separate state - local worker_lane = lanes.gen("*", {required = {"compat53"}}, worker) + local worker_lane = lanes.gen("*", worker) instance.workers[i] = worker_lane(i, run_coverage, instance.linda) end return instance From f49ab57aa0effd581d8129a963503ef3a3be2075 Mon Sep 17 00:00:00 2001 From: FourierTransformer Date: Tue, 5 May 2026 17:19:33 -0500 Subject: [PATCH 13/13] cleaning things up and clarifying AI usage --- README.md | 1 + build/tested/file_loader.lua | 1 - build/tested/libs/ThreadPool.lua | 7 +++---- docs/teal-support.md | 4 +++- src/tested/file_loader.tl | 5 ++--- src/tested/libs/ThreadPool.tl | 17 ++++++++--------- 6 files changed, 17 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 6147fbf..87c7ba1 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,7 @@ You can see more tests in this repo's [tests](https://github.com/FourierTransfor - AI was used to help research Lua internals (mostly around file loading and the debug module) - AI helped generate a prettier terminal output. - I fed it my [original terminal output](./docs/original-output.txt), and it re-formatted it to something that looks a lot closer to the final terminal output. +- AI has been used to help debug issues ## Licenses Parts of the following are included in the source code present in this repo: diff --git a/build/tested/file_loader.lua b/build/tested/file_loader.lua index dff793b..0e5dc06 100644 --- a/build/tested/file_loader.lua +++ b/build/tested/file_loader.lua @@ -51,7 +51,6 @@ if tl_ok then return load_function end file_loader.loader[".tl"] = load_teal_file - end return file_loader diff --git a/build/tested/libs/ThreadPool.lua b/build/tested/libs/ThreadPool.lua index 2bd176e..34d2013 100644 --- a/build/tested/libs/ThreadPool.lua +++ b/build/tested/libs/ThreadPool.lua @@ -43,17 +43,16 @@ local function worker(num, run_coverage, linda) - local tl_ok, tl_mod = pcall(require, "tl") + local tl_ok, tl = pcall(require, "tl") if tl_ok then - local tl_load = tl_mod.load local function tl_fallback_loader(modname) - local found, fd = tl_mod.search_module(modname, false) + local found, fd = tl.search_module(modname, false) if not found then return end local code = fd:read("*all") fd:close() - local fn, err = (tl_load)(code, "@" .. found) + local fn, err = tl.load(code, "@" .. found) if fn then return fn end return nil, "Error compiling '" .. found .. "': " .. tostring(err) end diff --git a/docs/teal-support.md b/docs/teal-support.md index d37b8c4..63570d5 100644 --- a/docs/teal-support.md +++ b/docs/teal-support.md @@ -32,4 +32,6 @@ Assuming I had multiple unit test files that all pull in `utf8validator`, every For example, if you are doing TDD, you may want to accept the performance loss and use Teal unit test files so that `tested` is _always_ using the Teal files as a source. If you have a large test suite where Lua benchmarking matters, it may make more sense to compile and then test. -In the future, I may consider adding in some way to avoid that additional compilation, so any Teal modules only get compiled once, but it sort've goes against the ethos of unit testing should be isolated if `require`'d modules start being shared across files. \ No newline at end of file +Another thing to keep in mind, if there is a Lua and Teal file in the Lua's instance search path with the same `require`-able name, the Lua file will be pulled in first. + +In the future, I may consider adding in some way to avoid that additional compilation, so any Teal modules only get compiled once, but it sort've goes against the ethos of unit testing (ie: tests should be isolated from one another) if `require`'d modules start being shared across files. diff --git a/src/tested/file_loader.tl b/src/tested/file_loader.tl index 81fd3f9..0a958a2 100644 --- a/src/tested/file_loader.tl +++ b/src/tested/file_loader.tl @@ -37,7 +37,7 @@ end function file_loader.load_and_register_handler(filepath: string) local handler = file_loader.load_file(filepath) as types.FileLoaderHandler - file_loader.register_handler(handler.extension, handler.loader) + file_loader.register_handler(handler.extension, handler.loader) end local tl_ok, tl = pcall(require, "tl") @@ -51,7 +51,6 @@ if tl_ok then return load_function end file_loader.loader[".tl"] = load_teal_file - -- tl.loader() end -return file_loader \ No newline at end of file +return file_loader diff --git a/src/tested/libs/ThreadPool.tl b/src/tested/libs/ThreadPool.tl index 644c857..53c9f37 100644 --- a/src/tested/libs/ThreadPool.tl +++ b/src/tested/libs/ThreadPool.tl @@ -38,22 +38,21 @@ end local function worker(num: integer, run_coverage: boolean, linda: lanes.Linda) logger:info("Starting worker %d", num) - -- Register a low-priority Teal fallback loader so nested `require()` calls inside - -- test files can find .tl modules. We intentionally append to the END of - -- package.loaders (not position 2 like tl.loader() does) so that compiled .lua - -- versions of framework modules are still found first, avoiding expensive - -- tl.new_env()+tl.check() calls on framework internals across all worker threads. - local tl_ok, tl_mod = pcall(require, "tl") + -- Unfortunately have to handle this as more of a special case than I was hoping for... + -- To be able to have teal files depend on other teal files, a package loader needs to be added + -- I can't just use tl.load() to handle this here, because it causes the concurrent tests to hang + -- (similar to the luacov problems below). Still not entirely sure why, but appending this loader + -- does appear to solve the issue + local tl_ok, tl = pcall(require, "tl") if tl_ok then - local tl_load = tl_mod.load local function tl_fallback_loader(modname: string): function, string -- search_all=false: finds only .tl files (not .lua), and respects TL_PATH - local found, fd = tl_mod.search_module(modname, false) + local found, fd = tl.search_module(modname, false) if not found then return end local code = fd:read("*all") fd:close() - local fn, err = (tl_load as function(string, string): (function, string))(code, "@" .. found) + local fn, err = tl.load(code, "@" .. found) if fn then return fn end return nil, "Error compiling '" .. found .. "': " .. tostring(err) end