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, core
  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
 37  a 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           # 4 decisions ABCD
 64r up A down              # revisit #1 for A
 65t right                  # revisit #1 for B
 66r down_left D up_right   # revisit #1 for D
 67t right                  # revisit #1 for C
 68t up                     # revisit #2 for A
 69t left                   # revisit #2 for B
 70t down                   # revisit #2 for C
 71
 72# now we have: 2 revisits each for A, B, and C, and 1 revisit for D
 73"""
 74
 75
 76def test_CreateExploration() -> None:
 77    """
 78    Simple test to make sure we can create an exploration object for
 79    other tests in this file.
 80    """
 81    ex = journal.convertJournal(JOURNAL)
 82    assert len(ex) == 6
 83    assert ex.getActiveDecisions(0) == set()
 84    assert ex.getActiveDecisions(1) == {0}
 85
 86    assert bool(ex.getSituation(1).graph) is True
 87
 88
 89def test_countActionsAtDecision() -> None:
 90    """
 91    Test to make sure the number of actions in the whole graph
 92    at each step is accurate.
 93    """
 94    ex = journal.convertJournal(BABY_JOURNAL)
 95    assert [
 96        analysis.totalActions(ex, i)
 97        for i in range(len(ex))
 98    ] == [0, 0, 1, 1, 1]
 99
100    now = ex.getSituation()
101    graph = now.graph
102    startID = graph.resolveDecision("Start")
103    nookID = graph.resolveDecision("left_nook")
104    assert analysis.actionCount(ex, len(ex) - 1, startID) == 0
105    assert analysis.actionCount(ex, len(ex) - 1, nookID) == 1
106    # TODO: Further testing?
107
108
109def test_describeProgress() -> None:
110    """
111    Tests the `describeProgress` function.
112    """
113    e1 = journal.convertJournal(BABY_JOURNAL)
114    e2 = journal.convertJournal(BABY_JOURNAL_2)
115    e3 = journal.convertJournal(REVISITS_JOURNAL)
116
117    description = analysis.describeProgress(e1)
118    assert description == """\
119Start of the exploration
120Start exploring domain main at 0 (Start)
121  Gained capability 'attack'
122  Gained capability 'jump'
123At decision 0 (Start)
124  In region Wilds
125  There are transitions:
126    left to unconfirmed
127    up to unconfirmed; requires _flight
128  1 note(s) at this step
129Explore left from decision 0 (Start) to 2 (now Wilds::left_nook)
130At decision 2 (left_nook)
131  There are transitions:
132    right to 0 (Start)
133  There are actions:
134    geo_rock
135Do action geo_rock
136  Gained 15 geo(s)
137Take right from decision 2 (left_nook) to 0 (Start)
138At decision 0 (Start)
139  There are transitions:
140    left to 2 (left_nook)
141    right to unconfirmed; requires attack
142    up to unconfirmed; requires _flight
143Waiting for another action...
144End of the exploration.
145"""
146
147    description2 = analysis.describeProgress(e2)
148    assert description2 == """\
149Start of the exploration
150Start exploring domain main at 0 (Start)
151  Gained capability 'attack'
152  Gained capability 'jump'
153At decision 0 (Start)
154  In region Wilds
155  There are transitions:
156    left to unconfirmed
157    up to unconfirmed; requires _flight
158  1 note(s) at this step
159Explore left from decision 0 (Start) to 2 (now Wilds::left_nook)
160At decision 2 (left_nook)
161  There are transitions:
162    right to 0 (Start)
163Waiting for another action...
164End of the exploration.
165"""
166
167    description3 = analysis.describeProgress(e3)
168    assert description3 == """\
169Start of the exploration
170Start exploring domain main at 0 (A)
171At decision 0 (A)
172  There are transitions:
173    right to unconfirmed
174Explore right from decision 0 (A) to 1 (now B)
175At decision 1 (B)
176  There are transitions:
177    down to unconfirmed
178    left to 0 (A)
179Explore down from decision 1 (B) to 2 (now C)
180At decision 2 (C)
181  There are transitions:
182    left to unconfirmed
183    up to 1 (B)
184Explore left from decision 2 (C) to 3 (now D)
185At decision 3 (D)
186  There are transitions:
187    right to 2 (C)
188    up to 0 (A)
189Take up from decision 3 (D) to 0 (A)
190At decision 0 (A)
191  There are transitions:
192    down to 3 (D)
193    right to 1 (B)
194Take right from decision 0 (A) to 1 (B)
195At decision 1 (B)
196  There are transitions:
197    down to 2 (C)
198    down_left to 3 (D)
199    left to 0 (A)
200Take down_left from decision 1 (B) to 3 (D)
201At decision 3 (D)
202  There are transitions:
203    right to 2 (C)
204    up to 0 (A)
205    up_right to 1 (B)
206Take right from decision 3 (D) to 2 (C)
207At decision 2 (C)
208  There are transitions:
209    left to 3 (D)
210    up to 1 (B)
211Take up from decision 2 (C) to 1 (B)
212At decision 1 (B)
213  There are transitions:
214    down to 2 (C)
215    down_left to 3 (D)
216    left to 0 (A)
217Take left from decision 1 (B) to 0 (A)
218At decision 0 (A)
219  There are transitions:
220    down to 3 (D)
221    right to 1 (B)
222Take down from decision 0 (A) to 3 (D)
223At decision 3 (D)
224  There are transitions:
225    right to 2 (C)
226    up to 0 (A)
227    up_right to 1 (B)
228Waiting for another action...
229End of the exploration.
230"""
231
232
233def test_unexploredBranches() -> None:
234    """
235    Tests the `unexploredBranches` and related count functions.
236    """
237    ex = journal.convertJournal(JOURNAL)
238    assert analysis.unexploredBranches(ex.getSituation(0).graph) == []
239    g1 = ex.getSituation(1).graph
240    assert g1.destinationsFrom(0) == {
241        'right': 1,
242        'left': 2
243    }
244    assert g1.nameFor(1) == '_u.0'
245    assert g1.nameFor(2) == '_u.1'
246    assert analysis.unexploredBranches(ex.getSituation(1).graph) == [
247        (0, 'right'),
248        (0, 'left'),
249    ]
250    assert analysis.unexploredBranches(ex.getSituation(2).graph) == [
251        (0, 'right'),
252        (2, 'up'),
253    ]
254    assert analysis.unexploredBranches(ex.getSituation(3).graph) == [
255        (0, 'right'),
256        (2, 'up'),
257    ]
258    g4 = ex.getSituation(4).graph
259    assert g4.namesListing(set(g4.nodes)) == """\
260  0 (Start_room::Start)
261  1 (Start_room::platforms)
262  2 (Start_room::coin_room)
263  3 (Start_room::above_coin_room)
264  4 (_u.3)
265  5 (_u.4)
266"""
267    assert analysis.unexploredBranches(ex.getSituation(4).graph) == [
268        (1, 'up'),
269        (1, 'right'),
270        (2, 'up'),
271    ]
272    assert analysis.unexploredBranches(ex.getSituation(5).graph) == [
273        (1, 'right'),
274        (2, 'up'),
275    ]
276    allPerStep = [
277        analysis.unexploredBranchCount(ex, step)
278        for step in range(len(ex))
279    ]
280    traversablePerStep = [
281        analysis.traversableUnexploredCount(ex, step)
282        for step in range(len(ex))
283    ]
284    assert allPerStep == [0, 2, 2, 2, 3, 2]
285    assert traversablePerStep == [0, 2, 1, 1, 2, 1]
286    # TODO
287
288
289def test_countBranches() -> None:
290    """
291    Tests the `countBranches` function.
292    """
293    ex = journal.convertJournal(BABY_JOURNAL)
294    ex2 = journal.convertJournal(BABY_JOURNAL_2)
295
296    # Note: as of v0.6, we can index an exploration to get a Situation,
297    # and most analysis functions want Situations as input
298
299    first = ex[0]
300    second = ex[1]
301    third = ex[2]
302    fourth = ex[3]
303    fifth = ex[4]
304
305    ex2first = ex2[0]
306    ex2second = ex2[1]
307    ex2third = ex2[2]
308
309    assert first.graph.namesListing(set(first.graph.nodes)) == """\
310  0 (Start)
311"""
312    assert analysis.meanBranches(ex, 0) == 0
313    assert analysis.meanBranches(ex, 1) == 2
314    assert analysis.meanBranches(ex, 2) == 1.5
315    assert analysis.meanBranches(ex, 3) == 2
316    assert analysis.meanBranches(ex, 4) == 2.5
317
318    startID = fifth.graph.resolveDecision("Start")
319    nookID = fifth.graph.resolveDecision("left_nook")
320    assert analysis.branches(ex, 1, startID) == 2
321    assert analysis.branches(ex, 2, startID) == 2
322    assert analysis.branches(ex, 2, nookID) == 1
323    assert analysis.branches(ex, 4, startID) == 3
324    assert analysis.branches(ex, 4, nookID) == 2
325
326    assert analysis.meanBranches(ex2, 0) == 0
327    assert analysis.meanBranches(ex2, 1) == 2
328    assert analysis.meanBranches(ex2, 2) == 1.5
329
330
331def test_revisits() -> None:
332    """
333    Tests the `arrivals`, `revisits`, and related total/mean/median
334    functions.
335    """
336
337    babyExp = journal.convertJournal(BABY_JOURNAL)
338    graph = babyExp.getSituation().graph
339    startID = graph.resolveDecision("Start")
340    nookID = graph.resolveDecision("left_nook")
341    assert analysis.stepsVisited(babyExp) == {
342        startID: [1, 4],
343        nookID: [2, 3]
344    }
345    assert analysis.arrivals(babyExp, startID) == 2
346    assert analysis.revisits(babyExp, startID) == 1
347    assert analysis.arrivals(babyExp, nookID) == 1
348    assert analysis.revisits(babyExp, nookID) == 0
349    assert analysis.arrivals(babyExp, 28309823) == 0
350    assert analysis.revisits(babyExp, 28309823) == 0
351
352    fullExp = journal.convertJournal(JOURNAL)
353    graph = fullExp.getSituation().graph
354    startID = graph.resolveDecision("Start")
355    coinRoomID = graph.resolveDecision("coin_room")
356    platformsID = graph.resolveDecision("platforms")
357    dangerplatID = graph.resolveDecision("dangerplat")
358    assert analysis.revisits(fullExp, startID) == 1
359    assert analysis.revisits(fullExp, coinRoomID) == 0
360    assert analysis.revisits(fullExp, platformsID) == 0
361    assert analysis.revisits(fullExp, dangerplatID) == 0
362
363    revExp = journal.convertJournal(REVISITS_JOURNAL)
364    graph = revExp.getSituation().graph
365    aID = graph.resolveDecision('A')
366    bID = graph.resolveDecision('B')
367    cID = graph.resolveDecision('C')
368    dID = graph.resolveDecision('D')
369    assert analysis.revisits(revExp, aID) == 2
370    assert analysis.revisits(revExp, bID) == 2
371    assert analysis.revisits(revExp, cID) == 1
372    assert analysis.revisits(revExp, dID) == 2
373
374    assert analysis.totalRevisits(babyExp) == 1
375    assert analysis.meanRevisits(babyExp) == 1/5
376    assert analysis.medianRevisits(babyExp) == 0
377    assert analysis.totalRevisits(fullExp) == 1
378    assert analysis.meanRevisits(fullExp) == 1/6
379    assert analysis.medianRevisits(fullExp) == 0
380    assert analysis.totalRevisits(revExp) == 7
381    assert analysis.meanRevisits(revExp) == 7/4
382    assert analysis.medianRevisits(revExp) == 2.0
383
384    blankExp = core.DiscreteExploration()
385    assert analysis.totalRevisits(blankExp) == 0
386    assert analysis.meanRevisits(blankExp) is None
387    assert analysis.medianRevisits(blankExp) is None
388
389    soloExp = core.DiscreteExploration()
390    soloExp.start("start")
391    assert analysis.totalRevisits(soloExp) == 0
392    assert analysis.meanRevisits(soloExp) == 0
393    assert analysis.medianRevisits(soloExp) == 0
394
395    doubleExp = core.DiscreteExploration()
396    doubleExp.start("start")
397    doubleExp.observe("start", "up")
398    doubleExp.explore("up", "above", "down")
399    assert analysis.totalRevisits(doubleExp) == 0
400    assert analysis.meanRevisits(doubleExp) == 0
401    assert analysis.medianRevisits(doubleExp) == 0
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\n a 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 # 4 decisions ABCD\nr up A down # revisit #1 for A\nt right # revisit #1 for B\nr down_left D up_right # revisit #1 for D\nt right # revisit #1 for C\nt up # revisit #2 for A\nt left # revisit #2 for B\nt down # revisit #2 for C\n\n# now we have: 2 revisits each for A, B, and C, and 1 revisit for D\n'
def test_CreateExploration() -> None:
77def test_CreateExploration() -> None:
78    """
79    Simple test to make sure we can create an exploration object for
80    other tests in this file.
81    """
82    ex = journal.convertJournal(JOURNAL)
83    assert len(ex) == 6
84    assert ex.getActiveDecisions(0) == set()
85    assert ex.getActiveDecisions(1) == {0}
86
87    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:
 90def test_countActionsAtDecision() -> None:
 91    """
 92    Test to make sure the number of actions in the whole graph
 93    at each step is accurate.
 94    """
 95    ex = journal.convertJournal(BABY_JOURNAL)
 96    assert [
 97        analysis.totalActions(ex, i)
 98        for i in range(len(ex))
 99    ] == [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.actionCount(ex, len(ex) - 1, startID) == 0
106    assert analysis.actionCount(ex, len(ex) - 1, nookID) == 1
107    # TODO: Further testing?

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

def test_describeProgress() -> None:
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"""

