Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Vida_Data/vevents.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,9 @@ def readZoneSelection(theDict):
if "selection" in theDict:
theSelectionDict=theDict['selection'][0]
#make sure the selection array has all three needed elements
if not ("attribute" and "logic" and "value") in theSelectionDict:
#(each one checked: ("attribute" and "logic" and "value") is just
#"value", so only that one used to be checked)
if not ("attribute" in theSelectionDict and "logic" in theSelectionDict and "value" in theSelectionDict):
print("\n***WARNING: Selection array needs exactly three elements: attribute, logic, and value")
print("\n***Ignoring selection criteria")
zoneSelAttribute = "none"
Expand Down
4 changes: 3 additions & 1 deletion Vida_Data/vgraphics.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,9 @@ def initCFDGText(theGarden, displayType, percentTimeStamp, maxHeightPlant):
worldTypeRule=worldTypeRule+CFDGTopWorldRule
worldTypeRule=worldTypeRule % (worldX+(worldX*0.3), worldY1+(worldY1*0.3), worldX, worldY1, worldX-1, worldY1-1)
worldTypeRule=worldTypeRule+CFDGSideWorldRule
worldTypeRule=worldTypeRule % (worldX, worldY2, worldX-1, worldY2-1)
###the side view's rule takes six numbers, as in the other side views
###(it used to be given four, which crashed)
worldTypeRule=worldTypeRule % (worldX+(worldX*0.3), worldY2+(worldY1*0.3), worldX, worldY2, worldX-1, worldY2-1)

if percentTimeStamp>0.0:
timeStampCode= CFDGTimeStamp
Expand Down
10 changes: 7 additions & 3 deletions Vida_Data/vplacement.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,19 @@ def checkSeedPlacementList(seedPlacementList):
aLine = [correctType(x) for x in aLine]
seedPlacementList[i]=aLine
i=i+1
i=0
###keep the lines that are a species name, x, y and a whole number of
###cycles. (This used to delete the bad lines from the list while going
###through it, which skipped the line after each one it deleted.)
goodLines=[]
printErrorMessage=0
for aLine in seedPlacementList:
if type(aLine[3])==float:
aLine[3]=int(aLine[3])
if (type(aLine[0])!=str) or (type(aLine[1])!=float) or (type(aLine[2])!=float) or (type(aLine[3])!=int):
printErrorMessage=1
del seedPlacementList[i]
i=i+1
else:
goodLines.append(aLine)
seedPlacementList=goodLines
if printErrorMessage:
print("***Improper seeding file format...")
print(" Questionable lines will be ignored.")
Expand Down
9 changes: 5 additions & 4 deletions tests/characterization/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,10 +180,11 @@ been fixed since, and each now has a scenario that uses the feature.
a `TypeError` on Python 3.12+, and on 3.11 it was already a `ValueError`
for worlds of odd size.

Still open: the combined bottom + top + side view (`-g bts`) crashes with
`TypeError: not enough arguments for format string`, because
`initCFDGText` in `vgraphics.py` fills the side-view template, which needs
six numbers, with only four. The `graphics_outputs` scenario pins this.
5. Fixed: the combined bottom + top + side view (`-g bts`) crashed with
`TypeError: not enough arguments for format string`, because
`initCFDGText` in `vgraphics.py` filled the side-view template, which
needs six numbers, with only four. The `graphics_outputs` scenario now
makes that view too.

Also noticed, but not crashes: in `disperseSeed`, the terrain binary search
calls `elevationFromPixel(thePixelValue)` without `theGarden.maxElevation`,
Expand Down
Binary file modified tests/characterization/golden/graphics_outputs.json.xz
Binary file not shown.
7 changes: 4 additions & 3 deletions tests/characterization/scenarios/graphics_outputs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ description: >
Graphics output: the ContextFree (.cfdg) files and the 3D .dxf files, kept
on disk (-c) so their names and contents are pinned. Stage 1 makes the
combined bottom-up + side view and 3D; stage 2 makes every other view
except bottom + top + side (-g bts), which currently crashes (stage 3):
initCFDGText fills the side view template, which needs six numbers, with
only four. The external cfdg and ffmpeg programs are not run.
except bottom + top + side (-g bts), which is stage 3. (That view used to
crash: initCFDGText filled the side view template, which needs six
numbers, with only four.) The external cfdg and ffmpeg programs are not
run.
species: [species/generic]
stages:
- rngstart: 808
Expand Down
9 changes: 9 additions & 0 deletions tests/unit/test_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ def test_a_zone_without_a_selection_selects_everything():
assert vevents.readZoneSelection({})[0] == "none"


def test_a_selection_missing_a_part_is_ignored():
# Each of attribute, logic and value is needed. Only value used to be
# checked, so a selection without attribute or logic crashed.
for missing in ["attribute", "logic", "value"]:
selection = {"attribute": "heightStem", "logic": ">", "value": 2.0}
del selection[missing]
assert vevents.readZoneSelection({"selection": [selection]})[0] == "none"


def test_a_selection_with_bad_logic_is_ignored():
zone = {"selection": [{"attribute": "heightStem", "logic": "!=", "value": 2.0}]}
assert vevents.readZoneSelection(zone)[0] == "none"
Expand Down
11 changes: 6 additions & 5 deletions tests/unit/test_placement.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ def test_whole_number_coordinates_are_rejected():
assert lines == [["random", 1.0, 2.0, 0]]


def test_after_a_bad_line_the_next_line_is_not_checked():
# The check deletes bad lines from the list while looping over it, so the
# line after a deleted one is skipped: here the second bad line is kept.
lines = vplacement.checkSeedPlacementList(["a.yml, 1, 2.0, 0", "b.yml, 3, 4.0, 0", "c.yml, 5.0, 6.0, 0"])
assert lines == [["b.yml", 3, 4.0, 0], ["c.yml", 5.0, 6.0, 0]]
def test_every_bad_line_is_left_out_and_every_good_line_kept():
# This used to delete bad lines from the list while looping over it, which
# skipped the line after each deleted one: the second bad line was kept.
lines = vplacement.checkSeedPlacementList(
["a.yml, 1, 2.0, 0", "b.yml, 3, 4.0, 0", "c.yml, 5.0, 6.0, 0", "d.yml, 7, 8.0, 0", "e.yml, 9.0, 1.0, 2"])
assert lines == [["c.yml", 5.0, 6.0, 0], ["e.yml", 9.0, 1.0, 2]]