Repository navigation
Expand file tree
/
Copy pathci_test_loading_order.lua
More file actions
223 lines (185 loc) · 7.69 KB
/
Copy pathci_test_loading_order.lua
File metadata and controls
223 lines (185 loc) · 7.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
#!/usr/bin/env lua
-- HealIQ Loading Order CI Test
-- Focused regression test for the .toc loading order issue
-- This test validates that the fix for issue #98 prevents future regressions
local function validate_loading_order()
print("🔍 Validating .toc loading order (Issue #98 regression test)")
-- Read .toc file
local file = io.open("HealIQ.toc", "r")
if not file then
print("❌ ERROR: Cannot read HealIQ.toc file")
return false
end
local lines = {}
for line in file:lines() do
table.insert(lines, line)
end
file:close()
-- Extract Lua files in loading order
local lua_files = {}
for _, line in ipairs(lines) do
local trimmed = line:match("^%s*(.-)%s*$")
if trimmed and trimmed:match("%.lua$") and not trimmed:match("^#") then
table.insert(lua_files, trimmed)
end
end
print(string.format("📋 Found %d Lua files in loading order", #lua_files))
-- Find positions of key files
local core_pos = nil
local logging_pos = nil
local base_rule_pos = nil
local first_rule_pos = nil
for i, luaFile in ipairs(lua_files) do
if luaFile == "Core.lua" then
core_pos = i
elseif luaFile == "Logging.lua" then
logging_pos = i
elseif luaFile == "rules/BaseRule.lua" then
base_rule_pos = i
end
-- Track the first rule file we encounter
if luaFile:match("^rules/") and not first_rule_pos then
first_rule_pos = i
end
end
-- Validate loading order
local errors = {}
if not core_pos then
table.insert(errors, "Core.lua not found in .toc file")
end
if not logging_pos then
table.insert(errors, "Logging.lua not found in .toc file")
end
if not base_rule_pos then
table.insert(errors, "rules/BaseRule.lua not found in .toc file")
end
if not first_rule_pos then
table.insert(errors, "No rule files found in .toc file")
end
if core_pos and first_rule_pos and core_pos >= first_rule_pos then
table.insert(errors, string.format("Core.lua (pos %d) must load before rule files (pos %d)", core_pos, first_rule_pos))
end
if logging_pos and first_rule_pos and logging_pos >= first_rule_pos then
table.insert(errors, string.format("Logging.lua (pos %d) must load before rule files (pos %d)", logging_pos, first_rule_pos))
end
if not base_rule_pos then
table.insert(errors, "BaseRule.lua not found in .toc file")
elseif base_rule_pos ~= first_rule_pos then
table.insert(errors, string.format("BaseRule.lua (pos %d) should be the first rule file (first rule at pos %d)", base_rule_pos, first_rule_pos or 0))
end
-- If base_rule_pos == first_rule_pos, then BaseRule.lua is correctly the first rule file
-- Report results
if #errors > 0 then
print("❌ LOADING ORDER VALIDATION FAILED:")
for _, error in ipairs(errors) do
print(" • " .. error)
end
return false
else
print("✅ Loading order validation passed!")
print(string.format(" • Core.lua loads at position %d", core_pos))
print(string.format(" • Logging.lua loads at position %d", logging_pos))
print(string.format(" • First rule file loads at position %d", first_rule_pos))
print(string.format(" • BaseRule.lua loads at position %d", base_rule_pos))
return true
end
end
local function validate_rule_files()
print("🔍 Validating rule file defensive initialization")
local rule_files = {
"rules/BaseRule.lua",
"rules/DefensiveCooldowns.lua",
"rules/HealingCooldowns.lua",
"rules/UtilityRules.lua",
"rules/AoERules.lua",
"rules/OffensiveRules.lua"
}
local errors = {}
for _, rule_file in ipairs(rule_files) do
local file = io.open(rule_file, "r")
if not file then
table.insert(errors, rule_file .. " not found")
else
local content = file:read("*all")
file:close()
-- Check for correct global namespace access pattern (not the old parameter pattern)
-- Look for the correct pattern and ensure no non-comment lines use the wrong pattern
local has_correct_pattern = content:find("local HealIQ = _G%.HealIQ")
local has_incorrect_pattern = false
-- Check each line to see if it uses the incorrect pattern (but not in comments)
for line in content:gmatch("[^\r\n]+") do
local trimmed_line = line:gsub("^%s*", "")
if trimmed_line:find("^local addonName, HealIQ = ") and not trimmed_line:find("^%-%-") then
has_incorrect_pattern = true
break
end
end
has_correct_pattern = has_correct_pattern and not has_incorrect_pattern
-- Check for defensive initialization (essential for handling WoW loading issues)
local has_defensive_init = (
content:find("HealIQ%.Rules = HealIQ%.Rules or {}") or
content:find("_G%.HealIQ = _G%.HealIQ or {}")
)
-- Check for proper error handling
local has_error_handling = content:find("addon not properly initialized")
if not has_correct_pattern then
table.insert(errors, rule_file .. " does not use correct global namespace pattern")
end
if not has_defensive_init then
table.insert(errors, rule_file .. " lacks defensive initialization")
end
if not has_error_handling then
table.insert(errors, rule_file .. " lacks proper error handling")
end
-- Test that the file can actually load without errors
-- Set up minimal HealIQ environment first to prevent defensive initialization errors
local original_healiq = _G.HealIQ
_G.HealIQ = _G.HealIQ or {
Rules = {},
Logging = { Error = function(msg) end }
}
local success, err = pcall(dofile, rule_file)
-- Restore original state
_G.HealIQ = original_healiq
if not success then
table.insert(errors, rule_file .. " fails to load: " .. tostring(err))
end
end
end
if #errors > 0 then
print("❌ RULE FILE VALIDATION FAILED:")
for _, error in ipairs(errors) do
print(" • " .. error)
end
return false
else
print("✅ Rule file validation passed!")
print(string.format(" • All %d rule files have defensive initialization", #rule_files))
return true
end
end
local function main()
print("=== HealIQ Loading Order Regression Test ===")
print("This test validates the fix for issue #98:")
print("'Error loading Interface/AddOns/HealIQ/rules/BaseRule.lua'")
print("")
local success1 = validate_loading_order()
print("")
local success2 = validate_rule_files()
print("")
if success1 and success2 then
print("🎉 ALL TESTS PASSED!")
print("✅ The .toc loading order issue has been fixed")
print("✅ Rule files are protected against loading failures")
print("✅ Regression protection is in place")
return true
else
print("💥 TESTS FAILED!")
print("❌ Loading order issue may have regressed")
print("❌ Manual intervention required")
return false
end
end
-- Run the test
local success = main()
os.exit(success and 0 or 1)