Skip to content

Commit 587c8d2

Browse files
committed
test(trade): cover attribute requirement trade filters
1 parent d3230f4 commit 587c8d2

2 files changed

Lines changed: 158 additions & 0 deletions

File tree

spec/System/TestTradeQueryGenerator_spec.lua

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,58 @@
1+
local dkjson = require "dkjson"
2+
13
describe("TradeQueryGenerator", function()
24
local mock_queryGen = new("TradeQueryGenerator", { itemsTab = {} })
35

6+
local function findStatFilter(queryTable, id)
7+
for _, group in ipairs(queryTable.query.stats) do
8+
for _, filter in ipairs(group.filters or {}) do
9+
if filter.id == id then
10+
return filter
11+
end
12+
end
13+
end
14+
end
15+
16+
local function finishQueryWithAttributeShortfall(shortfall, includeAttrReqs)
17+
local queryGen = new("TradeQueryGenerator", { itemsTab = {} })
18+
local queryTable
19+
local errMsg
20+
queryGen.modWeights = {
21+
{ tradeModId = "explicit.stat_3299347043", weight = 1, meanStatDiff = 1 },
22+
}
23+
queryGen.tradeTypeIndex = 1
24+
queryGen.requesterContext = {}
25+
queryGen.requesterCallback = function(_, queryJson, queryErrMsg)
26+
queryTable = dkjson.decode(queryJson)
27+
errMsg = queryErrMsg
28+
end
29+
queryGen.calcContext = {
30+
itemCategoryQueryStr = "ring",
31+
special = {},
32+
testItem = {
33+
BuildAndParseRaw = function() end,
34+
},
35+
baseOutput = { TotalDPS = 100 },
36+
baseStatValue = 0,
37+
options = {
38+
statWeights = { { stat = "TotalDPS", weightMult = 1 } },
39+
includeAllWEMods = false,
40+
includeAttrReqs = includeAttrReqs,
41+
includeMirrored = true,
42+
influence1 = 1,
43+
influence2 = 1,
44+
},
45+
attrReqShortfall = shortfall,
46+
}
47+
48+
local previousClosePopup = main.ClosePopup
49+
main.ClosePopup = function() end
50+
queryGen:FinishQuery()
51+
main.ClosePopup = previousClosePopup
52+
53+
return queryTable, errMsg
54+
end
55+
456
describe("ProcessMod", function()
557
-- Pass: Mod line maps correctly to trade stat entry without error
658
-- Fail: Mapping fails (e.g., no match found), indicating incomplete stat parsing for curse mods, potentially missing curse-enabling items in queries
@@ -57,4 +109,25 @@ describe("TradeQueryGenerator", function()
57109
_G.MAX_FILTERS = orig_max
58110
end)
59111
end)
112+
113+
describe("attribute requirement filters", function()
114+
it("adds needed attribute pseudo filters to the generated query", function()
115+
local queryTable, errMsg = finishQueryWithAttributeShortfall({ Str = 12, Dex = 34, Int = 56 }, true)
116+
assert.is_nil(errMsg)
117+
assert.are.equal(12, findStatFilter(queryTable, "pseudo.pseudo_total_strength").value.min)
118+
assert.are.equal(34, findStatFilter(queryTable, "pseudo.pseudo_total_dexterity").value.min)
119+
assert.are.equal(56, findStatFilter(queryTable, "pseudo.pseudo_total_intelligence").value.min)
120+
end)
121+
122+
it("omits attribute pseudo filters when disabled or no shortfall exists", function()
123+
local disabledQuery = finishQueryWithAttributeShortfall({ Str = 12, Dex = 34, Int = 56 }, false)
124+
local zeroQuery = finishQueryWithAttributeShortfall({ Str = 0, Dex = 0, Int = 0 }, true)
125+
assert.is_nil(findStatFilter(disabledQuery, "pseudo.pseudo_total_strength"))
126+
assert.is_nil(findStatFilter(disabledQuery, "pseudo.pseudo_total_dexterity"))
127+
assert.is_nil(findStatFilter(disabledQuery, "pseudo.pseudo_total_intelligence"))
128+
assert.is_nil(findStatFilter(zeroQuery, "pseudo.pseudo_total_strength"))
129+
assert.is_nil(findStatFilter(zeroQuery, "pseudo.pseudo_total_dexterity"))
130+
assert.is_nil(findStatFilter(zeroQuery, "pseudo.pseudo_total_intelligence"))
131+
end)
132+
end)
60133
end)

