exploration.tests.test_analysis

  • Authors: Nissi, Jada, Rachel, Kaitlyn, Kitty, Peter Mawhorter
  • Consulted: Peter Mawhorter
  • Date: 2022-12-5
  • Purpose: Tests for exploration analysis.
  1"""
  2- Authors: Nissi, Jada, Rachel, Kaitlyn, Kitty, Peter Mawhorter
  3- Consulted: Peter Mawhorter
  4- Date: 2022-12-5
  5- Purpose: Tests for exploration analysis.
  6"""
  7
  8from .. import analysis, journal
  9
 10#Part of Rachel's journal:
 11JOURNAL = """
 12S Start_room::Start
 13  zz Starting_region
 14  A gain attack
 15  o right
 16  o left
 17x left coin_room sr
 18  o up above_coin_room fall
 19    q _wall_kick_jumps  # TODO: '?' syntax
 20t sr
 21x right platforms rp
 22  o up
 23  o right
 24x up dangerplat ud
 25"""
 26
 27BABY_JOURNAL = """
 28S Start
 29  A gain jump
 30  A gain attack
 31  n button check
 32  zz Wilds
 33  o up
 34    q _flight
 35  o left
 36x left left_nook right
 37a geo_rock
 38  At gain geo*15
 39  At deactivate
 40  o up
 41    q _tall_narrow
 42t right
 43  o right
 44    q attack
 45"""
 46
 47BABY_JOURNAL_2 = """
 48S Start
 49  A gain jump
 50  A gain attack
 51  n button check
 52  zz Wilds
 53  o up
 54    q _flight
 55  o left
 56x left left_nook right
 57"""
 58
 59REVISITS_JOURNAL = """
 60S A
 61x right B left
 62x down C up
 63x left D right
 64r up A down
 65t right
 66r down_left D up_right
 67t right
 68t up
 69t left
 70t down
 71"""
 72
 73
 74def test_CreateExploration() -> None:
 75    """
 76    Simple test to make sure we can create an exploration object for
 77    other tests in this file.
 78    """
 79    ex = journal.convertJournal(JOURNAL)
 80    assert len(ex) == 6
 81    assert ex.getActiveDecisions(0) == set()
 82    assert ex.getActiveDecisions(1) == {0}
 83
 84    assert bool(ex.getSituation(1).graph) is True
 85
 86
 87def test_countActionsAtDecision() -> None:
 88    """
 89    Test to make sure the number of actions in the whole graph
 90    at each step is accurate.
 91    """
 92    ex = journal.convertJournal(BABY_JOURNAL)
 93    assert analysis.perSituation(
 94        analysis.sumOfResults(
 95            analysis.perDecision(
 96                analysis.analyzeGraph(analysis.countActionsAtDecision)
 97            )
 98        )
 99    )(ex) == [0, 0, 1, 1, 1]
