In this fourth issue of our blog we look at wurstscript’s start into 2018, and our roadmap. Once again we’re excited to mention that users within our awesome community are getting involved and contribute to the wurst.
The theme for this months code snippet is unit testing in wurst.
WurstScript, or Wurst for short, aims to be a completely integrated wc3 modding solution, with a focus on higher level programming and IDE experience, without sacrificing efficiency of the generated map script.
runmap
command now uses war3.exe
if it is present, which can improve loading time. The game executable detection has also been improved.force
and gamecache
, enabling them to be ued in object editing and unit tests.StringHash
now returns values identical to those at runtime, thanks to @lepStringHash
implementation.Note: The showcase is now official - you should submit your wurst maps for a chance in the spotlight!
Our main goals for this year are:
wurst.build
and the setup tool to allow more complete and seamless map compilation. In detail: scenario
and force
optionsPreamble: The ‘unit’ in unit testing does not refer to wc3 units - rather, a unit is an individual piece of source code that is being tested.
Tests allow you to verify the behaviour of your code outside of warcraft 3 at compiletime. Instead of the game interpreting your generated Jass code, Wurst interprets it and can therefore assert correctness and find errors in code, before they happen in the game.
The major benefit of a unit test is that it can cover most imaginable behaviours, even those that rarely happens inside the game, easily, and without wasting time executing such behaviours inside the game.
One of the caveats of unit testing is that compiletime jass interpretation depends on the completeness and correctness of the wurst compiler that is performing the testing instead of the warcraft engine. Wurst does not implement every native, and since we don’t know the inner workings of wc3, it can’t emulate everything identically.
There are many benefits of unit testing overall, such as:
The easiest units to test are the ones that don’t include warcraft specific elements. Here are some condensed example unit tests for our data structures, arithmetics and string manipulation from the standard library.
@Test function testAdd()
new HashList<int>..add(5).get(0).assertEquals(5)
@Test function linearVecTest()
let v = linear(vec2(3,4), vec2(6,2), 0.5)
v.x.assertEquals(4.5)
v.y.assertEquals(3)
@Test function testJoin()
new LinkedList<string>()..add("this")..add("is")..add("a")..add("string")
.joinBy(" ").assertEquals("this is a string")
To make any function a test, just annotate it with @Test
. All functions with this annotation will then be recognized by wurst. This doesn’t limit the function in any way and it could theoretically still be used inside your code and not exclusivly as test, however that is not recommended.
A unit test consists of two parts - the execution of the to be tested code and an assertion, that compares the actual result with an expected value. You can find the assert functions inside the Wurstunit
package.
The most simple example is an arithmetic test, because we can easily find out the expected value. E.g.
@Test function example()
let actual = (10 .squared()) * 6
let expected = 600
actual.assertEquals(expected)
As you can see, we calculate what we want to test and then assert that the value is what we expect it to be.
In VScode, use F1 to open the task prompt and enter “run test” and choose one of the options.
You can see the result inside the Output tab.
And that’s it! You are now a testing guru. We hope you enjoyed reading this, and we look forward to next month’s blog post wherein we’ll take a practical look at composing visually beautiful spells in wurst.