aboutsummaryrefslogtreecommitdiffziptar.gz
path: root/tests/test_config.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_config.py')
-rw-r--r--tests/test_config.py182
1 files changed, 182 insertions, 0 deletions
diff --git a/tests/test_config.py b/tests/test_config.py
new file mode 100644
index 0000000..5aafbef
--- /dev/null
+++ b/tests/test_config.py
@@ -0,0 +1,182 @@
+import shutil
+import tempfile
+import unittest
+from pathlib import Path
+
+from mapgen import config as C
+
+from mapgen.testing import FIXTURE_TOML
+
+TECT = """
+[[plate]]
+id = "a"
+seed = [0.0, 0.0]
+kind = "continental"
+motion = [90.0, 3.0]
+[[plate]]
+id = "b"
+seed = [0.0, 90.0]
+kind = "oceanic"
+motion = [270.0, 3.0]
+"""
+
+
+class ConfigTest(unittest.TestCase):
+ def setUp(self):
+ self.tmp = Path(tempfile.mkdtemp())
+ (self.tmp / "config").mkdir()
+ shutil.copy(FIXTURE_TOML, self.tmp / "config" / "world.toml")
+ (self.tmp / "config" / "tectonics.toml").write_text(TECT)
+
+ def tearDown(self):
+ shutil.rmtree(self.tmp)
+
+ def test_loads_repo_world(self):
+ cfg, tect = C.load(self.tmp)
+ self.assertEqual(cfg["planet"]["radius_km"], 12742.0)
+ self.assertEqual(len(tect["plate"]), 2)
+
+ def test_out_of_range_is_error(self):
+ p = self.tmp / "config" / "world.toml"
+ p.write_text(p.read_text().replace("tilt_deg = 20.0", "tilt_deg = 120.0"))
+ with self.assertRaisesRegex(C.ConfigError, "tilt_deg"):
+ C.load(self.tmp)
+
+ def test_missing_key_is_error(self):
+ p = self.tmp / "config" / "world.toml"
+ p.write_text(p.read_text().replace("seed = 1296\n", ""))
+ with self.assertRaisesRegex(C.ConfigError, "seed"):
+ C.load(self.tmp)
+
+ def test_params_merge_and_typo_guard(self):
+ cfg = {"erosion": {"k": 0.5}}
+ self.assertEqual(C.params(cfg, "erosion", {"k": 0.1, "m": 0.5}), {"k": 0.5, "m": 0.5})
+ with self.assertRaisesRegex(C.ConfigError, "kk"):
+ C.params({"erosion": {"kk": 1}}, "erosion", {"k": 0.1})
+
+ def test_tectonics_validation(self):
+ (self.tmp / "config" / "tectonics.toml").write_text(TECT.replace('kind = "oceanic"', 'kind = "lava"'))
+ with self.assertRaisesRegex(C.ConfigError, "kind"):
+ C.load(self.tmp)
+ (self.tmp / "config" / "tectonics.toml").write_text(TECT.replace('id = "b"', 'id = "a"'))
+ with self.assertRaisesRegex(C.ConfigError, "duplicate"):
+ C.load(self.tmp)
+
+
+REV = """
+[[plateau]]
+name = "p1"
+center = [-40.0, -18.0]
+area_km2 = 3.0e6
+elongation = 1.9
+azimuth_deg = 30.0
+top_m = [1500.0, 3000.0]
+[[plateau]]
+name = "p2"
+center = [0.0, 176.0]
+area_km2 = 1.0e6
+top_m = [1000.0, 1500.0]
+islands = true
+[[land_patch]]
+name = "fill"
+center = [-10.0, 102.0]
+radius_km = 2850.0
+edge_noise = 0.4
+[[zone]]
+name = "R1"
+field = "o2"
+center = [-5.6, -118.8]
+radius_km = 3200.0
+v = 1.0
+"""
+ERAS = """
+[[event]]
+name = "cut"
+kind = "disintegrate"
+center = [-10.0, 102.0]
+radius_km = 3000.0
+depth_m = 3000.0
+[[event]]
+name = "aura"
+kind = "zone"
+shape = "landmass"
+seed = [-12.7, 121.5]
+reach_km = [500.0, 1000.0]
+edge_km = 5.0
+fields = { gravity_g = 0.35, pressure_bar = 2.0, o2_fraction = 0.35, fire_reactivity = 0.5 }
+[eras]
+order = ["before", "after"]
+default = "after"
+[eras.before]
+label = "Before"
+events = []
+[eras.after]
+label = "After"
+events = ["cut", "aura"]
+"""
+
+
+class RevisionConfigTest(unittest.TestCase):
+ def setUp(self):
+ self.tmp = Path(tempfile.mkdtemp())
+ (self.tmp / "config").mkdir()
+ shutil.copy(FIXTURE_TOML, self.tmp / "config" / "world.toml")
+ self._set()
+
+ def tearDown(self):
+ shutil.rmtree(self.tmp)
+
+ def _set(self, rev=REV, eras=ERAS):
+ (self.tmp / "config" / "tectonics.toml").write_text(TECT + rev)
+ (self.tmp / "config" / "eras.toml").write_text(eras)
+
+ def test_valid_revision_config_loads(self):
+ _, t = C.load(self.tmp)
+ self.assertEqual([p["name"] for p in t["plateau"]], ["p1", "p2"])
+ self.assertEqual([e["name"] for e in C.era_events(t, "after")], ["cut", "aura"])
+ self.assertEqual(C.era_events(t, "before"), [])
+
+ def test_era_events_are_cumulative(self):
+ eras = ERAS.replace('order = ["before", "after"]', 'order = ["before", "mid", "after"]').replace(
+ '[eras.after]\nlabel = "After"\nevents = ["cut", "aura"]',
+ '[eras.mid]\nlabel = "Mid"\nevents = ["aura"]\n[eras.after]\nlabel = "After"\nevents = ["cut"]')
+ self._set(REV, eras)
+ _, t = C.load(self.tmp)
+ self.assertEqual([e["name"] for e in C.era_events(t, "mid")], ["aura"])
+ self.assertEqual([e["name"] for e in C.era_events(t, "after")], ["aura", "cut"])
+ with self.assertRaises(C.ConfigError):
+ C.era_events(t, "never")
+
+ def test_errors_name_the_problem(self):
+ dup = '[[plateau]]\nname = "p1"\ncenter = [60.0, 60.0]\narea_km2 = 1e6\ntop_m = [1000.0, 2000.0]\n'
+ cases = [
+ (REV.replace("top_m = [1500.0, 3000.0]", "top_m = [3000.0, 1500.0]"), ERAS, "top_m"),
+ (REV.replace("center = [0.0, 176.0]", "center = [-41.0, -10.0]"), ERAS, "apart"),
+ (REV + dup, ERAS, "duplicate"),
+ (REV.replace('field = "o2"', 'field = "heat"'), ERAS, "field"),
+ (REV, ERAS.replace("fire_reactivity = 0.5", "sparkle = 1.0"), "sparkle"),
+ (REV, ERAS.replace('default = "after"', 'default = "later"'), "default"),
+ (REV, ERAS.replace('events = ["cut", "aura"]', 'events = ["cut", "nope"]'), "nope"),
+ (REV, ERAS.replace('kind = "disintegrate"', 'kind = "flood"'), "kind"),
+ (REV, ERAS.replace("edge_km = 5.0\n", ""), "edge_km"),
+ ]
+ for rev, eras, needle in cases:
+ with self.subTest(needle=needle):
+ self._set(rev, eras)
+ with self.assertRaises(C.ConfigError) as cm:
+ C.load(self.tmp)
+ self.assertIn(needle, str(cm.exception))
+
+ def test_events_belong_in_eras_toml(self):
+ (self.tmp / "config" / "tectonics.toml").write_text(TECT + REV + ERAS)
+ with self.assertRaises(C.ConfigError) as cm:
+ C.load(self.tmp)
+ self.assertIn("eras.toml", str(cm.exception))
+
+ def test_eras_toml_is_not_part_of_the_base_inputs_key(self):
+ from mapgen import pipeline as P
+ k = P.inputs_key(self.tmp, 1)
+ self._set(REV, ERAS.replace("fire_reactivity = 0.5", "fire_reactivity = 0.6"))
+ self.assertEqual(P.inputs_key(self.tmp, 1), k, "tuning an event must not rebuild the base world")
+ self._set(REV.replace("v = 1.0", "v = 0.9"), ERAS)
+ self.assertNotEqual(P.inputs_key(self.tmp, 1), k)