100
101    now = ex.getSituation()
102    graph = now.graph
103    startID = graph.resolveDecision("Start")
104    nookID = graph.resolveDecision("left_nook")
105    assert analysis.countActionsAtDecision(graph, startID) == 0
106    assert analysis.countActionsAtDecision(graph, nookID) == 1
107    # TODO: Further testing?
108
109
110def test_describeProgress() -> None:
111    """
112    Tests the `describeProgress` function.
113    """
114    e1 = journal.convertJournal(BABY_JOURNAL)
115    e2 = journal.convertJournal(BABY_JOURNAL_2)
116    e3 = journal.convertJournal(REVISITS_JOURNAL)
117
118    description = analysis.describeProgress(e1)
119    assert description == """\
120Start of the exploration
121Start exploring domain main at 0 (Start)
122  Gained capability 'attack'
123  Gained capability 'jump'
124At decision 0 (Start)
125  In region Wilds
126  There are transitions:
127    left to unconfirmed
128    up to unconfirmed; requires _flight
129  1 note(s) at this step
130Explore left from decision 0 (Start) to 2 (now Wilds::left_nook)
131At decision 2 (left_nook)
132  There are transitions:
133    right to 0 (Start)
134  There are actions:
135    geo_rock
136Do action geo_rock
137  Gained 15 geo(s)
138Take right from decision 2 (left_nook) to 0 (Start)
139At decision 0 (Start)
140  There are transitions:
141    left to 2 (left_nook)
142    right to unconfirmed; requires attack
143    up to unconfirmed; requires _flight
144Waiting for another action...
145End of the exploration.
146"""
147
148    description2 = analysis.describeProgress(e2)
149    assert description2 == """\
150Start of the exploration
151Start exploring domain main at 0 (Start)
152  Gained capability 'attack'
153  Gained capability 'jump'
154At decision 0 (Start)
155  In region Wilds
156  There are transitions:
157    left to unconfirmed
158    up to unconfirmed; requires _flight
159  1 note(s) at this step
160Explore left from decision 0 (Start) to 2 (now Wilds::left_nook)
161At decision 2 (left_nook)
162  There are transitions:
163    right to 0 (Start)
164Waiting for another action...
165End of the exploration.
166"""
167
168    description3 = analysis.describeProgress(e3)
169    assert description3 == """\
170Start of the exploration
171Start exploring domain main at 0 (A)
172At decision 0 (A)
173  There are transitions:
174    right to unconfirmed
175Explore right from decision 0 (A) to 1 (now B)
176At decision 1 (B)
177  There are transitions:
178    down to unconfirmed
179    left to 0 (A)
180Explore down from decision 1 (B) to 2 (now C)
181At decision 2 (C)
182  There are transitions:
183    left to unconfirmed
184    up to 1 (B)
185Explore left from decision 2 (C) to 3 (now D)
186At decision 3 (D)
187  There are transitions:
188    right to 2 (C)
189    up to 0 (A)
190Take up from decision 3 (D) to 0 (A)
191At decision 0 (A)
192  There are transitions:
193    down to 3 (D)
194    right to 1 (B)
195Take right from decision 0 (A) to 1 (B)
196At decision 1 (B)
197  There are transitions:
198    down to 2 (C)
199    down_left to 3 (D)
200    left to 0 (A)
201Take down_left from decision 1 (B) to 3 (D)
202At decision 3 (D)
203  There are transitions:
204    right to 2 (C)
205    up to 0 (A)
206    up_right to 1 (B)
207Take right from decision 3 (D) to 2 (C)
208At decision 2 (C)
209  There are transitions:
210    left to 3 (D)
211    up to 1 (B)
212Take up from decision 2 (C) to 1 (B)
213At decision 1 (B)
214  There are transitions:
215    down to 2 (C)
216    down_left to 3 (D)
217    left to 0 (A)
218Take left from decision 1 (B) to 0 (A)
219At decision 0 (A)
220  There are transitions:
221    down to 3 (D)
222    right to 1 (B)
223Take down from decision 0 (A) to 3 (D)
224At decision 3 (D)
225  There are transitions:
226    right to 2 (C)
227    up to 0 (A)
228    up_right to 1 (B)
229Waiting for another action...
230End of the exploration.
231"""
232
233
234def test_unexploredBranches() -> None:
235    """
236    Tests the `unexploredBranches` and related count functions.
237    """
238    ex = journal.convertJournal(JOURNAL)
239    assert analysis.unexploredBranches(ex.getSituation(0).graph) == []
240    g1 = ex.getSituation(1).graph
241    assert g1.destinationsFrom(0) == {
242        'right': 1,
243        'left': 2
244    }
245    assert g1.nameFor(1) == '_u.0'
246    assert g1.nameFor(2) == '_u.1'
247    assert analysis.unexploredBranches(ex.getSituation(1).graph) == [
248        (0, 'right'),
249        (0, 'left'),
250    ]
251    assert analysis.unexploredBranches(ex.getSituation(2).graph) == [
252        (0, 'right'),
253        (2, 'up'),
254    ]
255    assert analysis.unexploredBranches(ex.getSituation(3).graph) == [
256        (0, 'right'),
257        (2, 'up'),
258    ]
259    g4 = ex.getSituation(4).graph
260    assert g4.namesListing(set(g4.nodes)) == """\
261  0 (Start_room::Start)
262  1 (Start_room::platforms)
263  2 (Start_room::coin_room)
264  3 (Start_room::above_coin_room)
265  4 (_u.3)
266  5 (_u.4)
267"""
268    assert analysis.unexploredBranches(ex.getSituation(4).graph) == [
269        (1, 'up'),
270        (1, 'right'),
271        (2, 'up'),
272    ]
273    assert analysis.unexploredBranches(ex.getSituation(5).graph) == [
274        (1, 'right'),
275        (2, 'up'),
276    ]
277    allPerStep = analysis.perSituation(analysis.countAllUnexploredBranches)
278    traversablePerStep = analysis.perSituation(
279        analysis.countTraversableUnexploredBranches
280    )
281    assert allPerStep(ex) == [0, 2, 2, 2, 3, 2]
282    assert traversablePerStep(ex) == [0, 2, 1, 1, 2, 1]
283    # TODO
284
285
286def test_countBranches() -> None:
287    """
288    Tests the `countBranches` function.
289    """
290    ex = journal.convertJournal(BABY_JOURNAL)
291    ex2 = journal.convertJournal(BABY_JOURNAL_2)
292
293    # Note: as of v0.6, we can index an exploration to get a Situation,
294    # and most analysis functions want Situations as input
295
296    first = ex[0]
297    second = ex[1]
298    third = ex[2]
299    fourth = ex[3]
300    fifth = ex[4]
301
302    ex2first = ex2[0]
303    ex2second = ex2[1]
304    ex2third = ex2[2]
305
306    meanInStep = analysis.meanOfResults(
307        analysis.perDecision(
308            analysis.analyzeGraph(analysis.countBranches)
309        )
310    )
311    assert first.graph.namesListing(set(first.graph.nodes)) == """\
312  0 (Start)
313"""
314    assert meanInStep(first) == 0
315    assert meanInStep(second) == 2
316    assert meanInStep(third) == 1.5
317    assert meanInStep(fourth) == 2
318    assert meanInStep(fifth) == 2.5
319
320    startID = fifth.graph.resolveDecision("Start")
321    nookID = fifth.graph.resolveDecision("left_nook")
322    assert analysis.countBranches(second.graph, startID) == 2
323    assert analysis.countBranches(third.graph, startID) == 2
324    assert analysis.countBranches(third.graph, nookID) == 1
325    assert analysis.countBranches(fifth.graph, startID) == 3
326    assert analysis.countBranches(fifth.graph, nookID) == 2
327
328    assert meanInStep(ex2first) == 0
329    assert meanInStep(ex2second) == 2
330    assert meanInStep(ex2third) == 1.5
331
332
333def test_countRevisits() -> None:
334    """
335    Tests the `countRevisits` function
336    """
337
338    babyExp = journal.convertJournal(BABY_JOURNAL)
339    graph = babyExp.getSituation().graph
340    startID = graph.resolveDecision("Start")
341    nookID = graph.resolveDecision("left_nook")
342    assert analysis.countRevisits(babyExp, startID) == 1
343    assert analysis.countRevisits(babyExp, nookID) == 0
344    assert analysis.countRevisits(babyExp, 28309823) == 0
345
346    fullExp = journal.convertJournal(JOURNAL)
347    graph = fullExp.getSituation().graph
348    startID = graph.resolveDecision("Start")
349    coinRoomID = graph.resolveDecision("coin_room")
350    platformsID = graph.resolveDecision("platforms")
351    dangerplatID = graph.resolveDecision("dangerplat")
352    assert analysis.countRevisits(fullExp, startID) == 1
353    assert analysis.countRevisits(fullExp, coinRoomID) == 0
354    assert analysis.countRevisits(fullExp, platformsID) == 0
355    assert analysis.countRevisits(fullExp, dangerplatID) == 0
356
357    revExp = journal.convertJournal(REVISITS_JOURNAL)
358    graph = revExp.getSituation().graph
359    aID = graph.resolveDecision('A')
360    bID = graph.resolveDecision('B')
361    cID = graph.resolveDecision('C')
362    dID = graph.resolveDecision('D')
363    assert analysis.countRevisits(revExp, aID) == 2
364    assert analysis.countRevisits(revExp, bID) == 2
365    assert analysis.countRevisits(revExp, cID) == 1
366    assert analysis.countRevisits(revExp, dID) == 2
367
368    countAll = analysis.sumOfResults(
369        analysis.perExplorationDecision(
370            analysis.countRevisits
371        )
372    )
373    assert countAll(babyExp) == 1
374    assert countAll(fullExp) == 1
375    assert countAll(revExp) == 7
JOURNAL = "\nS Start_room::Start\n zz Starting_region\n A gain attack\n o right\n o left\nx left coin_room sr\n o up above_coin_room fall\n q _wall_kick_jumps # TODO: '?' syntax\nt sr\nx right platforms rp\n o up\n o right\nx up dangerplat ud\n"
BABY_JOURNAL = '\nS Start\n A gain jump\n A gain attack\n n button check\n zz Wilds\n o up\n q _flight\n o left\nx left left_nook right\na geo_rock\n At gain geo*15\n At deactivate\n o up\n q _tall_narrow\nt right\n o right\n q attack\n'
BABY_JOURNAL_2 = '\nS Start\n A gain jump\n A gain attack\n n button check\n zz Wilds\n o up\n q _flight\n o left\nx left left_nook right\n'
REVISITS_JOURNAL = '\nS A\nx right B left\nx down C up\nx left D right\nr up A down\nt right\nr down_left D up_right\nt right\nt up\nt left\nt down\n'
def test_CreateExploration() -> None:
75def test_CreateExploration() -> None:
76    """
77    Simple test to make sure we can create an exploration object for
78    other tests in this file.
79    """
80    ex = journal.convertJournal(JOURNAL)
81    assert len(ex) == 6
82    assert ex.getActiveDecisions(0) == set()
83    assert ex.getActiveDecisions(1) == {0}
84
85    assert bool(ex.getSituation(1).graph) is True

