forked from google-deepmind/lab
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathposition_trigger_test.lua
More file actions
310 lines (278 loc) · 8.38 KB
/
position_trigger_test.lua
File metadata and controls
310 lines (278 loc) · 8.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
local asserts = require 'testing.asserts'
local PositionTrigger = require 'common.position_trigger'
local set = require 'common.set'
local test_runner = require 'testing.test_runner'
local tests = {}
local HAPPINESS_LAYER = [[
..LL.LL..
.L..L..L.
..L...L..
...L.L...
....L....
]]
local UNHAPPY_POSITION = {50, 50} -- bottom left
local HAPPY_POSITION = {150, 350} -- left-most `L`
-- Update without any triggers.
function tests.testEmptyUpdate()
local triggers = PositionTrigger.new()
triggers:update(HAPPY_POSITION)
end
-- Create and remove a trigger multiple times.
function tests.testRemove()
local fired = false
local triggers = PositionTrigger.new()
for i = 1, 3 do
-- Create.
assert(not triggers:exists("testTrigger"))
triggers:start{
name = 'testTrigger',
maze = HAPPINESS_LAYER,
triggerWhenEnter = 'L',
callback = function() fired = true end,
}
assert(not fired)
assert(triggers:exists("testTrigger"))
-- Remove.
triggers:remove("testTrigger")
assert(not fired)
assert(not triggers:exists("testTrigger"))
end
end
-- Set up two triggers and verify the enter one fires when the first update is
-- on the trigger, and the exit one fires when the second update is off the
-- trigger.
function tests.testFirstUpdateTrigger()
local triggers = PositionTrigger.new()
-- Create trigger to fire .
-- Ensure it doesn't fire immediately.
local firedEnter = false
local firedExit = false
triggers:start{
name = 'testEnterTrigger',
maze = HAPPINESS_LAYER,
triggerWhenEnter = 'L',
callback = function() firedEnter = true end,
}
triggers:start{
name = 'testExitTrigger',
maze = HAPPINESS_LAYER,
triggerWhenExit = 'L',
callback = function() firedExit = true end,
}
assert(not firedEnter)
assert(not firedExit)
assert(triggers:exists("testEnterTrigger"))
assert(triggers:exists("testExitTrigger"))
-- Update position to one that should fire and check that it fired on enter
-- trigger, but not on exit trigger.
triggers:update(HAPPY_POSITION)
assert(firedEnter)
assert(not triggers:exists("testEnterTrigger"))
assert(not firedExit)
assert(triggers:exists("testExitTrigger"))
-- Update position to one that's outside, and check that the exit trigger
-- fired.
triggers:update(UNHAPPY_POSITION)
assert(firedExit)
assert(not triggers:exists("testExitTrigger"))
end
-- Set up two triggers and verify that neither fire when the first update is
-- off the trigger, the enter one fires when the second update is on the
-- trigger, and the exit one fires when the third update is off the trigger.
function tests.testSecondUpdateTrigger()
local triggers = PositionTrigger.new()
-- Create trigger to fire .
-- Ensure it doesn't fire immediately.
local firedEnter = false
local firedExit = false
triggers:start{
name = 'testEnterTrigger',
maze = HAPPINESS_LAYER,
triggerWhenEnter = 'L',
callback = function() firedEnter = true end,
}
triggers:start{
name = 'testExitTrigger',
maze = HAPPINESS_LAYER,
triggerWhenExit = 'L',
callback = function() firedExit = true end,
}
assert(not firedEnter)
assert(not firedExit)
assert(triggers:exists("testEnterTrigger"))
assert(triggers:exists("testExitTrigger"))
-- Update position to one that's outside, and check that nothing triggers.
triggers:update(UNHAPPY_POSITION)
assert(not firedEnter)
assert(not firedExit)
assert(triggers:exists("testEnterTrigger"))
assert(triggers:exists("testExitTrigger"))
-- Update position to one that should fire and check that it fired on enter
-- trigger, but not on exit trigger.
triggers:update(HAPPY_POSITION)
assert(firedEnter)
assert(not triggers:exists("testEnterTrigger"))
assert(not firedExit)
assert(triggers:exists("testExitTrigger"))
-- Update position to one that's outside, and check that the exit trigger
-- fired.
triggers:update(UNHAPPY_POSITION)
assert(firedExit)
assert(not triggers:exists("testExitTrigger"))
end
-- When we return true from the callback, the trigger should be reset so that
-- it fires again.
function tests.testPersist()
local triggers = PositionTrigger.new()
local fired = false
triggers:start{
name = 'testTrigger',
maze = HAPPINESS_LAYER,
triggerWhenEnter = 'L',
callback = function()
fired = true
return true -- request trigger to persist.
end,
}
-- Update position and assert trigger gets triggered.
assert(not fired)
triggers:update(HAPPY_POSITION)
assert(fired)
-- Reset trigger, move off the position and back on.
-- Assert trigger gets triggered again.
fired = false
triggers:update(UNHAPPY_POSITION)
assert(not fired)
triggers:update(HAPPY_POSITION)
assert(fired)
end
--[[ Test starting and triggering multiple triggers in the same maze.
Key word argements:
* `maze` (string) text representation of the maze.
* `triggers` (array) values for triggerWhenEnter and triggerWhenExit for
series of triggers.
* `updatePositions` (array) {x,y} positions used in call to triggers:update().
* `fired` (array) indices of {x,y} positions used in call to
triggers:update().
--]]
local function testMultiple(kwargs)
local triggers = PositionTrigger.new()
-- Create triggers.
local fired = {}
for i = 1, #kwargs.triggers do
triggers:start{
name = "testTrigger" .. tostring(i),
maze = kwargs.maze,
triggerWhenEnter = kwargs.triggers[i].triggerWhenEnter,
triggerWhenExit = kwargs.triggers[i].triggerWhenExit,
callback = function()
fired[i] = true
return kwargs.triggers[i].persist
end
}
end
-- Repeatedly call triggers:update() and verify that the appropriate triggers
-- have been fired.
for j = 1, #kwargs.updatePositions do
local currentPosition = kwargs.updatePositions[j]
triggers:update(currentPosition)
-- Ensure exactly the correct triggers have fired.
assert(set.isSame(fired, kwargs.fired[j]))
-- Reset which triggers were fired.
fired = {}
end
end
-- Set up multiple triggers that complete in the order they're created.
function tests.testMultipleInOrder()
testMultiple{
maze = 'CD\n' ..
'AB',
triggers = {
{triggerWhenEnter = 'A'}, -- trigger 1
{triggerWhenEnter = 'B'}, -- trigger 2
{triggerWhenEnter = 'C'}, -- trigger 3
{triggerWhenEnter = 'D'}, -- trigger 4
},
updatePositions = {
{0, 0},
{100, 0},
{0, 100},
{100, 100},
},
fired = {
{[1] = true},
{[2] = true},
{[3] = true},
{[4] = true},
},
}
end
-- Set up multiple triggers, where some trigger at the same time.
function tests.testMultipleSimultaneous()
testMultiple{
maze = 'AA\n' ..
'AB',
triggers = {
{triggerWhenEnter = 'A'}, -- trigger 1
{triggerWhenEnter = 'B'}, -- trigger 2
},
updatePositions = {
{100, 100},
{100, 0},
{100, 0},
},
fired = {
{[1] = true},
{[2] = true},
{},
},
}
end
-- Set up multiple triggers, where some trigger on exit.
function tests.testMultipleEnterExit()
testMultiple{
maze = 'AB',
triggers = {
{triggerWhenEnter = 'A'}, -- trigger 1
{triggerWhenExit = 'B'}, -- trigger 2
{triggerWhenExit = 'A'}, -- trigger 3
},
updatePositions = {
{100, 0},
{0, 0},
{100, 0},
},
fired = {
{},
{[1] = true, [2] = true},
{[3] = true},
},
}
end
-- Set up multiple triggers, where some are reset after they trigger.
function tests.testMultiplePersist()
testMultiple{
maze = 'AB',
triggers = {
{triggerWhenEnter = 'A', persist = true}, -- trigger 1
{triggerWhenEnter = 'B', persist = true}, -- trigger 2
{triggerWhenExit = 'A', persist = true}, -- trigger 3
{triggerWhenExit = 'B', persist = true}, -- trigger 4
},
updatePositions = {
{0, 0},
{100, 0},
{100, 0},
{0, 0},
{100, 0},
},
fired = {
{[1] = true},
{[2] = true, [3] = true},
{},
{[1] = true, [4] = true},
{[2] = true, [3] = true},
},
}
end
return test_runner.run(tests)