mirror of
https://gitcode.com/JianFeeeee/LuaCangjia_api.git
synced 2026-09-21 17:38:12 +00:00
feat: 实现loadFunction预加载函数能力 + AI辅助编程标识
- 新增 loadFunction/callFunction/unloadFunction 预加载函数 API - 预加载语义:加载文件→顶层执行一次→返回函数存入Lua Registry→可多次调用 - 与管道模式(load/runScript)存储完全解耦:funcs[]+Registry vs pkgs[]+虚拟栈 - 新增错误码 5023/5024/5025 - 新增单元测试:仓颉侧 8 个 + C++ GTest 侧 11 个 - 本机以 Cangjie 1.1.0 实编译并通过功能运行验证 - README/doc 增加 AI 辅助编程标识及预加载函数模式说明
This commit is contained in:
@ -323,3 +323,178 @@ func testDefaultIOCallback(): Unit {
|
||||
let result = unsafe { defaultIO() }
|
||||
@Expect(result, 0)
|
||||
}
|
||||
|
||||
// ====================
|
||||
// 8. loadFunction / callFunction 预加载测试
|
||||
// ====================
|
||||
|
||||
@Test
|
||||
func testLoadFunctionAndCall(): Unit {
|
||||
let runner = LuaRunner()
|
||||
runner.loadFunction(scriptPath("func_add.lua"), "add")
|
||||
let res = runner.callFunction("add", "hello")
|
||||
// 闭包带计数器,第一次调用应返回 call #1
|
||||
@Expect(res, "result: hello (call #1)")
|
||||
}
|
||||
|
||||
@Test
|
||||
func testCallFunctionMultipleTimes(): Unit {
|
||||
let runner = LuaRunner()
|
||||
runner.loadFunction(scriptPath("func_multi_call.lua"), "multi")
|
||||
|
||||
let r1 = runner.callFunction("multi", "")
|
||||
@Expect(r1, "multi:init-done")
|
||||
|
||||
let r2 = runner.callFunction("multi", "")
|
||||
@Expect(r2, "multi:init-done")
|
||||
|
||||
let r3 = runner.callFunction("multi", "")
|
||||
@Expect(r3, "multi:init-done")
|
||||
|
||||
let r4 = runner.callFunction("multi", "")
|
||||
@Expect(r4, "multi:init-done")
|
||||
}
|
||||
|
||||
@Test
|
||||
func testCallFunctionCallCount(): Unit {
|
||||
let runner = LuaRunner()
|
||||
runner.loadFunction(scriptPath("func_add.lua"), "add")
|
||||
|
||||
@Expect(runner.callFunction("add", "a"), "result: a (call #1)")
|
||||
@Expect(runner.callFunction("add", "b"), "result: b (call #2)")
|
||||
@Expect(runner.callFunction("add", "c"), "result: c (call #3)")
|
||||
}
|
||||
|
||||
@Test
|
||||
func testCallFunctionNotFound(): Unit {
|
||||
let runner = LuaRunner()
|
||||
try {
|
||||
runner.callFunction("nonexistent", "")
|
||||
fail("Should throw function not found error")
|
||||
} catch (e: LuaError) {
|
||||
@Expect(e.code, 5023)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
func testLoadFunctionFileNotFound(): Unit {
|
||||
let runner = LuaRunner()
|
||||
try {
|
||||
runner.loadFunction("/no/such/file.lua", "bad")
|
||||
fail("Should throw file not found error")
|
||||
} catch (e: LuaError) {
|
||||
@Expect(e.code, 5003)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
func testLoadFunctionNotAFunction(): Unit {
|
||||
let runner = LuaRunner()
|
||||
try {
|
||||
runner.loadFunction(scriptPath("func_not_a_function.lua"), "bad")
|
||||
fail("Should throw function not valid error")
|
||||
} catch (e: LuaError) {
|
||||
@Expect(e.code, 5025)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
func testLoadFunctionDuplicate(): Unit {
|
||||
let runner = LuaRunner()
|
||||
runner.loadFunction(scriptPath("func_add.lua"), "dup")
|
||||
try {
|
||||
runner.loadFunction(scriptPath("func_add.lua"), "dup")
|
||||
fail("Should throw on duplicate name")
|
||||
} catch (e: LuaError) {
|
||||
@Expect(e.code, 5023)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
func testCallFunctionRuntimeError(): Unit {
|
||||
let runner = LuaRunner()
|
||||
runner.loadFunction(scriptPath("func_runtime_error.lua"), "bad")
|
||||
try {
|
||||
runner.callFunction("bad", "")
|
||||
fail("Should throw runtime error")
|
||||
} catch (e: LuaError) {
|
||||
@Expect(e.code, 5010)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
func testCallFunctionWithUnloadFunction(): Unit {
|
||||
let runner = LuaRunner()
|
||||
runner.loadFunction(scriptPath("func_add.lua"), "add")
|
||||
@Expect(runner.callFunction("add", "before"), "result: before (call #1)")
|
||||
|
||||
runner.unloadFunction("add")
|
||||
|
||||
try {
|
||||
runner.callFunction("add", "")
|
||||
fail("Should throw function not found after unloadFunction")
|
||||
} catch (e: LuaError) {
|
||||
@Expect(e.code, 5023)
|
||||
}
|
||||
|
||||
// 卸载后可重新加载同名函数
|
||||
runner.loadFunction(scriptPath("func_add.lua"), "add")
|
||||
@Expect(runner.callFunction("add", "after"), "result: after (call #1)")
|
||||
}
|
||||
|
||||
@Test
|
||||
func testLoadFunctionAndPipelineNoInterference(): Unit {
|
||||
let runner = LuaRunner()
|
||||
// 预加载函数(用独立 func 脚本)
|
||||
runner.loadFunction(scriptPath("func_add.lua"), "add")
|
||||
@Expect(runner.callFunction("add", "x"), "result: x (call #1)")
|
||||
|
||||
// 管道模式(用 pipeline 脚本,走 pkgs 栈)
|
||||
runner.load(scriptPath("pipeline_add_suffix.lua"), "add_suffix")
|
||||
.load(scriptPath("pipeline_to_upper.lua"), "to_upper")
|
||||
.load(scriptPath("pipeline_add_prefix.lua"), "add_prefix")
|
||||
|
||||
let initialData = runner.runScript(scriptPath("pipeline_generate_data.lua"), "hello")
|
||||
@Expect(initialData, "hello")
|
||||
|
||||
@Expect(runner.runScript("", ""), "[PREFIX] hello")
|
||||
@Expect(runner.runScript("", ""), "[PREFIX] HELLO")
|
||||
@Expect(runner.runScript("", ""), "[PREFIX] HELLO [SUFFIX]")
|
||||
|
||||
// 管道结束后,预加载函数仍可调用,且计数器继续
|
||||
@Expect(runner.callFunction("add", "y"), "result: y (call #2)")
|
||||
}
|
||||
|
||||
@Test
|
||||
func testLoadFunctionAndCleanCoexists(): Unit {
|
||||
let runner = LuaRunner()
|
||||
runner.loadFunction(scriptPath("func_add.lua"), "add")
|
||||
@Expect(runner.callFunction("add", "x"), "result: x (call #1)")
|
||||
|
||||
runner.clear()
|
||||
|
||||
try {
|
||||
runner.callFunction("add", "")
|
||||
fail("Should throw after clean")
|
||||
} catch (e: LuaError) {
|
||||
@Expect(e.code, 5023)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
func testLoadFunctionOverflow(): Unit {
|
||||
ensureGeneratedScriptsDir()
|
||||
let runner = LuaRunner()
|
||||
|
||||
for (i in 0..20) {
|
||||
let name = "overflow_func_${i}"
|
||||
let path = generatedScriptPath(name + ".lua")
|
||||
File.writeTo(path, ("return function() return \"" + name + "\" end").toArray())
|
||||
try {
|
||||
runner.loadFunction(path, name)
|
||||
} catch (e: LuaError) {
|
||||
@Expect(e.code, 5024)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user