Simple test to make sure we can create an exploration object for other tests in this file.

def test_countActionsAtDecision() -> None:
 88def test_countActionsAtDecision() -> None:
 89    """
 90    Test to make sure the number of actions in the whole graph
 91    at each step is accurate.
 92    """
 93    ex = journal.convertJournal(BABY_JOURNAL)
 94    assert analysis.perSituation(
 95        analysis.sumOfResults(
 96            analysis.perDecision(
 97                analysis.analyzeGraph(analysis.countActionsAtDecision)
 98            )
 99        )
100    )(ex) == [0, 0, 1, 1, 1]
101
102    now = ex.getSituation()
103    graph = now.graph
104    startID = graph.resolveDecision("Start")
105    nookID = graph.resolveDecision("left_nook")
106    assert analysis.countActionsAtDecision(graph, startID) == 0
107    assert analysis.countActionsAtDecision(graph, nookID) == 1
108    # TODO: Further testing?

Test to make sure the number of actions in the whole graph at each step is accurate.

def test_describeProgress() -> None:
111def test_describeProgress() -> None:
112    """
113    Tests the `describeProgress` function.
114    """
115    e1 = journal.convertJournal(BABY_JOURNAL)
116    e2 = journal.convertJournal(BABY_JOURNAL_2)
117    e3 = journal.convertJournal(REVISITS_JOURNAL)
118
119    description = analysis.describeProgress(e1)
120    assert description == """\
121Start of the exploration
122Start exploring domain main at 0 (Start)
123  Gained capability 'attack'
124  Gained capability 'jump'
125At decision 0 (Start)
126  In region Wilds
127  There are transitions:
128    left to unconfirmed
129    up to unconfirmed; requires _flight
130  1 note(s) at this step
131Explore left from decision 0 (Start) to 2 (now Wilds::left_nook)
132At decision 2 (left_nook)
133  There are transitions:
134    right to 0 (Start)
135  There are actions:
136    geo_rock
137Do action geo_rock
138  Gained 15 geo(s)
139Take right from decision 2 (left_nook) to 0 (Start)
140At decision 0 (Start)
141  There are transitions:
142    left to 2 (left_nook)
143    right to unconfirmed; requires attack
144    up to unconfirmed; requires _flight
145Waiting for another action...
146End of the exploration.
147"""
148
149    description2 = analysis.describeProgress(e2)
150    assert description2 == """\
151Start of the exploration
152Start exploring domain main at 0 (Start)
153  Gained capability 'attack'
154  Gained capability 'jump'
155At decision 0 (Start)
156  In region Wilds
157  There are transitions:
158    left to unconfirmed
159    up to unconfirmed; requires _flight
160  1 note(s) at this step
161Explore left from decision 0 (Start) to 2 (now Wilds::left_nook)
162At decision 2 (left_nook)
163  There are transitions:
164    right to 0 (Start)
165Waiting for another action...
166End of the exploration.
167"""
168
169    description3 = analysis.describeProgress(e3)
170    assert description3 == """\
171Start of the exploration
172Start exploring domain main at 0 (A)
173At decision 0 (A)
174  There are transitions:
175    right to unconfirmed
176Explore right from decision 0 (A) to 1 (now B)
177At decision 1 (B)
178  There are transitions:
179    down to unconfirmed
180    left to 0 (A)
181Explore down from decision 1 (B) to 2 (now C)
182At decision 2 (C)
183  There are transitions:
184    left to unconfirmed
185    up to 1 (B)
186Explore left from decision 2 (C) to 3 (now D)
187At decision 3 (D)
188  There are transitions:
189    right to 2 (C)
190    up to 0 (A)
191Take up from decision 3 (D) to 0 (A)
192At decision 0 (A)
193  There are transitions:
194    down to 3 (D)
195    right to 1 (B)
196Take right from decision 0 (A) to 1 (B)
197At decision 1 (B)
198  There are transitions:
199    down to 2 (C)
200    down_left to 3 (D)
201    left to 0 (A)
202Take down_left from decision 1 (B) to 3 (D)
203At decision 3 (D)
204  There are transitions:
205    right to 2 (C)
206    up to 0 (A)
207    up_right to 1 (B)
208Take right from decision 3 (D) to 2 (C)
209At decision 2 (C)
210  There are transitions:
211    left to 3 (D)
212    up to 1 (B)
213Take up from decision 2 (C) to 1 (B)
214At decision 1 (B)
215  There are transitions:
216    down to 2 (C)
217    down_left to 3 (D)
218    left to 0 (A)
219Take left from decision 1 (B) to 0 (A)
220At decision 0 (A)
221  There are transitions:
222    down to 3 (D)
223    right to 1 (B)
224Take down from decision 0 (A) to 3 (D)
225At decision 3 (D)
226  There are transitions:
227    right to 2 (C)
228    up to 0 (A)
229    up_right to 1 (B)
230Waiting for another action...
231End of the exploration.
232"""

