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
175 changes: 175 additions & 0 deletions spec/System/TestCompareBuySimilar_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
describe("Buy similar mod stat matching", function()
local bs = LoadModule("Classes/CompareBuySimilar")

describe("addModEntries mod matching", function()
it("matches impossible escape mods as options", function()
local fromNothing = new("Item", [[
Impossible Escape
Viridian Jewel
LevelReq: 0
Radius: Small
Limited to: 1
Implicits: 0
Passive skills in radius of Elemental Overload can be Allocated without being connected to your tree
Corrupted]])

local modSources = {
{ list = fromNothing.explicitModLines, type = "explicit" }
}
local modEntries = bs.addModEntries(fromNothing, modSources)
assert.equal(1, #modEntries)
assert.same(
{
formattedLines = { colorCodes.MAGIC .. "Passive skills in radius of Elemental Overload can be Allocated without being connected to your tree" },
type =
"explicit",
isOption = true,
invert = false,
tradeIds = { "explicit.stat_2422708892" },
value = 22088
},
modEntries[1])

local thread = new("Item", [[
Rarity: UNIQUE
Thread of Hope
Crimson Jewel
Radius: Variable
Implicits: 0
Only affects Passives in Massive Ring
-15% to all Elemental Resistances
Passive Skills in Radius can be Allocated without being connected to your tree
Passage]])
local modSources = {
{ list = thread.explicitModLines, type = "explicit" }
}
local modEntries = bs.addModEntries(thread, modSources)
assert.equal(4, #modEntries)
assert.equal(modEntries[1].tradeIds[1], "explicit.stat_3642528642")
assert.equal(modEntries[1].value, 5)
end)

it("combines mods that are the same stat", function()
local lifeDiamond = new("Item", [[
Test Subject
Diamond
Implicits: 0
+100 to Maximum Life
+50 to Maximum Life
+50% to Fire Resistance]])

local entries = bs.addModEntries(lifeDiamond, { { list = lifeDiamond.explicitModLines, type = "explicit" } })
assert.equal(2, #entries)
assert.equal(2, #entries[1].formattedLines)
assert.equal("+100 to Maximum Life", StripEscapes(entries[1].formattedLines[1]))
assert.equal("+50 to Maximum Life", StripEscapes(entries[1].formattedLines[2]))
assert.equal(150, entries[1].value)

local lifelessDiamond = new("Item", [[
Test Subject
Diamond
Implicits: 0
-100 to Maximum Life
+50 to Maximum Life
+50% to Fire Resistance]])
local entries = bs.addModEntries(lifelessDiamond,
{ { list = lifelessDiamond.explicitModLines, type = "explicit" } })
assert.equal(2, #entries)
assert.equal(2, #entries[1].formattedLines)
assert.equal(-50, entries[1].value)
end)

it("is not case-sensitive", function ()
local funnyItem = new("Item", [[
Test Subject
Diamond
Implicits: 1
+50 tO MaxIMum lifE]])

local entries = bs.addModEntries(funnyItem, {{list = funnyItem.implicitModLines, type = "implicit"}})
assert.equal(1, #entries)
end)

it("does not combine implicit and explicit mods", function()
local lifelessDiamond = new("Item", [[
Test Subject
Diamond
Implicits: 1
-100 to Maximum Life
+50 to Maximum Life]])
local entries = bs.addModEntries(lifelessDiamond,
{ { list = lifelessDiamond.implicitModLines, type = "implicit" }, { list = lifelessDiamond.explicitModLines, type = "explicit" } })
assert.equal(2, #entries)
assert.equal(-100, entries[1].value)
assert.equal(50, entries[2].value)
end)
end)
describe("popup URL controls", function()
local originalCopy
local originalOpenURL
local originalFetchLeagues
local copiedUrl
local searchEnv

before_each(function()
newBuild()
local requests = build.itemsTab.tradeQuery.tradeQueryRequests
originalFetchLeagues = requests.FetchLeagues
requests.FetchLeagues = function(_, realm, callback)
callback({ "Test League", "Standard" })
end
end)

after_each(function()
build.itemsTab.tradeQuery.tradeQueryRequests.FetchLeagues = originalFetchLeagues
searchEnv.Copy = originalCopy
searchEnv.OpenURL = originalOpenURL
bs.lastRealmIdx = nil
bs.lastLeagueIdx = nil
bs.lastListedIndex = nil
main:ClosePopup()
end)

local function openPopup()
local item = new("Item", "Rarity: Rare\nTest Ring\nRuby Ring\nImplicits: 0\n+50 to maximum Life")
bs.openPopup(item, "Ring", build)
local controls = main.popups[1].controls
searchEnv = getfenv(controls.search.onClick)

Check warning on line 137 in spec/System/TestCompareBuySimilar_spec.lua

View workflow job for this annotation

GitHub Actions / spellcheck

Unknown word (getfenv)
originalCopy = originalCopy or searchEnv.Copy
originalOpenURL = originalOpenURL or searchEnv.OpenURL
searchEnv.Copy = function(url) copiedUrl = url end
searchEnv.OpenURL = function() end
return controls
end

it("rebuilds the URL when league and listed status change", function()
local controls = openPopup()
controls.search.onClick()
local initialUrl = copiedUrl

controls.leagueDrop:SetSel(2)
controls.search.onClick()
assert.not_equal(initialUrl, copiedUrl)
assert.is_truthy(copiedUrl:find("/Standard?", 1, true))
local standardUrl = copiedUrl

controls.listedDrop:SetSel(4)
controls.search.onClick()
assert.not_equal(standardUrl, copiedUrl)
assert.is_truthy(copiedUrl:find("any", 1, true))
end)

it("persists popup selector choices", function()
local controls = openPopup()
controls.realmDrop.selFunc(1, "PoE2")
controls.leagueDrop:SetSel(2)
controls.listedDrop:SetSel(4)
main:ClosePopup()

controls = openPopup()
assert.equal(1, bs.lastRealmIdx)
assert.equal("Standard", controls.leagueDrop:GetSelValue())
assert.equal("Any", controls.listedDrop:GetSelValue())
end)
end)
end)
130 changes: 130 additions & 0 deletions spec/System/TestTradeHelpers_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
describe("TradeHelpers trade hash matching", function()
local tradeHelpers = LoadModule("Classes/TradeHelpers")

---@param ids number[]
---@param expected number
---@return boolean contains whether the given array contains the expected id
local function contains(ids, expected)
for _, id in ipairs(ids) do
if id == expected then return true end
end
return false
end

describe("modLineValue", function()
it("returns the single number on a line", function()
assert.equal(50, tradeHelpers.modLineValue("+50 to maximum Life"))
end)

it("returns the midpoint of a '# to #' range", function()
assert.equal(15, tradeHelpers.modLineValue("Adds 10 to 20 Fire Damage"))
assert.equal(12.5, tradeHelpers.modLineValue("Adds 10 to 15 Fire Damage"))
end)

it("handles negative numbers", function()
assert.equal(-10, tradeHelpers.modLineValue("-10% to Fire Resistance"))
end)

it("returns nil when onlyFromTo is set and there is no range", function()
assert.is_nil(tradeHelpers.modLineValue("+50 to maximum Life", true))
end)
end)

describe("findTradeIdOption", function()
it("matches a '#'-valued option and returns its value", function()
local tradeId, value = tradeHelpers.findTradeIdOption("Grants Level 20 Summon Bestial Snake Skill",
"explicit")
assert.equal("explicit.stat_2878779644", tradeId)
assert.equal(3, value)
end)

it("matches an exact-text option and returns no value", function()
local tradeId, value = tradeHelpers.findTradeIdOption("Allocates Tranquility", "enchant")
assert.equal("enchant.stat_2954116742", tradeId)
assert.equal(16246, value)
end)

it("matches a timeless jewel", function()
local tradeId, value = tradeHelpers.findTradeIdOption(
"Bathed in the blood of 666 sacrificed in the name of Doryani", "explicit")
assert.equal("explicit.pseudo_timeless_jewel_doryani", tradeId)
assert.equal(666, value)
end)

it("returns nil for an unmatchable line", function()
assert.is_nil(tradeHelpers.findTradeIdOption("+100 to IQ", "explicit"))
end)
end)
describe("findTradeHash", function()
it("matches a simple mod", function()
local ids, value = tradeHelpers.findTradeHash("+50 to maximum Life")
assert.equal(50, value)
assert.is_true(contains(ids, HashStats({ "base_maximum_life" })))
end)

it("matches a percentage mod", function()
local ids, value = tradeHelpers.findTradeHash("25% reduced maximum Energy Shield")
assert.equal(25, value)
assert.is_true(contains(ids, HashStats({ "maximum_energy_shield_+%" })))
end)

it("matches a # to # mod", function()
local ids, value = tradeHelpers.findTradeHash("Adds 5 to 15 Fire Damage")
assert.equal(10, value)
assert.is_true(contains(ids,
HashStats({ "local_minimum_added_fire_damage", "local_maximum_added_fire_damage" })))
end)

it("is case-insensitive", function()
local ids = tradeHelpers.findTradeHash(
"1 aDDED PASSiVe sKilL IS ONE wITh The ShiELd")
assert.is_true(contains(ids, HashStats({ "local_affliction_notable_one_with_the_shield" })))
end)

it("returns no results for an unmatchable line", function()
local ids = tradeHelpers.findTradeHash("+100 to IQ")
assert.equal(0, #ids)
end)

it("works thrice in a row", function()
local a = tradeHelpers.findTradeHash("+50 to maximum Life")
local b = tradeHelpers.findTradeHash("+50 to maximum Life")
local c = tradeHelpers.findTradeHash("+50 to maximum Life")
assert.same(a, b)
assert.same(b, c)
end)

it("detects inverted mods correctly", function()
-- note that this stat is a handwrap mod and doesn't actually exist on the trade site
local ids, value, shouldNegate = tradeHelpers.findTradeHash(
"Debuffs on you expire 100% slower while affected by Haste")
assert.equal(100, value)
assert.is_true(shouldNegate)
assert.equal(1, #ids)

local ids, value, shouldNegate = tradeHelpers.findTradeHash("67% reduced maximum life")
assert.equal(67, value)
assert.is_true(shouldNegate)
assert.equal(1, #ids)
end)
it("detects mods with lua pattern characters correctly", function()
local ids, value = tradeHelpers.findTradeHash(
"trigger Socketed Spells when you focus, with a 0.25 second cooldown")
assert.is_true(contains(ids, HashStats({ "trigger_socketed_spells_when_you_focus_%" })))
assert.equal(100, value)

local ids, value, shouldNegate = tradeHelpers.findTradeHash(
"10% reduced effect of Non-Curse Auras from your Skills on your Minions")
assert.is_true(contains(ids, HashStats({ "minions_have_non_curse_aura_effect_+%_from_parent_skills" })))
assert.equal(10, value)
assert.is_true(shouldNegate)
end)
it("detects passage modline correctly", function()
local ids = tradeHelpers.findTradeHash(
"Passive Skills in Radius can be Allocated without being connected to your tree")
assert.is_true(contains(ids,
HashStats({ "local_unique_jewel_nearby_disconnected_passives_can_be_allocated",
"unique_thread_of_hope_base_resist_all_elements_%" })))
end)
end)
end)
Loading
Loading