Skip to content

Commit 9570b29

Browse files
committed
Merge branch 'lua_test_menu' into 'master'
Run Lua integration tests starting with menu script See merge request OpenMW/openmw!4556
2 parents d13f108 + 2892e19 commit 9570b29

14 files changed

+394
-295
lines changed

CI/run_integration_tests.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ git checkout FETCH_HEAD
99
cd ..
1010

1111
xvfb-run --auto-servernum --server-args='-screen 0 640x480x24x60' \
12-
scripts/integration_tests.py --omw build/install/bin/openmw --workdir integration_tests_output example-suite/
12+
scripts/integration_tests.py --verbose --omw build/install/bin/openmw --workdir integration_tests_output example-suite/
1313

1414
ls integration_tests_output/*.osg_stats.log | while read v; do
1515
scripts/osg_stats.py --stats '.*' --regexp_match < "${v}"

scripts/data/integration_tests/test_lua_api/test.lua scripts/data/integration_tests/test_lua_api/global.lua

+54-93
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ local vfs = require('openmw.vfs')
77
local world = require('openmw.world')
88
local I = require('openmw.interfaces')
99

10-
local function testTimers()
10+
testing.registerGlobalTest('timers', function()
1111
testing.expectAlmostEqual(core.getGameTimeScale(), 30, 'incorrect getGameTimeScale() result')
1212
testing.expectAlmostEqual(core.getSimulationTimeScale(), 1, 'incorrect getSimulationTimeScale result')
1313

@@ -39,9 +39,10 @@ local function testTimers()
3939
testing.expectGreaterOrEqual(ts1, 0.5, 'async:newSimulationTimer failed')
4040
testing.expectGreaterOrEqual(th2, 72, 'async:newUnsavableGameTimer failed')
4141
testing.expectGreaterOrEqual(ts2, 1, 'async:newUnsavableSimulationTimer failed')
42-
end
42+
end)
4343

44-
local function testTeleport()
44+
testing.registerGlobalTest('teleport', function()
45+
local player = world.players[1]
4546
player:teleport('', util.vector3(100, 50, 500), util.transform.rotateZ(math.rad(90)))
4647
coroutine.yield()
4748
testing.expect(player.cell.isExterior, 'teleport to exterior failed')
@@ -71,16 +72,16 @@ local function testTeleport()
7172
testing.expectEqualWithDelta(player.position.x, 50, 1, 'incorrect position after teleporting')
7273
testing.expectEqualWithDelta(player.position.y, -100, 1, 'incorrect position after teleporting')
7374
testing.expectEqualWithDelta(player.rotation:getYaw(), math.rad(-90), 0.05, 'teleporting changes rotation')
74-
end
75+
end)
7576

76-
local function testGetGMST()
77+
testing.registerGlobalTest('getGMST', function()
7778
testing.expectEqual(core.getGMST('non-existed gmst'), nil)
7879
testing.expectEqual(core.getGMST('Water_RippleFrameCount'), 4)
7980
testing.expectEqual(core.getGMST('Inventory_DirectionalDiffuseR'), 0.5)
8081
testing.expectEqual(core.getGMST('Level_Up_Level2'), 'something')
81-
end
82+
end)
8283

83-
local function testMWScript()
84+
testing.registerGlobalTest('MWScript', function()
8485
local variableStoreCount = 18
8586
local variableStore = world.mwscript.getGlobalVariables(player)
8687
testing.expectEqual(variableStoreCount, #variableStore)
@@ -100,7 +101,7 @@ local function testMWScript()
100101
indexCheck = indexCheck + 1
101102
end
102103
testing.expectEqual(variableStoreCount, indexCheck)
103-
end
104+
end)
104105

105106
local function testRecordStore(store, storeName, skipPairs)
106107
testing.expect(store.records)
@@ -121,7 +122,7 @@ local function testRecordStore(store, storeName, skipPairs)
121122
testing.expectEqual(status, true, storeName)
122123
end
123124

124-
local function testRecordStores()
125+
testing.registerGlobalTest('record stores', function()
125126
for key, type in pairs(types) do
126127
if type.records then
127128
testRecordStore(type, key)
@@ -140,9 +141,9 @@ local function testRecordStores()
140141
testRecordStore(types.NPC.classes, "classes")
141142
testRecordStore(types.NPC.races, "races")
142143
testRecordStore(types.Player.birthSigns, "birthSigns")
143-
end
144+
end)
144145

145-
local function testRecordCreation()
146+
testing.registerGlobalTest('record creation', function()
146147
local newLight = {
147148
isCarriable = true,
148149
isDynamic = true,
@@ -165,9 +166,9 @@ local function testRecordCreation()
165166
for key, value in pairs(newLight) do
166167
testing.expectEqual(record[key], value)
167168
end
168-
end
169+
end)
169170

170-
local function testUTF8Chars()
171+
testing.registerGlobalTest('UTF-8 characters', function()
171172
testing.expectEqual(utf8.codepoint("😀"), 0x1F600)
172173

173174
local chars = {}
@@ -192,9 +193,9 @@ local function testUTF8Chars()
192193
testing.expectEqual(utf8.codepoint(char), codepoint)
193194
testing.expectEqual(utf8.len(char), 1)
194195
end
195-
end
196+
end)
196197

197-
local function testUTF8Strings()
198+
testing.registerGlobalTest('UTF-8 strings', function()
198199
local utf8str = "Hello, 你好, 🌎!"
199200

200201
local str = ""
@@ -205,9 +206,9 @@ local function testUTF8Strings()
205206

206207
testing.expectEqual(utf8.len(utf8str), 13)
207208
testing.expectEqual(utf8.offset(utf8str, 9), 11)
208-
end
209+
end)
209210

210-
local function testMemoryLimit()
211+
testing.registerGlobalTest('memory limit', function()
211212
local ok, err = pcall(function()
212213
local t = {}
213214
local n = 1
@@ -218,14 +219,16 @@ local function testMemoryLimit()
218219
end)
219220
testing.expectEqual(ok, false, 'Script reaching memory limit should fail')
220221
testing.expectEqual(err, 'not enough memory')
221-
end
222+
end)
222223

223224
local function initPlayer()
225+
local player = world.players[1]
224226
player:teleport('', util.vector3(4096, 4096, 1745), util.transform.identity)
225227
coroutine.yield()
228+
return player
226229
end
227230

228-
local function testVFS()
231+
testing.registerGlobalTest('vfs', function()
229232
local file = 'test_vfs_dir/lines.txt'
230233
local nosuchfile = 'test_vfs_dir/nosuchfile'
231234
testing.expectEqual(vfs.fileExists(file), true, 'lines.txt should exist')
@@ -269,12 +272,11 @@ local function testVFS()
269272
for _,v in pairs(expectedLines) do
270273
testing.expectEqual(getLine(), v)
271274
end
272-
end
275+
end)
273276

274-
local function testCommitCrime()
275-
initPlayer()
276-
local player = world.players[1]
277-
testing.expectEqual(player == nil, false, 'A viable player reference should exist to run `testCommitCrime`')
277+
testing.registerGlobalTest('commit crime', function()
278+
local player = initPlayer()
279+
testing.expectEqual(player == nil, false, 'A viable player reference should exist to run `commit crime`')
278280
testing.expectEqual(I.Crimes == nil, false, 'Crimes interface should be available in global contexts')
279281

280282
-- Reset crime level to have a clean slate
@@ -292,82 +294,41 @@ local function testCommitCrime()
292294
types.Player.setCrimeLevel(player, 0)
293295
testing.expectEqual(I.Crimes.commitCrime(player, { victim = victim, type = types.Player.OFFENSE_TYPE.Theft, arg = 50 }).wasCrimeSeen, true, "Running a crime with a valid victim should notify them when the player is not sneaking, even if it's not explicitly passed in")
294296
testing.expectEqual(types.Player.getCrimeLevel(player), 0, "Crime level should not change if the victim's alarm value is low and there's no other witnesses")
295-
end
297+
end)
296298

297-
local function testRecordModelProperty()
298-
initPlayer()
299+
testing.registerGlobalTest('record model property', function()
299300
local player = world.players[1]
300301
testing.expectEqual(types.NPC.record(player).model, 'meshes/basicplayer.dae')
302+
end)
303+
304+
local function registerPlayerTest(name)
305+
testing.registerGlobalTest(name, function()
306+
local player = initPlayer()
307+
testing.runLocalTest(player, name)
308+
end)
301309
end
302310

303-
tests = {
304-
{'timers', testTimers},
305-
{'rotating player with controls.yawChange should change rotation', function()
306-
initPlayer()
307-
testing.runLocalTest(player, 'playerYawRotation')
308-
end},
309-
{'rotating player with controls.pitchChange should change rotation', function()
310-
initPlayer()
311-
testing.runLocalTest(player, 'playerPitchRotation')
312-
end},
313-
{'rotating player with controls.pitchChange and controls.yawChange should change rotation', function()
314-
initPlayer()
315-
testing.runLocalTest(player, 'playerPitchAndYawRotation')
316-
end},
317-
{'rotating player should not lead to nan rotation', function()
318-
initPlayer()
319-
testing.runLocalTest(player, 'playerRotation')
320-
end},
321-
{'playerForwardRunning', function()
322-
initPlayer()
323-
testing.runLocalTest(player, 'playerForwardRunning')
324-
end},
325-
{'playerDiagonalWalking', function()
326-
initPlayer()
327-
testing.runLocalTest(player, 'playerDiagonalWalking')
328-
end},
329-
{'findPath', function()
330-
initPlayer()
331-
testing.runLocalTest(player, 'findPath')
332-
end},
333-
{'findRandomPointAroundCircle', function()
334-
initPlayer()
335-
testing.runLocalTest(player, 'findRandomPointAroundCircle')
336-
end},
337-
{'castNavigationRay', function()
338-
initPlayer()
339-
testing.runLocalTest(player, 'castNavigationRay')
340-
end},
341-
{'findNearestNavMeshPosition', function()
342-
initPlayer()
343-
testing.runLocalTest(player, 'findNearestNavMeshPosition')
344-
end},
345-
{'teleport', testTeleport},
346-
{'getGMST', testGetGMST},
347-
{'recordStores', testRecordStores},
348-
{'recordCreation', testRecordCreation},
349-
{'utf8Chars', testUTF8Chars},
350-
{'utf8Strings', testUTF8Strings},
351-
{'mwscript', testMWScript},
352-
{'testMemoryLimit', testMemoryLimit},
353-
{'playerMemoryLimit', function()
354-
initPlayer()
355-
testing.runLocalTest(player, 'playerMemoryLimit')
356-
end},
357-
{'player with equipped weapon on attack should damage health of other actors', function()
358-
initPlayer()
359-
world.createObject('basic_dagger1h', 1):moveInto(player)
360-
testing.runLocalTest(player, 'playerWeaponAttack')
361-
end},
362-
{'vfs', testVFS},
363-
{'testCommitCrime', testCommitCrime},
364-
{'recordModelProperty', testRecordModelProperty},
365-
}
311+
registerPlayerTest('player yaw rotation')
312+
registerPlayerTest('player pitch rotation')
313+
registerPlayerTest('player pitch and yaw rotation')
314+
registerPlayerTest('player rotation')
315+
registerPlayerTest('player forward running')
316+
registerPlayerTest('player diagonal walking')
317+
registerPlayerTest('findPath')
318+
registerPlayerTest('findRandomPointAroundCircle')
319+
registerPlayerTest('castNavigationRay')
320+
registerPlayerTest('findNearestNavMeshPosition')
321+
registerPlayerTest('player memory limit')
322+
323+
testing.registerGlobalTest('player weapon attack', function()
324+
local player = initPlayer()
325+
world.createObject('basic_dagger1h', 1):moveInto(player)
326+
testing.runLocalTest(player, 'player weapon attack')
327+
end)
366328

367329
return {
368330
engineHandlers = {
369-
onUpdate = testing.testRunner(tests),
370-
onPlayerAdded = function(p) player = p end,
331+
onUpdate = testing.updateGlobal,
371332
},
372-
eventHandlers = testing.eventHandlers,
333+
eventHandlers = testing.globalEventHandlers,
373334
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
local testing = require('testing_util')
2+
local menu = require('openmw.menu')
3+
4+
local function registerGlobalTest(name, description)
5+
testing.registerMenuTest(description or name, function()
6+
menu.newGame()
7+
coroutine.yield()
8+
testing.runGlobalTest(name)
9+
end)
10+
end
11+
12+
registerGlobalTest('timers')
13+
registerGlobalTest('teleport')
14+
registerGlobalTest('getGMST')
15+
registerGlobalTest('MWScript')
16+
registerGlobalTest('record stores')
17+
registerGlobalTest('record creation')
18+
registerGlobalTest('UTF-8 characters')
19+
registerGlobalTest('UTF-8 strings')
20+
registerGlobalTest('memory limit')
21+
registerGlobalTest('vfs')
22+
registerGlobalTest('commit crime')
23+
registerGlobalTest('record model property')
24+
25+
registerGlobalTest('player yaw rotation', 'rotating player with controls.yawChange should change rotation')
26+
registerGlobalTest('player pitch rotation', 'rotating player with controls.pitchChange should change rotation')
27+
registerGlobalTest('player pitch and yaw rotation', 'rotating player with controls.pitchChange and controls.yawChange should change rotation')
28+
registerGlobalTest('player rotation', 'rotating player should not lead to nan rotation')
29+
registerGlobalTest('player forward running')
30+
registerGlobalTest('player diagonal walking')
31+
registerGlobalTest('findPath')
32+
registerGlobalTest('findRandomPointAroundCircle')
33+
registerGlobalTest('castNavigationRay')
34+
registerGlobalTest('findNearestNavMeshPosition')
35+
registerGlobalTest('player memory limit')
36+
registerGlobalTest('player weapon attack', 'player with equipped weapon on attack should damage health of other actors')
37+
38+
return {
39+
engineHandlers = {
40+
onFrame = testing.makeUpdateMenu(),
41+
},
42+
eventHandlers = testing.menuEventHandlers,
43+
}

scripts/data/integration_tests/test_lua_api/openmw.cfg

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
content=test.omwscripts
1+
content=test_lua_api.omwscripts
22

33
# Needed to test `core.getGMST`
44
fallback=Water_RippleFrameCount,4

scripts/data/integration_tests/test_lua_api/player.lua

+9-9
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ local function rotateByPitch(object, target)
4040
rotate(object, target, nil)
4141
end
4242

43-
testing.registerLocalTest('playerYawRotation',
43+
testing.registerLocalTest('player yaw rotation',
4444
function()
4545
local initialAlphaXZ, initialGammaXZ = self.rotation:getAnglesXZ()
4646
local initialAlphaZYX, initialBetaZYX, initialGammaZYX = self.rotation:getAnglesZYX()
@@ -60,7 +60,7 @@ testing.registerLocalTest('playerYawRotation',
6060
testing.expectEqualWithDelta(gamma2, initialGammaZYX, 0.05, 'Gamma rotation in ZYX convention should not change')
6161
end)
6262

63-
testing.registerLocalTest('playerPitchRotation',
63+
testing.registerLocalTest('player pitch rotation',
6464
function()
6565
local initialAlphaXZ, initialGammaXZ = self.rotation:getAnglesXZ()
6666
local initialAlphaZYX, initialBetaZYX, initialGammaZYX = self.rotation:getAnglesZYX()
@@ -80,7 +80,7 @@ testing.registerLocalTest('playerPitchRotation',
8080
testing.expectEqualWithDelta(gamma2, targetPitch, 0.05, 'Incorrect gamma rotation in ZYX convention')
8181
end)
8282

83-
testing.registerLocalTest('playerPitchAndYawRotation',
83+
testing.registerLocalTest('player pitch and yaw rotation',
8484
function()
8585
local targetPitch = math.rad(-30)
8686
local targetYaw = math.rad(-60)
@@ -99,7 +99,7 @@ testing.registerLocalTest('playerPitchAndYawRotation',
9999
testing.expectEqualWithDelta(gamma2, math.rad(-16), 0.05, 'Incorrect gamma rotation in ZYX convention')
100100
end)
101101

102-
testing.registerLocalTest('playerRotation',
102+
testing.registerLocalTest('player rotation',
103103
function()
104104
local rotation = math.sqrt(2)
105105
local endTime = core.getSimulationTime() + 3
@@ -123,7 +123,7 @@ testing.registerLocalTest('playerRotation',
123123
end
124124
end)
125125

126-
testing.registerLocalTest('playerForwardRunning',
126+
testing.registerLocalTest('player forward running',
127127
function()
128128
local startPos = self.position
129129
local endTime = core.getSimulationTime() + 1
@@ -141,7 +141,7 @@ testing.registerLocalTest('playerForwardRunning',
141141
testing.expectEqualWithDelta(direction.y, 1, 0.1, 'Run forward, Y coord')
142142
end)
143143

144-
testing.registerLocalTest('playerDiagonalWalking',
144+
testing.registerLocalTest('player diagonal walking',
145145
function()
146146
local startPos = self.position
147147
local endTime = core.getSimulationTime() + 1
@@ -220,7 +220,7 @@ testing.registerLocalTest('findNearestNavMeshPosition',
220220
'Navigation mesh position ' .. testing.formatActualExpected(result, expected))
221221
end)
222222

223-
testing.registerLocalTest('playerMemoryLimit',
223+
testing.registerLocalTest('player memory limit',
224224
function()
225225
local ok, err = pcall(function()
226226
local str = 'a'
@@ -232,7 +232,7 @@ testing.registerLocalTest('playerMemoryLimit',
232232
testing.expectEqual(err, 'not enough memory')
233233
end)
234234

235-
testing.registerLocalTest('playerWeaponAttack',
235+
testing.registerLocalTest('player weapon attack',
236236
function()
237237
camera.setMode(camera.MODE.ThirdPerson)
238238

@@ -346,5 +346,5 @@ return {
346346
engineHandlers = {
347347
onFrame = testing.updateLocal,
348348
},
349-
eventHandlers = testing.eventHandlers
349+
eventHandlers = testing.localEventHandlers,
350350
}

scripts/data/integration_tests/test_lua_api/test.omwscripts

-2
This file was deleted.

0 commit comments

Comments
 (0)