|
|
| (13 intermediate revisions by 2 users not shown) |
| Line 1: |
Line 1: |
| -- TEMPORARY test module.
| |
| -- {{#invoke:Sandbox/Vergir|test}}
| |
| local p = {} | | local p = {} |
| local heroes_data = mw.loadJsonData("Data:HeroData.json")
| |
| local old_module = require('Module:HeroData')
| |
|
| |
| local function raw_scaling(hero_data, scaling_type, stat)
| |
| local scaling = hero_data and hero_data[scaling_type .. "Scaling"]
| |
| if (scaling == nil or stat == nil) then return nil end
| |
| return scaling[stat]
| |
| end
| |
|
| |
| function p.get_scalings(hero_data, stat, include_zero)
| |
| local scalings = {}
| |
| for _, scaling_type in ipairs({"Level", "Spirit"}) do
| |
| local value = raw_scaling(hero_data, scaling_type, stat)
| |
| if (value ~= nil and (include_zero or value ~= 0)) then
| |
| table.insert(scalings, { type = scaling_type, value = value })
| |
| end
| |
| end
| |
| return scalings
| |
| end
| |
|
| |
| function p.get_hero_scaling_data(hero_data, hero_stat_key)
| |
| local scaling_data_returned = {}
| |
| -- Walked backwards so Level is written last and wins a value collision,
| |
| -- matching the original Spirit-then-Level assignment order.
| |
| local scalings = p.get_scalings(hero_data, hero_stat_key, true)
| |
| for i = #scalings, 1, -1 do
| |
| scaling_data_returned[scalings[i].value] = scalings[i].type
| |
| end
| |
| return scaling_data_returned
| |
| end
| |
|
| |
| local function repr(v)
| |
| if type(v) ~= 'table' then return tostring(v) end
| |
| local entries = {}
| |
| for k, val in pairs(v) do
| |
| table.insert(entries, tostring(k) .. '=' .. tostring(val))
| |
| end
| |
| table.sort(entries)
| |
| return '{' .. table.concat(entries, ',') .. '}'
| |
| end
| |
|
| |
| function p.test(frame)
| |
| local hero_keys, stat_keys, seen = {}, {}, {}
| |
| for hero_key in pairs(heroes_data) do table.insert(hero_keys, hero_key) end
| |
| table.sort(hero_keys)
| |
| for _, hero in pairs(heroes_data) do
| |
| local sources = {
| |
| hero,
| |
| hero.Weapon or {},
| |
| (hero.Weapon and hero.Weapon.AltFire) or {},
| |
| hero.LevelScaling or {},
| |
| hero.SpiritScaling or {},
| |
| }
| |
| for _, source in ipairs(sources) do
| |
| for stat in pairs(source) do
| |
| if type(stat) == 'string' then seen[stat] = true end
| |
| end
| |
| end
| |
| end
| |
| for stat in pairs(seen) do table.insert(stat_keys, stat) end
| |
| table.sort(stat_keys)
| |
|
| |
| local checked, mismatches = 0, {}
| |
| local zero_cases, collision_cases = 0, 0
| |
|
| |
| for _, hero_key in ipairs(hero_keys) do
| |
| local hero_data = heroes_data[hero_key]
| |
| for _, stat in ipairs(stat_keys) do
| |
| local a = repr(old_module.get_hero_scaling_data(hero_data, stat))
| |
| local b = repr(p.get_hero_scaling_data(hero_data, stat))
| |
| checked = checked + 1
| |
| if a ~= b then
| |
| table.insert(mismatches, hero_key .. ' / ' .. stat .. ': ' .. a .. ' vs ' .. b)
| |
| end
| |
| -- Coverage: does the data actually exercise the tricky paths?
| |
| local with_zero = p.get_scalings(hero_data, stat, true)
| |
| local without_zero = p.get_scalings(hero_data, stat)
| |
| if #with_zero ~= #without_zero then zero_cases = zero_cases + 1 end
| |
| if #with_zero == 2 and with_zero[1].value == with_zero[2].value then
| |
| collision_cases = collision_cases + 1
| |
| end
| |
| end
| |
| end
| |
|
| |
| local out = {
| |
| 'Comparisons: ' .. checked,
| |
| 'Mismatches: ' .. #mismatches,
| |
| 'Cases with a zero scaling (shim must keep them): ' .. zero_cases,
| |
| 'Cases where Level and Spirit share a value (collision order): ' .. collision_cases,
| |
| '',
| |
| }
| |
| for i, m in ipairs(mismatches) do
| |
| if i > 30 then table.insert(out, '... and ' .. (#mismatches - 30) .. ' more') break end
| |
| table.insert(out, '* <code>' .. m .. '</code>')
| |
| end
| |
| if #mismatches == 0 then table.insert(out, 'No differences.') end
| |
| return table.concat(out, '\n')
| |
| end
| |
|
| |
| return p | | return p |