Files
tia-lsp.nvim/test/test_integration.lua
T
lazar eb10b1c0df feat: add testing framework with reference project integration
- Add test/ directory with test harness and test files
- Add UDT, DB, FB parser tests
- Add PLC JSON and integration tests
- Test against reference project (239 UDTs, 12 DBs, 37 SCL, 13 XML)
- Fix attribute parsing to handle underscores (S7_SetPoint)
- Add ORGANIZATION_BLOCK support to FB parser
2026-02-23 13:29:38 +01:00

250 lines
6.2 KiB
Lua

local test = dofile("test/test_harness.lua")
package.path = package.path .. ";lua/?.lua;src/?.lua"
local udt_parser = require("scl.udt_parser")
local db_parser = require("scl.db_parser")
local fb_parser = require("scl.fb_parser")
local script_path = debug.getinfo(1, "S").source:gsub("^@", ""):match("(.*/)") or "."
script_path = script_path:gsub("^test/", ""):gsub("/tests$", "")
if script_path == "" then script_path = "." end
local plc_json = dofile(script_path .. "/src/plc_json.lua")
local function scan_directory(dir, ext)
local files = {}
local handle = io.popen('find "' .. dir .. '" -type f -name "*.' .. ext .. '" 2>/dev/null')
if handle then
for line in handle:lines() do
if line ~= "" then
table.insert(files, line)
end
end
handle:close()
end
return files
end
local function test_parse_all_udt_files()
udt_parser.clear_cache()
local udt_files = scan_directory(test.REF_PROJECT .. "/PLC data types", "udt")
test.assert_gt(#udt_files, 0, "should find UDT files in reference project")
local parsed = 0
local failed = {}
for _, filepath in ipairs(udt_files) do
local file = io.open(filepath, "r")
if file then
local content = file:read("*all")
file:close()
local udt, err = udt_parser.parse_udt_content(content, filepath)
if udt then
parsed = parsed + 1
else
table.insert(failed, filepath .. ": " .. (err or "unknown error"))
end
end
end
print(string.format("Parsed %d/%d UDT files", parsed, #udt_files))
if #failed > 0 then
print("Failed files:")
for _, f in ipairs(failed) do
print(" " .. f)
end
end
test.assert_gt(parsed, 0, "should parse at least one UDT file")
end
local function test_parse_all_db_files()
db_parser.clear_cache()
local db_files = scan_directory(test.REF_PROJECT .. "/Program blocks", "db")
test.assert_gt(#db_files, 0, "should find DB files in reference project")
local parsed = 0
local failed = {}
for _, filepath in ipairs(db_files) do
local file = io.open(filepath, "r")
if file then
local content = file:read("*all")
file:close()
local db, err = db_parser.parse_db_content(content, filepath)
if db then
parsed = parsed + 1
else
table.insert(failed, filepath .. ": " .. (err or "unknown error"))
end
end
end
print(string.format("Parsed %d/%d DB files", parsed, #db_files))
if #failed > 0 then
print("Failed files:")
for _, f in ipairs(failed) do
print(" " .. f)
end
end
test.assert_gt(parsed, 0, "should parse at least one DB file")
end
local function test_parse_all_scl_files()
fb_parser.clear_cache()
local scl_files = scan_directory(test.REF_PROJECT .. "/Program blocks", "scl")
test.assert_gt(#scl_files, 0, "should find SCL files in reference project")
local parsed = 0
local failed = {}
for _, filepath in ipairs(scl_files) do
local file = io.open(filepath, "r")
if file then
local content = file:read("*all")
file:close()
local fb, err = fb_parser.parse_fb_content(content, filepath)
if fb then
parsed = parsed + 1
else
table.insert(failed, filepath .. ": " .. (err or "unknown error"))
end
end
end
print(string.format("Parsed %d/%d SCL files", parsed, #scl_files))
if #failed > 0 then
print("Failed files:")
for _, f in ipairs(failed) do
print(" " .. f)
end
end
test.assert_gt(parsed, 0, "should parse at least one SCL file")
end
local function test_parse_xml_files()
local xml_files = scan_directory(test.REF_PROJECT, "xml")
local found = 0
for _, filepath in ipairs(xml_files) do
local file = io.open(filepath, "r")
if file then
local content = file:read("*all")
file:close()
if content and #content > 10 then
found = found + 1
end
end
end
print(string.format("Found %d/%d XML files", found, #xml_files))
test.assert(found > 0, "should find XML files")
end
local function test_type_resolution()
udt_parser.clear_cache()
db_parser.clear_cache()
fb_parser.clear_cache()
local udt_content = [[
TYPE "inner_type"
TITLE = Inner
VERSION : 0.1
STRUCT
x : Int;
y : Bool;
END_STRUCT;
END_TYPE
]]
local db_content = [[
DATA_BLOCK "test_db"
TITLE = Test
VERSION : 0.1
VAR
myInner : "inner_type";
simple : Bool;
END_VAR
END_DATA_BLOCK
]]
local fb_content = [[
FUNCTION_BLOCK "test_fb"
TITLE = Test
VERSION : 0.1
VAR_INPUT
input1 : "inner_type";
END_VAR
END_FUNCTION_BLOCK
]]
local udt = udt_parser.parse_udt_content(udt_content, "inner.udt")
if udt then udt_parser.register_inline_udt(udt) end
local db = db_parser.parse_db_content(db_content, "test.db")
if db then db_parser.register_inline_db(db) end
local fb = fb_parser.parse_fb_content(fb_content, "test.scl")
test.assert(udt_parser.is_udt_type("inner_type"), "inner_type should be recognized as UDT")
test.assert(db_parser.is_db_type("test_db"), "test_db should be recognized as DB")
local db_members = db_parser.get_db_members("test_db")
if db_members and db_members[1] then
test.assert_equals(db_members[1].is_udt, true, "DB member should be recognized as UDT reference")
end
end
local function test_workspace_type_loading()
plc_json.clear_cache()
local types = plc_json.get_types(test.REF_PROJECT)
local total_types = 0
for _ in pairs(types) do
total_types = total_types + 1
end
print(string.format("Loaded %d types from workspace", total_types))
test.assert_gt(total_types, 0, "should load types from reference project")
end
local function run_integration_tests()
test.run_suite("Integration Tests - Reference Project", function()
print("\n--- UDT Files ---")
test_parse_all_udt_files()
print("\n--- DB Files ---")
test_parse_all_db_files()
print("\n--- SCL Files ---")
test_parse_all_scl_files()
print("\n--- XML Files ---")
test_parse_xml_files()
print("\n--- Type Resolution ---")
test_type_resolution()
print("\n--- Workspace Type Loading ---")
test_workspace_type_loading()
end)
end
if vim then
vim.api.nvim_create_user_command("TestIntegration", function()
run_integration_tests()
end, {})
end
run_integration_tests()