Tests the describeProgress function.

def test_unexploredBranches() -> None:
235def test_unexploredBranches() -> None:
236    """
237    Tests the `unexploredBranches` and related count functions.
238    """
239    ex = journal.convertJournal(JOURNAL)
240    assert analysis.unexploredBranches(ex.getSituation(0).graph) == []
241    g1 = ex.getSituation(1).graph
242    assert g1.destinationsFrom(0) == {
243        'right': 1,
244        'left': 2
245    }
246    assert g1.nameFor(1) == '_u.0'
247    assert g1.nameFor(2) == '_u.1'
248    assert analysis.unexploredBranches(ex.getSituation(1).graph) == [
249        (0, 'right'),
250        (0, 'left'),
251    ]
252    assert analysis.unexploredBranches(ex.getSituation(2).graph) == [
253        (0, 'right'),
254        (2, 'up'),
255    ]
256    assert analysis.unexploredBranches(ex.getSituation(3).graph) == [
257        (0, 'right'),
258        (2, 'up'),
259    ]
260    g4 = ex.getSituation(4).graph
261    assert g4.namesListing(set(g4.nodes)) == """\
262  0 (Start_room::Start)
263  1 (Start_room::platforms)
264  2 (Start_room::coin_room)
265  3 (Start_room::above_coin_room)
266  4 (_u.3)
267  5 (_u.4)
268"""
269    assert analysis.unexploredBranches(ex.getSituation(4).graph) == [
270        (1, 'up'),
271        (1, 'right'),
272        (2, 'up'),
273    ]
274    assert analysis.unexploredBranches(ex.getSituation(5).graph) == [
275        (1, 'right'),
276        (2, 'up'),
277    ]
278    allPerStep = analysis.perSituation(analysis.countAllUnexploredBranches)
279    traversablePerStep = analysis.perSituation(
280        analysis.countTraversableUnexploredBranches
281    )
282    assert allPerStep(ex) == [0, 2, 2, 2, 3, 2]
283    assert traversablePerStep(ex) == [0, 2, 1, 1, 2, 1]
284    # TODO

