How is GSE Developed?

Mods for World of Warcraft are written in the Lua language. Blizzard expose most of the Lua language to Mods with a bunch of API’s for game related functions. GSE is developed to use a combination of these. With GSE2 a lot of work has gone into seperating the mod in to three logical layers. GUI, API and WOW specific stuff. The purpose of all this behind the scenes is that it allows us to UnitTest some parts of the mod.

A Unit Test is like taking a car and removing the carburetor. You can with that piece of kit in isolation measure that you can an amount of fuel into it and that its regulating the amount coming out the other end. You could change the internals within the carby but as long as the amount coming out is the same as what it did before you havn’t inadvertantly broken the carby.

This applies to GSE in that parts of the API that do not depend on WOW Specific stuff can be tested automatically every time I do a code change. The code for GSE is hosted on GitHub (GitHub - TimothyLuke/GSE-Advanced-Macro-Compiler: GSE is an alternative advanced macro editor and engine for World of Warcraft. It uses Travis for UnitTests, Coveralls to report on test coverage and the Curse packager to build and publish GSE.) Git is a tool used for Source Code Management. It tracks what is changed and is able to link those changes to a particular issue. Someone identifies a bug or an enhancement (Issues · TimothyLuke/GSE-Advanced-Macro-Compiler · GitHub) and you can track all the code changes that relate to that issue.

Attached to that is a Continuous Integration Tool - Travis. Travis watches GitHub for changes and when it does it performs a series of tests. It marks each code change as working or not working based on the results of these tests. The first is that all the Lua syntax is correct. EG if … then … end All the parts of the structure are in the places they need to be. The second is that the variables and methods that are described exist and provide the right entry. The next is that it goes throught the API code and creates a human readable programmers guide for someone trying to use GSE’s API (https://timothyluke.github.io/GnomeSequencer-Enhanced/docs/).

The last thing it does is perform GSE’s Unit Tests. Now as this is all out of game and it doesnt have access to WOW’s specific methods and functions so it cant test parts that use this. It cant for example evaluate if SpecID 70 is actually a Paladin spec as opposed to a Warrior one as this is part of WoWs functions. It can however check that a sequence is saved properly and the saved sequence matches what was first entered. The tests are called specs and are located GSE-Advanced-Macro-Compiler/spec at master · TimothyLuke/GSE-Advanced-Macro-Compiler · GitHub If any one of these tests fail Travis prevents this being pushed to Curse until the test is fixed. What this means is that issues that are reported via GitHub get UnitTests attached to them so that as the mod changes if it breaks these tests I know about before it happens for you as a user.

This is an example of a couple of specs added trying to sort out the parser:

  it("checks that ctrl:mods are retained", function()
    local originalstring = '/castsequence [mod:ctrl] !Rip, Ferocious Bite, Ferocious Bite, Ferocious Bite; [nomod] Rake, shred, shred, shred, shred'
    local newstring = GSE.TranslateString(originalstring, "enUS", "enUS")
    local finalstring = GSE.UnEscapeString(newstring)
    assert.are.equal(originalstring, finalstring)
  end)

  it ("checks that pet stuff is not weird", function()
    local originalstring = '/petautocaston [nogroup] Growl; [@focus,noexists] Growl'
    local newstring = GSE.TranslateString(originalstring, "enUS", "enUS")
    local finalstring = GSE.UnEscapeString(newstring)
    assert.are.equal(originalstring, finalstring)
  end)

  it("checks for weird macro translations that break things", function ()
    local originalstring = "/cast [mod:alt, talent:6/1, talent:7/1, nochanneling:Void Torrent] [mod:alt, talent:6/1, talent:7/2, nochanneling:Void Torrent] Power Infusion"
    local newstring = GSE.TranslateString(originalstring, "enUS", "enUS")
    local finalstring = GSE.UnEscapeString(newstring)
    assert.are.equal(originalstring, finalstring)

  end)

If everything passes here then the mod is pushed to Curse’s Git instance where they take my code, the translations and all the libraries make that a Zip file.

The limitation in all this is GUI stuff cant be tested outside the game. So things like a Widget not working properly or a macro using the wrong stepfunction etc cant be tested this way.

the TLDR:
Issue Raised -> Test Developed -> Code Fixed -> Push to Curse if nothing else was broken.

The bit I forgot to add was a tool called Coveralls.io. This tool watches unit tests and monitors which parts of the source code have been auto tested. For an example this is part of the Storage API - TimothyLuke/GnomeSequencer-Enhanced | Build 702 | ./GSE/API/Storage.lua | Coveralls - Test Coverage History & Statistics

The yellow lines have been tested automatically the red lines haven’t.

Very nice explanation Tim!

This hasn’t changed much at all in how GSE is developed. There are two differences to this process. When Travis finishes testing it creates two versions of GSE. One for Classic and One for Retail. The differences between them are the TOC lines for Interface Version.

Every time I commit a change to the GitHub repository, an alpha or a beta version of that change is pushed to Curse. When that has finised testing, I create a release (Releases · TimothyLuke/GSE-Advanced-Macro-Compiler · GitHub) and this is pushed to both WoWInterface and Curse/Twitch again for both Classic and Retail. By looking at the releases you can see what changed between each release and why line by line.