Add spell data helper and organize screenshots
This commit is contained in:
+4
@@ -0,0 +1,4 @@
|
||||
1^6^Launches a bolt of fire at your target.^0^
|
||||
2^6^Lets your target breathe underwater for a short time.^0^
|
||||
3^6^Launches a ball of fire at your target.^0^
|
||||
1^5^Fire^0^
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
1^Fire Bolt^0^alpha
|
||||
2^Water Breathing^0^beta
|
||||
3^Fireball^0^gamma
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
#SPELLINDEX^CASTERMETXT^CASTEROTHERTXT^CASTEDMETXT^CASTEDOTHERTXT^SPELLGONE^
|
||||
1^You cast Fire Bolt.^%1 casts Fire Bolt.^Fire burns you.^Fire burns %1.^The fire fades.^
|
||||
2^You breathe water.^%1 breathes water.^You can breathe water.^%1 can breathe water.^The water magic fades.^
|
||||
3^^^^^^
|
||||
@@ -0,0 +1,108 @@
|
||||
"""End-to-end tests for the dependency-free EQL spell CLI."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
CLI = ROOT / "scripts" / "eql-spells"
|
||||
FIXTURE = ROOT / "tests" / "fixtures" / "eql-spells"
|
||||
|
||||
|
||||
class EqlSpellsCliTests(unittest.TestCase):
|
||||
def setUp(self) -> None:
|
||||
self.temporary = tempfile.TemporaryDirectory()
|
||||
self.work = Path(self.temporary.name)
|
||||
self.game = self.work / "game"
|
||||
shutil.copytree(FIXTURE, self.game)
|
||||
self.db = self.work / "cache" / "spells.sqlite"
|
||||
|
||||
def tearDown(self) -> None:
|
||||
self.temporary.cleanup()
|
||||
|
||||
def run_cli(self, *arguments: str) -> subprocess.CompletedProcess[str]:
|
||||
return subprocess.run(
|
||||
[sys.executable, str(CLI), "--game-path", str(self.game), "--db", str(self.db), *arguments],
|
||||
cwd=ROOT,
|
||||
text=True,
|
||||
capture_output=True,
|
||||
check=False,
|
||||
)
|
||||
|
||||
def json_stdout(self, *arguments: str) -> dict:
|
||||
result = self.run_cli(*arguments)
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
return json.loads(result.stdout)
|
||||
|
||||
def test_build_and_exact_lookup_by_id_and_name(self) -> None:
|
||||
built = self.json_stdout("build")
|
||||
self.assertEqual(built["built"], {"descriptions": 3, "messages": 3, "spells": 3})
|
||||
self.assertTrue(self.db.is_file())
|
||||
|
||||
by_id = self.json_stdout("get", "1")
|
||||
self.assertEqual(by_id["spell"]["name"], "Fire Bolt")
|
||||
self.assertEqual(by_id["spell"]["description"], "Launches a bolt of fire at your target.")
|
||||
self.assertEqual(by_id["spell"]["messages"]["caster_me"], "You cast Fire Bolt.")
|
||||
self.assertIn("fingerprint", by_id["source"])
|
||||
|
||||
by_name = self.json_stdout("get", "water breathing")
|
||||
self.assertEqual(by_name["spell"]["id"], 2)
|
||||
|
||||
def test_find_search_and_raw_output(self) -> None:
|
||||
found = self.json_stdout("find", "fire")
|
||||
self.assertEqual([spell["name"] for spell in found["results"]], ["Fire Bolt", "Fireball"])
|
||||
|
||||
searched = self.json_stdout("search", "breathing underwater")
|
||||
self.assertEqual([spell["id"] for spell in searched["results"]], [2])
|
||||
|
||||
raw = self.json_stdout("get", "1", "--raw")
|
||||
self.assertEqual(raw["spell"]["raw"]["line"], "1^Fire Bolt^0^alpha")
|
||||
self.assertEqual(raw["spell"]["raw"]["fields"], ["1", "Fire Bolt", "0", "alpha"])
|
||||
|
||||
def test_query_automatically_rebuilds_after_source_change(self) -> None:
|
||||
self.json_stdout("build")
|
||||
descriptions = self.game / "dbstr_us.txt"
|
||||
with descriptions.open("a", encoding="utf-8") as handle:
|
||||
handle.write("2^6^Lets your target breathe underwater indefinitely.^0^\n")
|
||||
|
||||
result = self.run_cli("search", "indefinitely")
|
||||
self.assertEqual(result.returncode, 1)
|
||||
self.assertIn("Duplicate spell description", json.loads(result.stderr)["error"]["message"])
|
||||
|
||||
# Replace the existing description rather than adding a duplicate.
|
||||
descriptions.write_text(
|
||||
"1^6^Launches a bolt of fire at your target.^0^\n"
|
||||
"2^6^Lets your target breathe underwater indefinitely.^0^\n"
|
||||
"3^6^Launches a ball of fire at your target.^0^\n"
|
||||
"1^5^Fire^0^\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
rebuilt = self.json_stdout("search", "indefinitely")
|
||||
self.assertTrue(rebuilt["index_rebuilt"])
|
||||
self.assertEqual(rebuilt["results"][0]["id"], 2)
|
||||
|
||||
def test_malformed_data_and_invalid_query_return_structured_errors(self) -> None:
|
||||
(self.game / "spells_us.txt").write_text("bad row\n", encoding="utf-8")
|
||||
malformed = self.run_cli("build")
|
||||
self.assertEqual(malformed.returncode, 1)
|
||||
self.assertEqual(json.loads(malformed.stderr)["error"]["code"], "data")
|
||||
|
||||
shutil.copy2(FIXTURE / "spells_us.txt", self.game / "spells_us.txt")
|
||||
invalid_limit = self.run_cli("find", "fire", "--limit", "101")
|
||||
self.assertEqual(invalid_limit.returncode, 2)
|
||||
self.assertEqual(json.loads(invalid_limit.stderr)["error"]["code"], "usage")
|
||||
|
||||
missing = self.run_cli("get", "999")
|
||||
self.assertEqual(missing.returncode, 1)
|
||||
self.assertEqual(json.loads(missing.stderr)["error"]["code"], "data")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user