Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 81 additions & 1 deletion spec/System/TestIdolatry_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ describe("TestIdolatry", function()
end)

-- Parsing: the three stat lines must resolve to mods that scale against those multipliers.
it("parses the three Idolatry stat lines", function()
it("parses Idolatry and bonded-idol stat lines", function()
local parseMod = LoadModule("Modules/ModParser")

-- Helper to find the Multiplier tag on a mod (tags are stored as array entries)
Expand Down Expand Up @@ -98,5 +98,85 @@ describe("TestIdolatry", function()
assert.are.equals("BASE", resist[1].type)
assert.are.equals(-4, resist[1].value)
assert.are.equals("NonIdolAugmentsInEquipment", multiplierTag(resist[1]).var)

-- 4) Fox Idol's unlock is an item-local flag, not a global condition.
local localUnlock = parseMod("Idols socketed in this item gain the benefits of their Bonded modifiers")
assert.are.equals(1, #localUnlock)
assert.are.equals("SocketedIdolsUseBondedModifiers", localUnlock[1].name)
assert.are.equals("FLAG", localUnlock[1].type)

-- 5) The ascendancy unlock is a flag consumed by calc setup, not a condition on each bonded mod.
local globalUnlock = parseMod("Gain the benefits of Bonded modifiers on Runes and Idols")
assert.are.equals(1, #globalUnlock)
assert.are.equals("CanUseBonded", globalUnlock[1].name)
assert.are.equals("FLAG", globalUnlock[1].type)
end)

it("enables only Idol Bonded modifiers from Fox Idol locally", function()
local item = new("Item", [[
Test Body
Rusted Cuirass
]])
item.itemSocketCount = 2
item.runes = { "Fox Idol", "Lesser Body Rune" }
item:UpdateRunes()
item:BuildAndParseRaw()
assert.is_true(item.socketedIdolsUseBondedModifiers)

local foxBondedLine
local bodyRuneBondedLife
for _, modLine in ipairs(item.runeModLines) do
if modLine.line == "Bonded: +5% to Quality of all Skills" then
foxBondedLine = modLine
end
if modLine.line == "Bonded: +20 to maximum Life" then
bodyRuneBondedLife = modLine
end
end
assert.is_not_nil(foxBondedLine)
assert.are.equals(0, #foxBondedLine.modList)
assert.is_not_nil(bodyRuneBondedLife)
assert.are.equals(0, #bodyRuneBondedLife.modList)

build.itemsTab:AddItem(item)
build.buildFlag = true
runCallback("OnFrame")

local modDB = build.calcsTab.mainEnv.itemModDB
local foxBondedQuality
for _, mod in ipairs(modDB.mods.GemProperty or { }) do
if mod.value.value == 5 and mod.source == item.modSource then
foxBondedQuality = mod
break
end
end
assert.is_not_nil(foxBondedQuality)
assert.is_not_nil(foxBondedLine.bondedModList)
assert.is_nil(bodyRuneBondedLife.bondedModList)

for _, mod in ipairs(modDB.mods.Life or { }) do
assert.is_false(mod.type == "BASE" and mod.value == 20 and mod.source == item.modSource)
end
end)

it("enables and scales Bonded modifiers from the ascendancy flag", function()
build.spec.allocNodes[42253] = build.spec.nodes[42253] -- Wisdom of the Maji

local item = new("Item", [[
Test Body
Rusted Cuirass
200% increased effect of Socketed Runes
]])
item.itemSocketCount = 1
item.runes = { "Lesser Body Rune" }
item:UpdateRunes()
item:BuildAndParseRaw()
build.itemsTab:AddItem(item)
build.buildFlag = true
runCallback("OnFrame")

local modDB = build.calcsTab.mainEnv.itemModDB
assert.are.equals(150, modDB:Sum("BASE", nil, "Life"))
assert.are.equals(60, modDB:Sum("BASE", nil, "Mana"))
end)
end)
15 changes: 11 additions & 4 deletions spec/System/TestItemParse_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -659,10 +659,15 @@ describe("TestItemParse", function()

assert.are.equals(3, item.itemSocketCount)
assert.are.same({ "Greater Glacial Rune", "Lesser Body Rune" }, item.runes)
assert.are.equals(1, item.runeModLines[1].runeCount)
assert.are.equals(1, item.runeModLines[2].runeCount)
assert.is_nil(item.runeModLines[3].runeCount)
assert.is_nil(item.runeModLines[4].runeCount)
local runeLines = { }
for _, modLine in ipairs(item.runeModLines) do
runeLines[modLine.line] = true
end
assert.are.equals(4, #item.runeModLines)
assert.is_true(runeLines["Adds 9 to 15 Cold Damage"])
assert.is_true(runeLines["Leeches 3% of Physical Damage as Life"])
assert.is_true(runeLines["Bonded: 5% increased maximum Life"])
assert.is_true(runeLines["Bonded: 30% increased Freeze Buildup"])
for _, rune in ipairs(item.runes) do
assert.are_not.equals("Lesser Glacial Rune", rune)
end
Expand All @@ -682,6 +687,8 @@ describe("TestItemParse", function()
assert.are.equals("+30 to maximum Life", item.runeModLines[1].line)
assert.are.equals("Bonded: +20 to maximum Life", item.runeModLines[2].line)
assert.are.equals("Bonded: +20 to maximum Mana", item.runeModLines[3].line)
assert.are.equals(0, #item.runeModLines[2].modList)
assert.are.equals(0, #item.runeModLines[3].modList)
end)

it("applies increased effect of socketed runes", function()
Expand Down
19 changes: 19 additions & 0 deletions spec/System/TestItemsTab_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,25 @@ describe("TestItemsTab", function()
assert.are.equals("Hits against you have 20% reduced Critical Damage Bonus", ticabaRune.lines[1])
assert.are.equals("Hits against you have 20% reduced Critical Damage Bonus", ticabaRune.lines[2])
end)

it("uses the regular rune mod as the dropdown label", function ()
local weaponMods = data.itemMods.Runes["Perfect Robust Rune"].weapon
assert.are.equals("+15 to Strength", weaponMods[1])
assert.are.same({ "Adds 6 to 10 Physical Damage to Attacks", "Adds 6 to 10 Fire damage to Attacks" }, { unpack(weaponMods.bonded) })

local item = new("Item", [[
Test Wand
Runic Fork
]])

for _, rune in ipairs(build.itemsTab:GetValidRunesForItem(item)) do
if rune.name == "Perfect Robust Rune" then
assert.are.equals("+15 to Strength", rune.label)
return
end
end
assert.fail("Perfect Robust Rune was not valid for a wand")
end)
end)

it("does nothing when no matching item is equipped", function ()
Expand Down
41 changes: 17 additions & 24 deletions spec/System/TestSocketables_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,19 @@ describe("TestSocketables", function()
-- Item Tab display Tests
-- Also checks slot type runes

local extractNamesFromModRunes = function(slotType)
local extractNamesFromModRunes = function(item)
local modRunes = LoadModule("../src/Data/ModRunes")
local names = { }
local baseType, specificType = item:GetSocketedAugmentTypes()
for name, rune in pairs(modRunes) do
for runeSlotType, mods in pairs(rune) do
if runeSlotType == slotType then
table.insert(names, name)
if rune[baseType] or rune[specificType] then
names[name] = true
else
for soulCoreType in pairs(item.socketedSoulCoreTypes) do
if rune[soulCoreType] and rune[soulCoreType].type == "SoulCore" then
names[name] = true
break
end
end
end
end
Expand All @@ -23,36 +29,23 @@ describe("TestSocketables", function()
-- ConPrintf("Testing: %s", slotType)
local itemRaw = "Test\n" .. itemBase .. "\nSockets: S"

local modRunes = extractNamesFromModRunes(slotType)

-- Create an ItemTab and add a socketable item to it
local item = new("Item", itemRaw)
local modRunes = extractNamesFromModRunes(item)

build.itemsTab:AddItem(item)
build.itemsTab:SetDisplayItem(item)
runCallback("OnFrame")

-- Extract the proper slot type runes from the list
-- The dropdown combines broad and specific slot types, then deduplicates by name.
-- Compare that exact union so both missing and incorrectly included runes fail.
local itemTabRunes = { }
for _, rune in ipairs(build.itemsTab.controls["displayItemRune1"].list) do
if rune.slot == slotType then
table.insert(itemTabRunes, rune.name)
end
end
-- To keep the test fast, only check that the lengths match
-- This should also catch issues with multi-mod line runes since the rune name will appear
-- for the number of mod lines that the rune has.
if #itemTabRunes ~= #modRunes then
ConPrintf("Item Tab Runes for slot type '%s':", slotType)
for _, name in ipairs(itemTabRunes) do
ConPrintf(" %s", name)
end
ConPrintf("Mod Runes for slot type '%s':", slotType)
for _, name in ipairs(modRunes) do
ConPrintf(" %s", name)
if rune.name ~= "None" then
itemTabRunes[rune.name] = true
end
end
assert.are.equals(#itemTabRunes, #modRunes, "Mismatch in number of runes for slot type: " .. slotType)
assert.are.same(modRunes, itemTabRunes, "Rune list mismatch for slot type: " .. slotType)
end

-- Note: Except for weapon/armour/caster,
Expand Down Expand Up @@ -113,4 +106,4 @@ describe("TestSocketables", function()

-- it("'Dagger' runes appear in Items tab", slotTypeTest("dagger", ""))

end)
end)
Loading
Loading