spec/System/TestTradeQuery_spec.lua

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,5 +53,90 @@ describe("TradeQuery", function()
5353
end)
5454
assert.are.equal(0, #tooltip.lines)
5555
end)
56+
57+
it("returns early from action button tooltips when filtering clears the selected result", function()
58+
local tq = newTradeQuery({
59+
resultTbl = { [1] = { [1] = { item_string = "Rarity: RARE\nBehemoth Hold\nGold Ring", amount = 1, currency = "chaos" } } },
60+
sortedResultTbl = { [1] = {} },
61+
})
62+
buildRow1Dropdown(tq)
63+
local tooltip = new("Tooltip")
64+
65+
assert.has_no.errors(function()
66+
tq.controls.importButton1.tooltipFunc(tooltip)
67+
tq.controls.whisperButton1.tooltipFunc(tooltip)
68+
end)
69+
assert.are.equal(0, #tooltip.lines)
70+
end)
71+
end)
72+
73+
describe("attribute requirement result filtering", function()
74+
local function newTradeQueryWithOutput(output, slotTbl)
75+
local calcCalls = 0
76+
local tq = new("TradeQuery", { itemsTab = {} })
77+
tq.slotTables[1] = slotTbl or { slotName = "Ring 1" }
78+
tq.resultTbl = {
79+
[1] = {
80+
[1] = { item_string = "Rarity: RARE\nBehemoth Hold\nGold Ring", amount = 1, currency = "chaos" },
81+
},
82+
}
83+
tq.sortModes = {
84+
Weight = "(Highest) Weighted Sum",
85+
}
86+
tq.itemsTab.build = {
87+
calcsTab = {
88+
GetMiscCalculator = function()
89+
return function()
90+
calcCalls = calcCalls + 1
91+
return output
92+
end, {}
93+
end,
94+
},
95+
}
96+
tq.itemsTab.slots = {
97+
["Ring 1"] = {},
98+
}
99+
return tq, function()
100+
return calcCalls
101+
end
102+
end
103+
104+
it("filters fetched results that do not meet attribute requirements", function()
105+
local tq = newTradeQueryWithOutput({ ReqStr = 50, Str = 40, ReqDex = 0, Dex = 0, ReqInt = 0, Int = 0 })
106+
tq.hideResultsFailingAttributeRequirements = true
107+
local sortedItems = tq:SortFetchResults(1, tq.sortModes.Weight)
108+
assert.are.equal(0, #sortedItems)
109+
end)
110+
111+
it("keeps fetched results that meet attribute requirements", function()
112+
local tq = newTradeQueryWithOutput({ ReqStr = 50, Str = 60, ReqDex = 30, Dex = 30, ReqInt = 20, Int = 25 })
113+
tq.hideResultsFailingAttributeRequirements = true
114+
local sortedItems = tq:SortFetchResults(1, tq.sortModes.Weight)
115+
assert.are.equal(1, #sortedItems)
116+
assert.are.equal(1, sortedItems[1].index)
117+
end)
118+
119+
it("filters fetched results that do not meet Omniscience requirements", function()
120+
local tq = newTradeQueryWithOutput({ ReqOmni = 100, Omni = 80 })
121+
tq.hideResultsFailingAttributeRequirements = true
122+
local sortedItems = tq:SortFetchResults(1, tq.sortModes.Weight)
123+
assert.are.equal(0, #sortedItems)
124+
end)
125+
126+
it("keeps fetched results without recalculating by default", function()
127+
local tq, calcCalls = newTradeQueryWithOutput({ ReqStr = 50, Str = 40, ReqDex = 0, Dex = 0, ReqInt = 0, Int = 0 })
128+
local sortedItems = tq:SortFetchResults(1, tq.sortModes.Weight)
129+
assert.are.equal(1, #sortedItems)
130+
assert.are.equal(1, sortedItems[1].index)
131+
assert.are.equal(0, calcCalls())
132+
end)
133+
134+
it("does not apply equipment attribute filtering to rows without a replacement slot", function()
135+
local tq, calcCalls = newTradeQueryWithOutput({ ReqStr = 50, Str = 40, ReqDex = 0, Dex = 0, ReqInt = 0, Int = 0 }, { slotName = "Megalomaniac", unique = true })
136+
local sortedItems = tq:SortFetchResults(1, tq.sortModes.Weight)
137+
assert.are.equal(1, #sortedItems)
138+
assert.are.equal(1, sortedItems[1].index)
139+
assert.are.equal(0, calcCalls())
140+
end)
56141
end)
57142
end)

0 commit comments

Comments
 (0)