Tests the describeProgress function.

def test_unexploredBranches() -> None:
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 = [
278        analysis.unexploredBranchCount(ex, step)
279        for step in range(len(ex))
280    ]
281    traversablePerStep = [
282        analysis.traversableUnexploredCount(ex, step)
283        for step in range(len(ex))
284    ]
285    assert allPerStep == [0, 2, 2, 2, 3, 2]
286    assert traversablePerStep == [0, 2, 1, 1, 2, 1]
287    # TODO

Tests the unexploredBranches and related count functions.

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

Tests the countBranches function.

def test_revisits() -> None:
332def test_revisits() -> None:
333    """
334    Tests the `arrivals`, `revisits`, and related total/mean/median
335    functions.
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.stepsVisited(babyExp) == {
343        startID: [1, 4],
344        nookID: [2, 3]
345    }
346    assert analysis.arrivals(babyExp, startID) == 2
347    assert analysis.revisits(babyExp, startID) == 1
348    assert analysis.arrivals(babyExp, nookID) == 1
349    assert analysis.revisits(babyExp, nookID) == 0
350    assert analysis.arrivals(babyExp, 28309823) == 0
351    assert analysis.revisits(babyExp, 28309823) == 0
352
353    fullExp = journal.convertJournal(JOURNAL)
354    graph = fullExp.getSituation().graph
355    startID = graph.resolveDecision("Start")
356    coinRoomID = graph.resolveDecision("coin_room")
357    platformsID = graph.resolveDecision("platforms")
358    dangerplatID = graph.resolveDecision("dangerplat")
359    assert analysis.revisits(fullExp, startID) == 1
360    assert analysis.revisits(fullExp, coinRoomID) == 0
361    assert analysis.revisits(fullExp, platformsID) == 0
362    assert analysis.revisits(fullExp, dangerplatID) == 0
363
364    revExp = journal.convertJournal(REVISITS_JOURNAL)
365    graph = revExp.getSituation().graph
366    aID = graph.resolveDecision('A')
367    bID = graph.resolveDecision('B')
368    cID = graph.resolveDecision('C')
369    dID = graph.resolveDecision('D')
370    assert analysis.revisits(revExp, aID) == 2
371    assert analysis.revisits(revExp, bID) == 2
372    assert analysis.revisits(revExp, cID) == 1
373    assert analysis.revisits(revExp, dID) == 2
374
375    assert analysis.totalRevisits(babyExp) == 1
376    assert analysis.meanRevisits(babyExp) == 1/5
377    assert analysis.medianRevisits(babyExp) == 0
378    assert analysis.totalRevisits(fullExp) == 1
379    assert analysis.meanRevisits(fullExp) == 1/6
380    assert analysis.medianRevisits(fullExp) == 0
381    assert analysis.totalRevisits(revExp) == 7
382    assert analysis.meanRevisits(revExp) == 7/4
383    assert analysis.medianRevisits(revExp) == 2.0
384
385    blankExp = core.DiscreteExploration()
386    assert analysis.totalRevisits(blankExp) == 0
387    assert analysis.meanRevisits(blankExp) is None
388    assert analysis.medianRevisits(blankExp) is None
389
390    soloExp = core.DiscreteExploration()
391    soloExp.start("start")
392    assert analysis.totalRevisits(soloExp) == 0
393    assert analysis.meanRevisits(soloExp) == 0
394    assert analysis.medianRevisits(soloExp) == 0
395
396    doubleExp = core.DiscreteExploration()
397    doubleExp.start("start")
398    doubleExp.observe("start", "up")
399    doubleExp.explore("up", "above", "down")
400    assert analysis.totalRevisits(doubleExp) == 0
401    assert analysis.meanRevisits(doubleExp) == 0
402    assert analysis.medianRevisits(doubleExp) == 0

Tests the arrivals, revisits, and related total/mean/median functions.