diff --git a/.busted b/.busted new file mode 100644 index 00000000..d16c464b --- /dev/null +++ b/.busted @@ -0,0 +1,12 @@ +return { + _all = { + coverage = true, + verbose = true, + }, + default = { + directory = "src", + lpath = "../runtime/lua/?.lua", + helper = "HeadlessWrapper.lua", + ROOT = { "../spec" }, + } +} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..cef78f9a --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,28 @@ +name: Run Tests +on: + push: + branches: [ dev ] + pull_request: + branches: [ dev ] +jobs: + run_tests: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Install Lua/LuaJIT + uses: leafo/gh-actions-lua@v8.0.0 + with: + luaVersion: "luajit-2.0.5" + - name: Install LuaRocks + uses: leafo/gh-actions-luarocks@v4.0.0 + - name: Install busted + run: luarocks install busted + - name: Install cluacov + run: luarocks install cluacov + - name: Install coveralls integration + run: luarocks install luacov-coveralls + - name: Run tests + run: busted --lua=/home/runner/work/PathOfBuilding/PathOfBuilding/.lua/bin/luajit + - name: Report coverage + run: cd src; luacov-coveralls --repo-token=${{ secrets.github_token }} diff --git a/spec/System/TestAttacks_spec.lua b/spec/System/TestAttacks_spec.lua new file mode 100644 index 00000000..7603c3eb --- /dev/null +++ b/spec/System/TestAttacks_spec.lua @@ -0,0 +1,25 @@ +describe("TestAttacks", function() + before_each(function() + newBuild() + end) + + teardown(function() + -- newBuild() takes care of resetting everything in setup() + end) + + it("creates an item and has the correct crit chance", function() + assert.are.equals(build.calcsTab.mainOutput.CritChance, 0) + build.itemsTab:CreateDisplayItemFromRaw("New Item\nMaraketh Bow\nCrafted: true\nPrefix: None\nPrefix: None\nPrefix: None\nSuffix: None\nSuffix: None\nSuffix: None\nQuality: 20\nSockets: G-G-G-G-G-G\nLevelReq: 71\nImplicits: 1\n{tags:speed}10% increased Movement Speed") + build.itemsTab:AddDisplayItem() + runCallback("OnFrame") + assert.are.equals(build.calcsTab.mainOutput.CritChance, 5.5 * build.calcsTab.mainOutput.HitChance / 100) + end) + + it("creates an item and has the correct crit multi", function() + assert.are.equals(1.5, build.calcsTab.mainOutput.CritMultiplier) + build.itemsTab:CreateDisplayItemFromRaw("New Item\nAssassin Bow\nCrafted: true\nPrefix: None\nPrefix: None\nPrefix: None\nSuffix: None\nSuffix: None\nSuffix: None\nQuality: 20\nSockets: G-G-G-G-G-G\nLevelReq: 62\nImplicits: 1\n{tags:damage,critical}{range:0.5}+(15-25)% to Global Critical Strike Multiplier") + build.itemsTab:AddDisplayItem() + runCallback("OnFrame") + assert.are.equals(1.5 + 0.2, build.calcsTab.mainOutput.CritMultiplier) + end) +end) \ No newline at end of file diff --git a/spec/System/TestBuilds_spec.lua b/spec/System/TestBuilds_spec.lua new file mode 100644 index 00000000..dc206912 --- /dev/null +++ b/spec/System/TestBuilds_spec.lua @@ -0,0 +1,33 @@ +local function fetchBuilds(path, buildList) + buildList = buildList or {} + for file in lfs.dir(path) do + if file ~= "." and file ~= ".." then + local f = path..'/'..file + local attr = lfs.attributes (f) + assert(type(attr) == "table") + if attr.mode == "directory" then + fetchBuilds(f, buildList) + elseif file:match("^.+(%..+)$") == ".lua" then + buildList[file] = LoadModule(f) + end + end + end + return buildList +end + +describe("test all builds", function() + + local buildList = fetchBuilds("../spec/TestBuilds") + for buildName, testBuild in pairs(buildList) do + loadBuildFromXML(testBuild.xml) + for key, value in pairs(testBuild.output) do + it("on build: " .. buildName .. ", testing stat: " .. key, function() + if type(value) == "number" then + assert.are.same(round(value, 4), round(build.calcsTab.mainOutput[key] or 0, 4)) + else + assert.are.same(value, build.calcsTab.mainOutput[key]) + end + end) + end + end +end) diff --git a/spec/TestBuilds/.gitignore b/spec/TestBuilds/.gitignore new file mode 100644 index 00000000..87c309b7 --- /dev/null +++ b/spec/TestBuilds/.gitignore @@ -0,0 +1 @@ +# This file is to keep an empty TestBuilds folder around when the CI process uses it to find test builds if there aren't any to find \ No newline at end of file diff --git a/src/Export/spec.lua b/src/Export/spec.lua index 1dfe9d0a..e41987ec 100644 --- a/src/Export/spec.lua +++ b/src/Export/spec.lua @@ -1420,6 +1420,8 @@ return { width=50 } }, + ComponentWeapon={ + }, CooldownBypassTypes={ }, CooldownGroups={ diff --git a/src/HeadlessWrapper.lua b/src/HeadlessWrapper.lua index 2934fa66..cc5c8285 100644 --- a/src/HeadlessWrapper.lua +++ b/src/HeadlessWrapper.lua @@ -6,7 +6,7 @@ -- Callbacks local callbackTable = { } local mainObject -local function runCallback(name, ...) +function runCallback(name, ...) if callbackTable[name] then return callbackTable[name](...) elseif mainObject and mainObject[name] then @@ -143,7 +143,7 @@ function PCall(func, ...) end function ConPrintf(fmt, ...) -- Optional - --print(string.format(fmt, ...)) + print(string.format(fmt, ...)) end function ConPrintTable(tbl, noRecurse) end function ConExecute(cmd) end @@ -177,18 +177,18 @@ if mainObject.promptMsg then end -- The build module; once a build is loaded, you can find all the good stuff in here -local build = mainObject.main.modes["BUILD"] +build = mainObject.main.modes["BUILD"] -- Here's some helpful helper functions to help you get started -local function newBuild() +function newBuild() mainObject.main:SetMode("BUILD", false, "Help, I'm stuck in Path of Building!") runCallback("OnFrame") end -local function loadBuildFromXML(xmlText) +function loadBuildFromXML(xmlText) mainObject.main:SetMode("BUILD", false, "", xmlText) runCallback("OnFrame") end -local function loadBuildFromJSON(getItemsJSON, getPassiveSkillsJSON) +function loadBuildFromJSON(getItemsJSON, getPassiveSkillsJSON) mainObject.main:SetMode("BUILD", false, "") runCallback("OnFrame") local charData = build.importTab:ImportItemsAndSkills(getItemsJSON) @@ -196,10 +196,3 @@ local function loadBuildFromJSON(getItemsJSON, getPassiveSkillsJSON) -- You now have a build without a correct main skill selected, or any configuration options set -- Good luck! end - - --- Now you can mess around! - - --- Probably optional -runCallback("OnExit")