Merge pull request #82 from cclauss/patch-4

Pytests of the database
This commit is contained in:
Lazo 2017-07-05 18:14:49 -04:00 committed by GitHub
commit 607ffdcd4e
4 changed files with 283 additions and 0 deletions

31
test_broken.py Normal file
View file

@ -0,0 +1,31 @@
#!/usr/bin/env python3
# To run the tests, use: python3 -m pytest --capture=sys
from database import Database
from test_utils import expected_len
def test_extra_length(region_name='extra'):
assert len(Database().get_extra()) == expected_len(region_name)
def test_kanto_length(region_name='kanto'):
assert len(Database().get_kanto()) == expected_len(region_name)
def test_johto_length(region_name='johto'):
assert len(Database().get_johto()) == expected_len(region_name)
def test_hoenn_length(region_name='hoenn'):
assert len(Database().get_hoenn()) == expected_len(region_name)
def test_sinnoh_length(region_name='sinnoh'):
assert len(Database().get_sinnoh()) == expected_len(region_name)
def test_all_length(region_name='all'):
expected = expected_len(region_name) + expected_len('extra')
assert len(Database().get_all()) == expected

143
test_database.py Normal file
View file

@ -0,0 +1,143 @@
#!/usr/bin/env python3
# To run the tests, use: python3 -m pytest --capture=sys
from database import Database
from test_utils import region_dict, get_region, make_extra_counts, MAX_ID
def test_first_database():
print('{} items in first database.'.format(len(Database())))
def test_second_database():
print('{} items in second database.'.format(len(Database())))
def test_len():
db = Database()
assert len(db) == MAX_ID + len(db.get_extra())
assert len(db.get_all()) == MAX_ID + len(db.get_extra())
def test_extra_counts():
assert len(Database()) == MAX_ID + sum(make_extra_counts().values())
def test_get_extras():
db = Database()
assert db.get_extra(), 'db.get_extra() returns no pokemon'
assert len(db.get_extra()) == sum(make_extra_counts().values())
def region_length_test(region_name):
db = Database()
# test db.get_region()
pokemon = get_region(db, region_name)
assert pokemon, 'No pokemon found in region: ' + region_name
# test that region_name is in region_dict
region_info = region_dict[region_name]
# extra_count = extra_counts.get(region_name, 0)
expected_len = region_info.end - region_info.start + 1 # + extra_count
fmt = 'Testing {}({} vs. {}): {}'
print(fmt.format(region_name, len(pokemon), expected_len, region_info))
# test the number of pokemon returned by db.get_region()
assert len(pokemon) == expected_len
def test_kanto_length():
region_length_test('kanto')
def test_johto_length():
region_length_test('johto')
def test_hoenn_length():
region_length_test('hoenn')
def test_sinnoh_length():
region_length_test('sinnoh')
def region_test(region_name):
db = Database()
# test db.get_region()
pokemon = get_region(db, region_name)
assert pokemon, 'No pokemon found in region: ' + region_name
# test that region_name is in region_dict
region_info = region_dict[region_name]
delta = region_info.end - region_info.start
fmt = 'Testing {}({} vs. {}): {}'
print(fmt.format(region_name, len(pokemon), delta + 1, region_info))
# test db.get_pokemon(id)
middle_pokemon = db.get_pokemon(region_info.start + (delta // 2))
assert middle_pokemon in pokemon
# test db.get_pokemon(name)
name = middle_pokemon.get_name()
assert db.get_pokemon(name) in pokemon
# test the case insensivity of db.get_pokemon(name)
# assert db.get_pokemon(name.upper()) in pokemon # !!! FixMe !!!
def test_kanto():
region_test('kanto')
def test_johto():
region_test('johto')
def test_hoenn():
region_test('hoenn')
def test_sinnoh():
region_test('sinnoh')
def test_regions():
for region_name in region_dict:
region_test(region_name)
def _test_region(region_name):
db = Database()
# Database unfortunately makes db.__get_region() private :-(
func = {
"kanto": db.get_kanto,
"johto": db.get_johto,
"hoenn": db.get_hoenn,
"sinnoh": db.get_sinnoh,
}[region_name]
pokemon_list = func()
region_record = region_dict[region_name]
# make sure there are no missing pokemon
start = region_record.start
end = region_record.end
# extra_count = extra_counts.get(region_name, 0)
assert len(pokemon_list) == end - start + 1 # + extra_count
# make sure that all pokemon.id == '---' or are in the ID range
assert all([start <= int(p.get_id()) <= end for p in pokemon_list if p.get_id() != '---'])
def test_regions_two():
for region_name in region_dict:
_test_region(region_name)
def test_ids():
db = Database()
numbered_ids = [p.get_id() for p in db.get_all() if p.get_id() != '---']
# test that all that are not --- are unique (no duplicate ids)
assert len(set(numbered_ids)) == len(numbered_ids) == MAX_ID
for id_str in numbered_ids:
assert len(id_str) == 3
assert isinstance(id_str, str)
assert 1 <= int(id_str) <= MAX_ID
def test_thresholds():
db = Database()
assert all(isinstance(p.get_dark_threshold(), float) for p in db.get_all())

31
test_scripter.py Normal file
View file

@ -0,0 +1,31 @@
#!/usr/bin/env python3
# To run use python3 -m pytest --capture=sys
from adapter import available_terminals
import os
def test_available_terminals():
assert available_terminals, 'No available_terminals found.'
terminal_names = [terminal.__name__ for terminal in available_terminals]
non_terminals = ['NullAdapter', '__init__']
assert all(terminal not in terminal_names for terminal in non_terminals)
script_dir = os.path.dirname(os.path.realpath(__file__))
terminals_dir = os.path.join(script_dir, 'adapter', 'implementations')
assert os.path.isdir(terminals_dir), 'Not found: ' + terminals_dir
for filename in os.listdir(terminals_dir):
terminal, ext = os.path.splitext(filename)
if ext.lower() == '.py':
assert terminal in (terminal_names + non_terminals), terminal
def test_adapter_methods():
for terminal in available_terminals:
assert callable(terminal.clear)
assert callable(terminal.is_available)
assert callable(terminal.set_image_file_path)
if __name__ == '__main__':
test_available_terminals()

78
test_utils.py Normal file
View file

@ -0,0 +1,78 @@
#!/usr/bin/env python3
# To run the tests, use: python3 -m pytest --capture=sys
"""These are general utilities for testing Pokemon Terminal. The data and
functions in this file can be used by other `test_*.py` scripts but they
should not be imported into or copied into normal scripts in the project.
This approach will help us to steer clear of assumption bias and avoid
shared code between dev and test."""
import os
from collections import Counter, namedtuple
MAX_ID = 493
SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
region_info = namedtuple('region_info', 'start end first last')
region_dict = {
'kanto': region_info(1, 151, 'Bulbasaur', 'Mew'),
'johto': region_info(152, 251, 'Chikorita', 'Celebi'),
'hoenn': region_info(252, 386, 'Treecko', 'Deoxys'),
'sinnoh': region_info(387, 493, 'Turtwig', 'Arceus'),
}
# From: https://en.wikipedia.org/wiki/Pok%C3%A9mon#Generation_1
_counts = {'kanto': 151, 'johto': 100, 'hoenn': 135, 'sinnoh': 107, 'all': 493}
def expected_len(region_name):
"""Utility function for knowing the standard pokemon population."""
if region_name == 'all':
return MAX_ID
elif region_name == 'extra':
return sum(make_extra_counts().values()) # 24
region_info = region_dict[region_name]
return region_info.end - region_info.start + 1
def test_region_dict():
"""Test if region_dict counts match wikipedia."""
assert _counts['all'] == MAX_ID == sum(_counts.values()) // 2
for region_name in region_dict:
assert _counts[region_name] == expected_len(region_name)
# print('{}: {}'.format(region_name, counts[region_name]))
def get_region(db, region_name):
"""Database unfortunately makes db.__get_region() private :-("""
func = {
'kanto': db.get_kanto,
'johto': db.get_johto,
'hoenn': db.get_hoenn,
'sinnoh': db.get_sinnoh,
'extra': db.get_extra,
'all': db.get_all
}[region_name]
return func()
def _pokemon_id_to_region(pokemon_id):
"""Rewrite of Database.__determine_region() avoids sharing implementations
between production code and test code."""
for region_name, region_info in region_dict.items():
if region_info.start <= pokemon_id <= region_info.end:
return region_name
assert False, '{} is an invalid region'.format(pokemon_id)
def make_extra_counts(filename='pokemon.txt'):
"""Test that correct regions are used in load_all_pokemon.load_extras().
Currently generates the dict: {'sinnoh': 14, 'hoenn': 9, 'johto': 1}"""
with open(os.path.join(SCRIPT_DIR, 'Data', filename)) as in_file:
pokemon_names = tuple([line.split()[0] for line in in_file])
filenames = os.listdir(os.path.join(SCRIPT_DIR, 'Images', 'Extra'))
father_names = (filename.split('-')[0] for filename in filenames)
father_ids = (pokemon_names.index(name) for name in father_names)
father_regions = (_pokemon_id_to_region(id) for id in father_ids)
return dict(Counter(father_regions))