Files
tia-lsp/test/test_diagnostics_spec.lua
T
lazar f7f1062b90 feat: test suite expansion + case-insensitive builtin lookup (Phase 6)
Add 3 new test files:

test_grammar_spec.lua (36 tests):
- Block structure: RETURN, GOTO, AUTHOR/FAMILY, VAR DB_SPECIFIC, typed
  DATA_BLOCK, END_STRUCT; semicolon, case-insensitive keywords
- Data types: REF_TO, VARIANT, anonymous STRUCT, ARRAY[*], multidim
  ARRAY, all type_builtin aliases (LWORD, LINT, ULINT, UDINT, DATE,
  TIME_OF_DAY, DATE_AND_TIME, S5TIME, LTIME, DTL, LTOD, LDT)
- Literals: binary (2#), octal (8#), BOOL#TRUE, typed int (INT#),
  combined time (T#1h30m), WSTRING#, compound assignments, CASE labels
- Parser: case-insensitive var_temp, VAR DB_SPECIFIC, lowercase blocks

test_diagnostics_spec.lua (6 tests):
- Unknown attribute warning (SCL005: ExternalWriteable typo)
- Valid attributes pass (ExternalWritable, S7_SetPoint)
- Unknown type warning (SCL003)
- Known types pass (VARIANT, LWORD, DTL)
- IEC types pass (IEC_COUNTER, IEC_TIMER)

test_builtin_instructions.lua (5 tests):
- All 221 spec instructions are known
- All spec data types are known
- Key instructions have parameter signatures
- Total count > 300 functions, > 35 FBs

Fix builtin_instructions.lua:
- Make is_known_function/is_known_function_block/get_parameters
  case-insensitive (check both name:upper() and name) — fixes 45
  mixed-case instruction names like Chars_TO_Strg, AssignmentAttempt
- Add missing Chars_TO_Strg to FUNCTIONS table

Fix test_harness.lua:
- Update REF_PROJECT path to ~/Documents/siemens/...

All 85 tests pass (38 formatter + 3 plc_json + 36 grammar + 6
diagnostics + 5 builtin). 3 grammar tests marked as expected failures
for known edge cases (GOTO labels, typed DB, combined time values).
2026-07-18 20:22:00 +02:00

133 lines
3.4 KiB
Lua

local test = dofile("test/test_harness.lua")
package.path = package.path .. ";src/?.lua"
local script_path = debug.getinfo(1, "S").source:gsub("^@", ""):match("(.*/)") or "."
script_path = script_path:gsub("^test/", ""):gsub("/test$", "")
if script_path == "" then script_path = "." end
local diagnostics = dofile(script_path .. "/src/diagnostics.lua")
local builtin = dofile(script_path .. "/src/builtin_instructions.lua")
test.run_suite("Diagnostics Spec Tests", function()
local function test_unknown_attribute_warning()
local content = [[FUNCTION_BLOCK "Test"
VAR_INPUT
x { ExternalWriteable := 'False' } : Bool;
END_VAR
BEGIN
END_FUNCTION_BLOCK
]]
local diags = diagnostics.validate_diagnostics(content, {}, nil)
local found = false
for _, d in ipairs(diags) do
if d.code == "SCL005" and d.message:find("ExternalWriteable") then
found = true
end
end
test.assert(found, "should warn on unknown attribute ExternalWriteable (typo)")
end
local function test_valid_attribute_no_warning()
local content = [[FUNCTION_BLOCK "Test"
VAR_INPUT
x { ExternalWritable := 'False' } : Bool;
END_VAR
BEGIN
END_FUNCTION_BLOCK
]]
local diags = diagnostics.validate_diagnostics(content, {}, nil)
local found = false
for _, d in ipairs(diags) do
if d.code == "SCL005" then
found = true
end
end
test.assert(not found, "should NOT warn on valid attribute ExternalWritable")
end
local function test_s7_setpoint_attribute()
local content = [[TYPE "TestUDT"
STRUCT
x { S7_SetPoint := 'True' } : Byte;
END_STRUCT;
END_TYPE
]]
local diags = diagnostics.validate_diagnostics(content, {}, nil)
local found = false
for _, d in ipairs(diags) do
if d.code == "SCL005" then
found = true
end
end
test.assert(not found, "should NOT warn on S7_SetPoint attribute")
end
local function test_unknown_type_warning()
local content = [[FUNCTION_BLOCK "Test"
VAR
x : NonExistentType;
END_VAR
BEGIN
END_FUNCTION_BLOCK
]]
local diags = diagnostics.validate_diagnostics(content, {}, nil)
local found = false
for _, d in ipairs(diags) do
if d.code == "SCL003" and d.message:find("NonExistentType") then
found = true
end
end
test.assert(found, "should warn on unknown data type NonExistentType")
end
local function test_known_type_no_warning()
local content = [[FUNCTION_BLOCK "Test"
VAR
x : VARIANT;
y : LWORD;
z : DTL;
END_VAR
BEGIN
END_FUNCTION_BLOCK
]]
local diags = diagnostics.validate_diagnostics(content, {}, nil)
local found = false
for _, d in ipairs(diags) do
if d.code == "SCL003" then
found = true
end
end
test.assert(not found, "should NOT warn on known types VARIANT, LWORD, DTL")
end
local function test_iec_counter_no_warning()
local content = [[FUNCTION_BLOCK "Test"
VAR
ctr : IEC_COUNTER;
timer : IEC_TIMER;
END_VAR
BEGIN
END_FUNCTION_BLOCK
]]
local diags = diagnostics.validate_diagnostics(content, {}, nil)
local found = false
for _, d in ipairs(diags) do
if d.code == "SCL003" then
found = true
end
end
test.assert(not found, "should NOT warn on IEC_COUNTER and IEC_TIMER")
end
test_unknown_attribute_warning()
test_valid_attribute_no_warning()
test_s7_setpoint_attribute()
test_unknown_type_warning()
test_known_type_no_warning()
test_iec_counter_no_warning()
end)
test.report()