Tests the unexploredBranches and related count functions.

def test_countBranches() -> None:
287def test_countBranches() -> None:
288    """
289    Tests the `countBranches` function.
290    """
291    ex = journal.convertJournal(BABY_JOURNAL)
292    ex2 = journal.convertJournal(BABY_JOURNAL_2)
293
294    # Note: as of v0.6, we can index an exploration to get a Situation,
295    # and most analysis functions want Situations as input
296
297    first = ex[0]
298    second = ex[1]
299    third = ex[2]
300    fourth = ex[3]
301    fifth = ex[4]
302
303    ex2first = ex2[0]
304    ex2second = ex2[1]
305    ex2third = ex2[2]
306
307    meanInStep = analysis.meanOfResults(
308        analysis.perDecision(
309            analysis.analyzeGraph(analysis.countBranches)
310        )
311    )
312    assert first.graph.namesListing(set(first.graph.nodes)) == """\
313  0 (Start)
314"""
315    assert meanInStep(first) == 0
316    assert meanInStep(second) == 2
317    assert meanInStep(third) == 1.5
318    assert meanInStep(fourth) == 2
319    assert meanInStep(fifth) == 2.5
320
321    startID = fifth.graph.resolveDecision("Start")
322    nookID = fifth.graph.resolveDecision("left_nook")
323    assert analysis.countBranches(second.graph, startID) == 2
324    assert analysis.countBranches(third.graph, startID) == 2
325    assert analysis.countBranches(third.graph, nookID) == 1
326    assert analysis.countBranches(fifth.graph, startID) == 3
327    assert analysis.countBranches(fifth.graph, nookID) == 2
328
329    assert meanInStep(ex2first) == 0
330    assert meanInStep(ex2second) == 2
331    assert meanInStep(ex2third) == 1.5

