Ran flake8 and black against tests.

This commit is contained in:
Mark Wolfman
2021-04-16 11:28:05 -05:00
parent 0c3dbc73fc
commit e5ec51b0e7
11 changed files with 278 additions and 207 deletions
+80 -57
View File
@@ -1,27 +1,32 @@
#!/usr/bin/env python
from unittest import TestCase
from pathlib import Path
import warnings
from dungeonsheets import race, monsters, exceptions, spells, infusions
from dungeonsheets.character import Character, Wizard, Druid, read_character_file, _resolve_mechanic
from dungeonsheets.character import (
Character,
Wizard,
Druid,
_resolve_mechanic,
)
from dungeonsheets.weapons import Weapon, Shortsword
from dungeonsheets.armor import Armor, LeatherArmor, Shield
class TestCharacter(TestCase):
"""Tests for the generic character base class."""
def test_constructor(self):
char = Character(name="Inara")
self.assertIsInstance(char, Character)
def test_hit_dice(self):
# Test the getter
char = Character()
char.level = 2
char.hit_dice_faces = 10
self.assertEqual(char.hit_dice, '2d10')
self.assertEqual(char.hit_dice, "2d10")
def test_max_hp(self):
char = Wizard(level=3, constitution=12)
@@ -29,37 +34,41 @@ class TestCharacter(TestCase):
def test_set_attrs(self):
char = Character()
char.set_attrs(name='Inara')
self.assertEqual(char.name, 'Inara')
char.set_attrs(name="Inara")
self.assertEqual(char.name, "Inara")
# Check that the weapons get loaded as objects not string
char.set_attrs(weapons=['shortsword'])
char.set_attrs(weapons=["shortsword"])
self.assertEqual(len(char.weapons), 1)
self.assertTrue(isinstance(char.weapons[0], Shortsword))
# Check that armor and shield gets set_attrs
char.set_attrs(armor='leather armor', shield='shield')
char.set_attrs(armor="leather armor", shield="shield")
self.assertFalse(isinstance(char.armor, str))
self.assertFalse(isinstance(char.shield, str))
# Check that race gets set to an object
char.set_attrs(race='high elf')
char.set_attrs(race="high elf")
self.assertIsInstance(char.race, race.HighElf)
# Check inspiration works
char.set_attrs(inspiration=True)
self.assertTrue(char.inspiration)
char.set_attrs(inspiration=False)
self.assertFalse(char.inspiration)
def test_homebrew_spells(self):
char = Character()
class MySpell(spells.Spell):
name="my spell!"
name = "my spell!"
char.set_attrs(spells=(MySpell,))
self.assertIsInstance(char.spells[0], spells.Spell)
self.assertEqual(char.spells[0].name, "my spell!")
def test_homebrew_infusions(self):
char = Character(classes="artificer")
class MyInfusion(infusions.Infusion):
name="my infusion!"
name = "my infusion!"
# Pass an already created infusion class
char.set_attrs(infusions=(MyInfusion,))
self.assertIsInstance(char.infusions[0], infusions.Infusion)
@@ -69,54 +78,58 @@ class TestCharacter(TestCase):
char.set_attrs(infusions=("spam_infusion",))
self.assertIsInstance(char.infusions[0], infusions.Infusion)
self.assertEqual(char.infusions[0].name, "Spam Infusion")
def test_resolve_mechanic(self):
# Test a well defined mechanic
NewSpell = _resolve_mechanic("mage_hand", spells, None)
self.assertTrue(issubclass(NewSpell, spells.Spell))
# Test an unknown mechanic
def new_spell(**params):
return spells.Spell
NewSpell = _resolve_mechanic("hocus_pocus", spells, spells.Spell)
self.assertTrue(issubclass(NewSpell, spells.Spell))
# Test direct resolution of a proper subclass
class MySpell(spells.Spell):
pass
NewSpell = _resolve_mechanic(MySpell, spells, spells.Spell)
def test_wield_weapon(self):
char = Character()
char.strength = 14
char.weapon_proficiencies = [Shortsword]
# Add a weapon
char.wield_weapon('shortsword')
char.wield_weapon("shortsword")
self.assertEqual(len(char.weapons), 1)
sword = char.weapons[0]
self.assertTrue(isinstance(sword, Weapon))
self.assertTrue(isinstance(sword, Shortsword))
self.assertEqual(sword.attack_modifier, 4) # str + prof
self.assertEqual(sword.damage, '1d6+2') # str
self.assertEqual(sword.attack_modifier, 4) # str + prof
self.assertEqual(sword.damage, "1d6+2") # str
# Check if dexterity is used if it's higher (Finesse weapon)
char.weapons = []
char.dexterity = 16
char.wield_weapon('shortsword')
char.wield_weapon("shortsword")
sword = char.weapons[0]
self.assertEqual(sword.attack_modifier, 5) # dex + prof
self.assertEqual(sword.attack_modifier, 5) # dex + prof
# Check if race weapon proficiencies are considered
char.weapons = []
char.weapon_proficiencies = []
char.race = race.HighElf()
char.wield_weapon('shortsword')
char.wield_weapon("shortsword")
sword = char.weapons[0]
self.assertEqual(sword.attack_modifier, 5)
def test_str(self):
char = Wizard(name="Inara")
self.assertEqual(str(char), 'Inara')
self.assertEqual(repr(char), '<Wizard: Inara>')
self.assertEqual(str(char), "Inara")
self.assertEqual(repr(char), "<Wizard: Inara>")
def test_is_proficient(self):
char = Character(classes=['Wizard'])
char = Character(classes=["Wizard"])
char.weapon_proficiencies
sword = Shortsword()
# Check for not-proficient weapon
@@ -128,24 +141,32 @@ class TestCharacter(TestCase):
char.weapon_proficiencies = tuple()
char.race = race.HighElf()
self.assertTrue(char.is_proficient(sword))
def test_proficiencies_text(self):
char = Character()
char._proficiencies_text = ('hello', 'world')
self.assertIn('hello', char.proficiencies_text.lower())
self.assertIn('world', char.proficiencies_text.lower())
char._proficiencies_text = ("hello", "world")
self.assertIn("hello", char.proficiencies_text.lower())
self.assertIn("world", char.proficiencies_text.lower())
# Check for extra proficiencies
char._proficiencies_text += ("it's", "me")
self.assertIn("it's", char.proficiencies_text.lower())
self.assertIn('me', char.proficiencies_text.lower())
self.assertIn("me", char.proficiencies_text.lower())
# Check that race proficienceis are included
elf = race.HighElf()
char.race = elf
expected = ("hello", "world", "longswords", "shortswords", "shortbows",
"longbows", "it's", "me")
expected = (
"hello",
"world",
"longswords",
"shortswords",
"shortbows",
"longbows",
"it's",
"me",
)
for e in expected:
self.assertIn(e, char.proficiencies_text.lower())
def test_proficiency_bonus(self):
char = Character()
char.level = 1
@@ -168,7 +189,7 @@ class TestCharacter(TestCase):
self.assertEqual(char.proficiency_bonus, 6)
char.level = 20
self.assertEqual(char.proficiency_bonus, 6)
def test_spell_slots(self):
char = Wizard()
# Wizard level 1
@@ -181,10 +202,10 @@ class TestCharacter(TestCase):
self.assertEqual(char.spell_slots(spell_level=0), 3)
self.assertEqual(char.spell_slots(spell_level=1), 3)
self.assertEqual(char.spell_slots(spell_level=2), 0)
def test_equip_armor(self):
char = Character(dexterity=16)
char.wear_armor('leather armor')
char.wear_armor("leather armor")
self.assertTrue(isinstance(char.armor, Armor))
# Now make sure the armor class is correct
self.assertEqual(char.armor_class, 14)
@@ -194,25 +215,25 @@ class TestCharacter(TestCase):
# Test equipped armor with max dexterity mod_str
char.armor.dexterity_mod_max = 1
self.assertEqual(char.armor_class, 12)
def test_wield_shield(self):
char = Character(dexterity=16)
char.wield_shield('shield')
char.wield_shield("shield")
self.assertTrue(isinstance(char.shield, Shield), msg=char.shield)
# Now make sure the armor class is correct
self.assertEqual(char.armor_class, 15)
# Try passing an Armor object directly
char.wield_shield(Shield)
self.assertEqual(char.armor_class, 15)
def test_speed(self):
# Check that the speed pulls from the character's race
char = Character(race='lightfoot halfling')
self.assertEqual(char.speed, '25')
char = Character(race="lightfoot halfling")
self.assertEqual(char.speed, "25")
# Check that a character with no race defaults to 30 feet
char = Character()
char.race = None
self.assertEqual(char.speed, '30')
self.assertEqual(char.speed, "30")
class DruidTestCase(TestCase):
@@ -221,44 +242,46 @@ class DruidTestCase(TestCase):
be ignored."""
char = Druid()
with warnings.catch_warnings():
warnings.filterwarnings('ignore', message="Druids cannot learn spells")
char.set_attrs(spells=['invisibility'],
spells_prepared=['druidcraft'])
warnings.filterwarnings("ignore", message="Druids cannot learn spells")
char.set_attrs(spells=["invisibility"], spells_prepared=["druidcraft"])
# self.assertEqual(len(char.spells), 1)
self.assertEqual(len(char.spells), 2)
self.assertIn(spells.Druidcraft(), char.spells)
def test_wild_shapes(self):
char = Druid()
# Druid level 2
char.level = 2
# Set reasonable wild shapes
char.wild_shapes = ['Wolf']
char.wild_shapes = ["Wolf"]
self.assertIsInstance(char.wild_shapes[0], monsters.Wolf)
# Check what happens if a non-existent wild_shape is added
with self.assertRaises(exceptions.MonsterError):
char.wild_shapes = ['Wolf', 'Hyperion Loader']
char.wild_shapes = ["Wolf", "Hyperion Loader"]
# Check what happens if a valid monster class is directly added
char.wild_shapes = [monsters.Wolf(), ]
char.wild_shapes = [
monsters.Wolf(),
]
self.assertIsInstance(char.wild_shapes[0], monsters.Wolf)
# Check that invalid monsters aren't accepted
char.wild_shapes = ['Wolf', 'giant eagle']
char.wild_shapes = ["Wolf", "giant eagle"]
self.assertEqual(len(char.wild_shapes), 1)
self.assertIsInstance(char.wild_shapes[0], monsters.Wolf)
def test_moon_druid_wild_shapes(self):
# Moon druid level 2 gets beasts up to CR 1
char = Druid(level=2, wild_shapes=['Ape'], circle='moon')
char = Druid(level=2, wild_shapes=["Ape"], circle="moon")
self.assertEqual(len(char.wild_shapes), 1)
self.assertIsInstance(char.wild_shapes[0], monsters.Ape)
# Moon druid above level 6 gets beasts up to CR level / 3
char = Druid(level=9, wild_shapes=['ankylosaurus'], circle='moon')
char = Druid(level=9, wild_shapes=["ankylosaurus"], circle="moon")
self.assertEqual(len(char.wild_shapes), 1)
self.assertIsInstance(char.wild_shapes[0], monsters.Ankylosaurus)
def test_can_assume_shape(self):
class Beast(monsters.Monster):
description = 'beast'
description = "beast"
new_druid = Druid(level=1)
low_druid = Druid(level=2)
mid_druid = Druid(level=4)
@@ -270,7 +293,7 @@ class DruidTestCase(TestCase):
self.assertTrue(low_druid.can_assume_shape(beast))
# Check that challenge rating is checked
hard_beast = Beast()
hard_beast.challenge_rating = 1/2
hard_beast.challenge_rating = 1 / 2
really_hard_beast = Beast()
really_hard_beast.challenge_rating = 1
self.assertFalse(low_druid.can_assume_shape(hard_beast))
+4 -4
View File
@@ -3,16 +3,16 @@ from unittest import TestCase
from dungeonsheets.exceptions import DiceError
from dungeonsheets import dice
class TestDice(TestCase):
class TestDice(TestCase):
def test_read_dice_str(self):
out = dice.read_dice_str('1d6')
out = dice.read_dice_str("1d6")
self.assertEqual(out.faces, 6)
self.assertEqual(out.num, 1)
# Multiple digits
out = dice.read_dice_str('15d10')
out = dice.read_dice_str("15d10")
self.assertEqual(out.faces, 10)
self.assertEqual(out.num, 15)
# Check a bad value
with self.assertRaises(DiceError):
dice.read_dice_str('Ed15')
dice.read_dice_str("Ed15")
+11 -6
View File
@@ -8,21 +8,26 @@ from dungeonsheets.features import create_feature, Feature, all_features
class TestFeatures(TestCase):
"""Tests for features and feature-related activities."""
def test_all_features(self):
# Make sure only features are returned
for ThisFeature in all_features():
self.assertTrue(isinstance(ThisFeature, type),
f"``all_features`` returned {ThisFeature} (not a class)")
self.assertTrue(issubclass(ThisFeature, Feature),
f"``all_features`` returned {ThisFeature} (not a feature)")
self.assertTrue(
isinstance(ThisFeature, type),
f"``all_features`` returned {ThisFeature} (not a class)",
)
self.assertTrue(
issubclass(ThisFeature, Feature),
f"``all_features`` returned {ThisFeature} (not a feature)",
)
# Pick a couple of known features to spot-check for
all_the_features = list(all_features())
self.assertIn(features.FalseIdentity, all_the_features)
self.assertIn(features.DivineSmite, all_the_features)
def test_create_feature(self):
NewFeature = create_feature(name="Hello world")
self.assertTrue(issubclass(NewFeature, Feature))
self.assertEqual(NewFeature.name, 'Hello world')
self.assertEqual(NewFeature.name, "Hello world")
feature = NewFeature()
print(feature, feature.__class__, type(feature))
+43 -39
View File
@@ -1,53 +1,56 @@
import unittest
from dungeonsheets import make_sheets, character, spells, features, latex
from dungeonsheets import spells, features, latex
class MarkdownTestCase(unittest.TestCase):
"""Check that conversion of markdown formats to LaTeX code works
correctly."""
def test_rst_bold(self):
text = latex.rst_to_latex('**hello**')
self.assertEqual(text, '\n\\textbf{hello}\n')
text = latex.rst_to_latex("**hello**")
self.assertEqual(text, "\n\\textbf{hello}\n")
def test_hit_dice(self):
text = latex.rst_to_latex('1d6+3')
self.assertEqual(text.strip("\n"), '\\texttt{1d6+3}')
text = latex.rst_to_latex("1d6+3")
self.assertEqual(text.strip("\n"), "\\texttt{1d6+3}")
def test_no_text(self):
text = latex.rst_to_latex(None)
self.assertEqual(text, '')
self.assertEqual(text, "")
def test_verbatim(self):
text = latex.rst_to_latex('``hello, world``')
self.assertIn(r'\texttt{hello, world}', text)
text = latex.rst_to_latex("``hello, world``")
self.assertIn(r"\texttt{hello, world}", text)
def test_literal_backslash(self):
text = latex.rst_to_latex(r'\\')
self.assertEqual(r'\textbackslash{}', text.strip("\n"))
text = latex.rst_to_latex(r"\\")
self.assertEqual(r"\textbackslash{}", text.strip("\n"))
@unittest.skip("Headings are all screwed up because it treats them as the document title")
@unittest.skip(
"Headings are all screwed up because it treats them as the document title"
)
def test_headings(self):
# Simple heading by itself
text = latex.rst_to_latex('Hello, world\n------------\n\nGoodbye, world')
self.assertEqual('\\section*{Hello, world}\n', text)
text = latex.rst_to_latex("Hello, world\n------------\n\nGoodbye, world")
self.assertEqual("\\section*{Hello, world}\n", text)
# Simple heading with leading whitespace
text = latex.rst_to_latex(' Hello, world\n ============\n')
self.assertEqual('\\section*{Hello, world}\n', text)
text = latex.rst_to_latex(" Hello, world\n ============\n")
self.assertEqual("\\section*{Hello, world}\n", text)
# Heading with text after it
text = latex.rst_to_latex('Hello, world\n============\n\nThis is some text')
self.assertEqual('\\section*{Hello, world}\n\nThis is some text', text)
text = latex.rst_to_latex("Hello, world\n============\n\nThis is some text")
self.assertEqual("\\section*{Hello, world}\n\nThis is some text", text)
# Heading with text before it
text = latex.rst_to_latex('This is a paragraph\n\nHello, world\n============\n')
self.assertEqual('This is a paragraph\n\n\\section*{Hello, world}\n', text)
text = latex.rst_to_latex("This is a paragraph\n\nHello, world\n============\n")
self.assertEqual("This is a paragraph\n\n\\section*{Hello, world}\n", text)
# Check that levels of headings are parsed appropriately
text = latex.rst_to_latex('Hello, world\n^^^^^^^^^^^^\n')
self.assertEqual('\\subsubsection*{Hello, world}\n', text)
text = latex.rst_to_latex('Hello, world\n^^^^^^^^^^^^\n', top_heading_level=3)
self.assertEqual('\\subparagraph*{Hello, world}\n', text)
text = latex.rst_to_latex("Hello, world\n^^^^^^^^^^^^\n")
self.assertEqual("\\subsubsection*{Hello, world}\n", text)
text = latex.rst_to_latex("Hello, world\n^^^^^^^^^^^^\n", top_heading_level=3)
self.assertEqual("\\subparagraph*{Hello, world}\n", text)
# This is a bad heading missing with all the underline on one line
text = latex.rst_to_latex('Hello, world^^^^^^^^^^^^\n')
self.assertEqual('Hello, world\\^\\^\\^\\^\\^\\^\\^\\^\\^\\^\\^\\^\n', text)
text = latex.rst_to_latex("Hello, world^^^^^^^^^^^^\n")
self.assertEqual("Hello, world\\^\\^\\^\\^\\^\\^\\^\\^\\^\\^\\^\\^\n", text)
def test_bullet_list(self):
tex = latex.rst_to_latex("\n- Hello\n- World\n\n")
@@ -67,14 +70,14 @@ class MarkdownTestCase(unittest.TestCase):
"""
tex = latex.rst_to_latex(real_list)
self.assertIn("\\begin{itemize}", tex)
def test_multiline_bullet_list(self):
md_list = """
- Secondhand (you have heard
of the target) - +5
- Firsthand (you have met
- Firsthand (you have met
the target) - +0
- Familiar (you know the target
- Familiar (you know the target
well) - -5
"""
@@ -100,16 +103,17 @@ class MarkdownTestCase(unittest.TestCase):
self.assertNotIn("endfoot", tex)
self.assertNotIn("endhead", tex)
self.assertNotIn("endfirsthead", tex)
def test_rst_all_spells(self):
for spell in spells.all_spells():
tex = latex.rst_to_latex(spell.__doc__)
self.assertNotIn("DUadmonition", tex,
f"spell {spell} is not valid reStructured text")
self.assertNotIn(
"DUadmonition", tex, f"spell {spell} is not valid reStructured text"
)
def test_rst_all_features(self):
for feature in features.all_features():
tex = latex.rst_to_latex(feature.__doc__)
self.assertNotIn("DUadmonition", tex,
f"feature {feature} is not valid reStructured text")
self.assertNotIn(
"DUadmonition", tex, f"feature {feature} is not valid reStructured text"
)
+13 -15
View File
@@ -1,38 +1,36 @@
import unittest
import os
from pathlib import Path
import subprocess
from dungeonsheets import make_sheets, character
EG_DIR = os.path.abspath(os.path.join(os.path.split(__file__)[0], '../examples/'))
CHARFILE = os.path.join(EG_DIR, 'rogue1.py')
EG_DIR = os.path.abspath(os.path.join(os.path.split(__file__)[0], "../examples/"))
CHARFILE = os.path.join(EG_DIR, "rogue1.py")
class CharacterFileTestCase(unittest.TestCase):
example_dir = Path(__file__).parent.parent / "examples"
# def test_(self):
# print(self.example_dir)
# subprocess.run(['makesheets', self.example_dir])
def test_load_character_file(self):
charfile = CHARFILE
result = make_sheets.load_character_file(charfile)
self.assertEqual(result['strength'], 10)
self.assertEqual(result["strength"], 10)
class PdfOutputTeestCase(unittest.TestCase):
basename = 'clara'
basename = "clara"
def tearDown(self):
temp_files = [f'{self.basename}.pdf']
temp_files = [f"{self.basename}.pdf"]
for f in temp_files:
if os.path.exists(f):
os.remove(f)
def test_file_created(self):
# Check that a file is created once the function is run
pdf_name = f'{self.basename}.pdf'
pdf_name = f"{self.basename}.pdf"
# self.assertFalse(os.path.exists(pdf_name), f'{pdf_name} already exists.')
char = character.Character(name='Clara')
char.saving_throw_proficiencies = ['strength']
char = character.Character(name="Clara")
char.saving_throw_proficiencies = ["strength"]
make_sheets.create_character_pdf(character=char, basename=self.basename)
self.assertTrue(os.path.exists(pdf_name), f'{pdf_name} not created.')
self.assertTrue(os.path.exists(pdf_name), f"{pdf_name} not created.")
+1 -1
View File
@@ -2,7 +2,7 @@
from unittest import TestCase
from dungeonsheets import monsters, exceptions
from dungeonsheets import monsters
class MonsterTestCase(TestCase):
+24 -28
View File
@@ -1,38 +1,39 @@
#!/usr/bin/env python
from unittest import TestCase
import warnings
from dungeonsheets import race, monsters, exceptions, spells
from dungeonsheets.character import Character
from dungeonsheets.weapons import Weapon, Shortsword
from dungeonsheets.armor import Armor, LeatherArmor, Shield
from dungeonsheets.weapons import Shortsword
class TestMulticlass(TestCase):
"""
Tests for Multiclass character.
"""
def test_constructor(self):
char = Character(name='Multiclass',
classes=['wizard', 'fighter'],
levels=[5, 4])
char = Character(
name="Multiclass", classes=["wizard", "fighter"], levels=[5, 4]
)
self.assertIsInstance(char, Character)
def test_level(self):
char = Character(name='Multiclass',
classes=['wizard', 'fighter'],
levels=[5, 4])
char = Character(
name="Multiclass", classes=["wizard", "fighter"], levels=[5, 4]
)
self.assertEqual(char.level, 9)
def test_spellcasting(self):
char = Character(name='Multiclass',
classes=['wizard', 'fighter'],
levels=[5, 4])
char = Character(
name="Multiclass", classes=["wizard", "fighter"], levels=[5, 4]
)
self.assertEqual(len(char.spellcasting_classes), 1)
char = Character(name='Multiclass',
classes=['wizard', 'fighter'],
subclasses=[None, 'Eldritch Knight'],
levels=[5, 4])
char = Character(
name="Multiclass",
classes=["wizard", "fighter"],
subclasses=[None, "Eldritch Knight"],
levels=[5, 4],
)
self.assertEqual(len(char.spellcasting_classes), 2)
# equivalent spellcasting level: 6
self.assertEqual(char.spell_slots(spell_level=1), 4)
@@ -41,20 +42,15 @@ class TestMulticlass(TestCase):
self.assertEqual(char.spell_slots(spell_level=4), 0)
def test_proficiencies(self):
char1 = Character(name='Multiclass',
classes=['wizard', 'fighter'],
levels=[5, 4])
for svt in ('intelligence', 'wisdom'):
char1 = Character(
name="Multiclass", classes=["wizard", "fighter"], levels=[5, 4]
)
for svt in ("intelligence", "wisdom"):
self.assertIn(svt, char1.saving_throw_proficiencies)
char2 = Character(name='Multiclass',
classes=['wizard', 'rogue'],
levels=[5, 4])
char3 = Character(name='Multiclass',
classes=['rogue', 'wizard'],
levels=[4, 5])
char2 = Character(name="Multiclass", classes=["wizard", "rogue"], levels=[5, 4])
char3 = Character(name="Multiclass", classes=["rogue", "wizard"], levels=[4, 5])
sword = Shortsword()
self.assertTrue(char1.is_proficient(sword))
# multiclassing into Rogue doesn't give simple weapon proficiency
self.assertFalse(char2.is_proficient(sword))
self.assertTrue(char3.is_proficient(sword))
+57 -22
View File
@@ -6,21 +6,22 @@ import types
from dungeonsheets.readers import read_character_file
EG_DIR = (Path(__file__).parent.parent / "examples").resolve()
CHAR_PYTHON_FILE = EG_DIR / 'rogue1.py'
CHAR_JSON_FILE = EG_DIR / 'barbarian3.json'
SPELLCASTER_JSON_FILE = EG_DIR / 'artificer2.json'
CHAR_PYTHON_FILE = EG_DIR / "rogue1.py"
CHAR_JSON_FILE = EG_DIR / "barbarian3.json"
SPELLCASTER_JSON_FILE = EG_DIR / "artificer2.json"
class PythonReaderTests(unittest.TestCase):
def test_load_python_file(self):
charfile = CHAR_PYTHON_FILE
result = read_character_file(charfile)
self.assertEqual(result['strength'], 10)
self.assertEqual(result["strength"], 10)
class JSONReaderTests(unittest.TestCase):
class JSONReaderTests(unittest.TestCase):
def test_load_json_file(self):
charfile = CHAR_JSON_FILE
with warnings.catch_warnings(record=True) as w:
with warnings.catch_warnings(record=True):
result = read_character_file(charfile)
expected_data = dict(
name="Ulthar Jenkins",
@@ -35,9 +36,22 @@ class JSONReaderTests(unittest.TestCase):
constitution=19,
intelligence=8,
hp_max=32,
skill_proficiencies=["athletics", "survival",],
weapon_proficiencies=["simple weapons", "martial weapons", "battleaxe", "handaxe", "light hammer", "warhammer", "unarmed strike",],
_proficiencies_text=["Brewer's Supplies",],
skill_proficiencies=[
"athletics",
"survival",
],
weapon_proficiencies=[
"simple weapons",
"martial weapons",
"battleaxe",
"handaxe",
"light hammer",
"warhammer",
"unarmed strike",
],
_proficiencies_text=[
"Brewer's Supplies",
],
languages="common, dwarvish",
cp=26,
sp=55,
@@ -48,13 +62,17 @@ class JSONReaderTests(unittest.TestCase):
magic_items=(),
armor="",
shield="",
personality_traits="Can easily dismember a body\n\nKnow fight battle tactics",
personality_traits=(
"Can easily dismember a body\n\nKnow fight battle tactics"
),
ideals="Vengence",
bonds="friends and adventurers.",
flaws="Bloodthirsty and wants to solve every problem by murder",
equipment=("warhammer, handaxe, explorer's pack, javelin (4), backpack, "
"bedroll, mess kit, tinderbox, torch (10), rations (10), "
"waterskin, hempen rope"),
equipment=(
"warhammer, handaxe, explorer's pack, javelin (4), backpack, "
"bedroll, mess kit, tinderbox, torch (10), rations (10), "
"waterskin, hempen rope"
),
attacks_and_spellcasting="",
spells_prepared=[],
spells=[],
@@ -65,19 +83,36 @@ class JSONReaderTests(unittest.TestCase):
if isinstance(this_result, types.GeneratorType):
this_result = list(this_result)
self.assertEqual(this_result, val, key)
def test_load_json_spells(self):
charfile = SPELLCASTER_JSON_FILE
with warnings.catch_warnings(record=True) as w:
with warnings.catch_warnings(record=True):
result = read_character_file(charfile)
expected_data = dict(
spells_prepared=["cure wounds",],
spells=["spare the dying", "fire bolt", "absorb elements",
"alarm", "catapult", "cure wounds", "detect magic",
"disguise self", "expeditious retreat", "faerie fire",
"false life", "feather fall", "grease", "identify",
"jump", "longstrider", "purify food and drink",
"sanctuary", "snare",],
spells_prepared=[
"cure wounds",
],
spells=[
"spare the dying",
"fire bolt",
"absorb elements",
"alarm",
"catapult",
"cure wounds",
"detect magic",
"disguise self",
"expeditious retreat",
"faerie fire",
"false life",
"feather fall",
"grease",
"identify",
"jump",
"longstrider",
"purify food and drink",
"sanctuary",
"snare",
],
)
for key, val in expected_data.items():
this_result = result[key]
+15 -10
View File
@@ -8,32 +8,37 @@ from dungeonsheets.spells import create_spell, Spell, all_spells
class TestSpells(TestCase):
"""Tests for spells and spell-related activities."""
def test_all_spells(self):
# Make sure only spells are returned
for ThisSpell in all_spells():
self.assertTrue(isinstance(ThisSpell, type),
f"``all_spells`` returned {ThisSpell} (not a class)")
self.assertTrue(issubclass(ThisSpell, Spell),
f"``all_spells`` returned {ThisSpell} (not a spell)")
self.assertTrue(
isinstance(ThisSpell, type),
f"``all_spells`` returned {ThisSpell} (not a class)",
)
self.assertTrue(
issubclass(ThisSpell, Spell),
f"``all_spells`` returned {ThisSpell} (not a spell)",
)
# Pick a couple of known spells to spot-check for
all_the_spells = list(all_spells())
self.assertIn(spells.MagicMissile, all_the_spells)
self.assertIn(spells.Thunderwave, all_the_spells)
def test_create_spell(self):
NewSpell = create_spell(name="Hello world")
self.assertTrue(issubclass(NewSpell, Spell))
self.assertEqual(NewSpell.name, 'Hello world')
self.assertEqual(NewSpell.name, "Hello world")
spell = NewSpell()
print(spell, spell.__class__, type(spell))
def test_spell_str(self):
spell = Spell()
spell.name = "My spell"
self.assertEqual(str(spell), 'My spell')
self.assertEqual(str(spell), "My spell")
# Try with a ritual
spell.ritual = True
self.assertEqual(str(spell), 'My spell (R)')
self.assertEqual(str(spell), "My spell (R)")
# Try with a ritual and a concentration
spell.concentration = True
self.assertEqual(str(spell), 'My spell (R, C)')
self.assertEqual(str(spell), "My spell (R, C)")
+27 -22
View File
@@ -2,27 +2,29 @@ from unittest import TestCase
from dungeonsheets import stats, character
class TestStats(TestCase):
class TestStats(TestCase):
def test_mod_str(self):
self.assertEqual(stats.mod_str(-3), '-3')
self.assertEqual(stats.mod_str(0), '+0')
self.assertEqual(stats.mod_str(2), '+2')
self.assertEqual(stats.mod_str(-3), "-3")
self.assertEqual(stats.mod_str(0), "+0")
self.assertEqual(stats.mod_str(2), "+2")
def test_saving_throw(self):
# Try it with an ST proficiency
class MyClass(character.Character):
saving_throw_proficiencies = ['strength']
saving_throw_proficiencies = ["strength"]
proficiency_bonus = 2
strength = stats.Ability(14)
my_class = MyClass()
self.assertEqual(my_class.strength.saving_throw, 4)
def test_modifier(self):
class MyCharacter(character.Character):
saving_throw_proficiencies = ['strength']
saving_throw_proficiencies = ["strength"]
proficiency_bonus = 2
strength = stats.Ability(14)
my_char = MyCharacter()
ranges = [
((1,), -5),
@@ -47,46 +49,49 @@ class TestStats(TestCase):
for value in range_:
my_char.strength = value
stat = my_char.strength
msg = f"Stat {value} doesn't produce modifier {target} ({stat.modifier})"
msg = (
f"Stat {value} doesn't produce modifier {target} ({stat.modifier})"
)
self.assertEqual(stat.modifier, target, msg)
def test_setter(self):
"""Verify that this class works as a data descriptor."""
# Set up a dummy class
class MyCharacter(character.Character):
stat = stats.Ability()
char = MyCharacter()
# Check that the stat works as expected once set
char.stat = 15
self.assertEqual(char.stat.value, 15)
self.assertEqual(char.stat.modifier, 2)
def test_skill(self):
"""Test for a skill, that depends on another ability."""
class MyClass(character.Character):
dexterity = stats.Ability(14)
acrobatics = stats.Skill(ability='dexterity')
acrobatics = stats.Skill(ability="dexterity")
skill_proficiencies = []
proficiency_bonus = 2
my_class = MyClass()
self.assertEqual(my_class.acrobatics, 2)
# Check for a proficiency
my_class.skill_proficiencies = ['acrobatics']
my_class.skill_proficiencies = ["acrobatics"]
self.assertEqual(my_class.acrobatics, 4)
def test_findattr(self):
"""Check if the function can find attributes."""
class TestClass():
class TestClass:
my_attr = 47
YourAttr = 53
test_class = TestClass()
# Direct access
self.assertEqual(stats.findattr(test_class, 'my_attr'),
test_class.my_attr)
self.assertEqual(stats.findattr(test_class, 'YourAttr'),
test_class.YourAttr)
self.assertEqual(stats.findattr(test_class, "my_attr"), test_class.my_attr)
self.assertEqual(stats.findattr(test_class, "YourAttr"), test_class.YourAttr)
# Swapping spaces for capitalization
self.assertEqual(stats.findattr(test_class, 'my attr'),
test_class.my_attr)
self.assertEqual(stats.findattr(test_class, 'your attr'),
test_class.YourAttr)
self.assertEqual(stats.findattr(test_class, "my attr"), test_class.my_attr)
self.assertEqual(stats.findattr(test_class, "your attr"), test_class.YourAttr)
+3 -3
View File
@@ -6,8 +6,8 @@ from dungeonsheets.weapons import Weapon
class WeaponTestCase(unittest.TestCase):
def test_weapon_damage(self):
weapon = Weapon()
weapon.base_damage = '1d6'
self.assertEqual(weapon.damage, '1d6')
weapon.base_damage = "1d6"
self.assertEqual(weapon.damage, "1d6")
# Now add some bonus damage
weapon.damage_bonus = 2
self.assertEqual(weapon.damage, '1d6+2')
self.assertEqual(weapon.damage, "1d6+2")