Tests the countBranches function.

def test_countRevisits() -> None:
334def test_countRevisits() -> None:
335    """
336    Tests the `countRevisits` function
337    """
338
339    babyExp = journal.convertJournal(BABY_JOURNAL)
340    graph = babyExp.getSituation().graph
341    startID = graph.resolveDecision("Start")
342    nookID = graph.resolveDecision("left_nook")
343    assert analysis.countRevisits(babyExp, startID) == 1
344    assert analysis.countRevisits(babyExp, nookID) == 0
345    assert analysis.countRevisits(babyExp, 28309823) == 0
346
347    fullExp = journal.convertJournal(JOURNAL)
348    graph = fullExp.getSituation().graph
349    startID = graph.resolveDecision("Start")
350    coinRoomID = graph.resolveDecision("coin_room")
351    platformsID = graph.resolveDecision("platforms")
352    dangerplatID = graph.resolveDecision("dangerplat")
353    assert analysis.countRevisits(fullExp, startID) == 1
354    assert analysis.countRevisits(fullExp, coinRoomID) == 0
355    assert analysis.countRevisits(fullExp, platformsID) == 0
356    assert analysis.countRevisits(fullExp, dangerplatID) == 0
357
358    revExp = journal.convertJournal(REVISITS_JOURNAL)
359    graph = revExp.getSituation().graph
360    aID = graph.resolveDecision('A')
361    bID = graph.resolveDecision('B')
362    cID = graph.resolveDecision('C')
363    dID = graph.resolveDecision('D')
364    assert analysis.countRevisits(revExp, aID) == 2
365    assert analysis.countRevisits(revExp, bID) == 2
366    assert analysis.countRevisits(revExp, cID) == 1
367    assert analysis.countRevisits(revExp, dID) == 2
368
369    countAll = analysis.sumOfResults(
370        analysis.perExplorationDecision(
371            analysis.countRevisits
372        )
373    )
374    assert countAll(babyExp) == 1
375    assert countAll(fullExp) == 1
376    assert countAll(revExp) == 7

Tests the countRevisits function