mirror of
https://github.com/veekun/pokedex.git
synced 2024-08-20 18:16:34 +00:00
Some love for the interface & tests
This commit is contained in:
parent
b27187e99a
commit
11d803fd63
2 changed files with 121 additions and 80 deletions
|
@ -1,62 +1,82 @@
|
|||
|
||||
import sys
|
||||
|
||||
from pokedex.db import connect
|
||||
from pokedex.util.movesets import main
|
||||
|
||||
testcase_args = u"""
|
||||
NO muk
|
||||
NO beedrill rage pursuit agility endeavor toxic
|
||||
NO ditto psystrike aeroblast mist-ball judgment
|
||||
OK metapod tackle harden
|
||||
OK lugia aeroblast punishment dive snore
|
||||
OK yanmega bug-bite bug-buzz tackle whirlwind
|
||||
OK crobat brave-bird quick-attack gust zen-headbutt
|
||||
OK bagon defense-curl fire-fang hydro-pump shadow-claw
|
||||
OK volcarona endure toxic fly fire-blast
|
||||
OK hippopotas curse revenge sleep-talk swallow
|
||||
OK hippopotas curse revenge sleep-talk snore
|
||||
OK smeargle bug-bite bug-buzz splash fire-blast
|
||||
NO smeargle bug-bite chatter splash fire-blast
|
||||
NO azurill muddy-water iron-tail scald mimic
|
||||
OK salamence dragon-dance dragon-claw fire-blast earthquake -v platinum
|
||||
OK crawdaunt brick-break rock-slide facade toxic -v platinum
|
||||
NO cleffa tickle wish amnesia splash
|
||||
OK tyrogue pursuit
|
||||
NO happiny softboiled
|
||||
NO mamoswine bite body-slam curse double-edge
|
||||
OK shedinja swords-dance
|
||||
NO shedinja swords-dance screech
|
||||
OK shedinja screech double-team fury-cutter x-scissor
|
||||
OK raichu volt-tackle
|
||||
OK raichu surf -v gold
|
||||
OK pikachu volt-tackle thunderbolt bide
|
||||
OK gyarados flail thrash iron-head outrage
|
||||
OK drifblim memento gust thunderbolt pain-split
|
||||
OK crobat nasty-plot brave-bird
|
||||
NO crobat nasty-plot hypnosis
|
||||
OK garchomp double-edge thrash outrage
|
||||
OK nidoking counter disable amnesia head-smash
|
||||
OK aggron stomp smellingsalt screech fire-punch
|
||||
OK tyranitar dragon-dance outrage thunder-wave surf
|
||||
NO butterfree morning-sun harden
|
||||
OK pikachu reversal bide nasty-plot discharge
|
||||
NO pikachu surf charge
|
||||
NO blissey wish counter
|
||||
NO clefairy copycat dynamicpunch
|
||||
"""
|
||||
|
||||
result_map = {'OK': True, 'NO': False}
|
||||
|
||||
def test_cases():
|
||||
session = connect()
|
||||
for argstring in u"""
|
||||
NO muk
|
||||
NO beedrill rage pursuit agility endeavor toxic
|
||||
NO ditto psystrike aeroblast mist-ball judgment
|
||||
OK lugia aeroblast punishment dive snore
|
||||
OK yanmega bug-bite bug-buzz tackle whirlwind
|
||||
OK crobat brave-bird quick-attack gust zen-headbutt
|
||||
OK bagon defense-curl fire-fang hydro-pump shadow-claw
|
||||
OK volcarona endure toxic fly fire-blast
|
||||
OK hippopotas curse revenge sleep-talk swallow
|
||||
OK hippopotas curse revenge sleep-talk snore
|
||||
OK smeargle bug-bite bug-buzz splash fire-blast
|
||||
NO smeargle bug-bite chatter splash fire-blast
|
||||
NO azurill muddy-water iron-tail scald mimic
|
||||
OK salamence dragon-dance dragon-claw fire-blast earthquake -v platinum
|
||||
OK crawdaunt brick-break rock-slide facade toxic -v platinum
|
||||
NO cleffa tickle wish amnesia splash
|
||||
OK tyrogue pursuit
|
||||
NO happiny softboiled
|
||||
NO mamoswine bite body-slam curse double-edge
|
||||
OK raichu volt-tackle
|
||||
OK raichu surf -v gold
|
||||
OK pikachu volt-tackle thunderbolt bide
|
||||
OK gyarados flail thrash iron-head outrage
|
||||
OK drifblim memento gust thunderbolt pain-split
|
||||
OK crobat nasty-plot brave-bird
|
||||
NO crobat nasty-plot hypnosis
|
||||
OK garchomp double-edge thrash outrage
|
||||
OK nidoking counter disable amnesia head-smash
|
||||
OK aggron stomp smellingsalt screech fire-punch
|
||||
OK tyranitar dragon-dance outrage thunder-wave surf
|
||||
NO butterfree morning-sun harden
|
||||
OK pikachu reversal bide nasty-plot discharge
|
||||
NO pikachu surf charge
|
||||
NO blissey wish counter
|
||||
NO clefairy copycat dynamicpunch
|
||||
""".strip().splitlines():
|
||||
for argstring in testcase_args.strip().splitlines():
|
||||
def run_test(argstring):
|
||||
args = argstring.split()
|
||||
assert main(args[1:], session=session) == result_map[args[0]]
|
||||
args = argstring.split() + ['-q']
|
||||
assert bool(main(args[1:], session=session)) == result_map[args[0]]
|
||||
run_test.description = 'Moveset checker test: ' + argstring.strip()
|
||||
yield run_test, argstring.strip()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Nose's default profiler, the unmaintained hotshot, sucks.
|
||||
# Use cProfile instead.
|
||||
filename = 'movesets.profile'
|
||||
print 'Profiling the moveset checker'
|
||||
import cProfile
|
||||
def header(str):
|
||||
print
|
||||
print str
|
||||
cProfile.runctx("[(header(argv), f(argv)) for f, argv in test_cases()]",
|
||||
ok_fail = [0, 0]
|
||||
def run_case(f, argv):
|
||||
print argv, '...',
|
||||
sys.stdout.flush()
|
||||
try:
|
||||
f(argv)
|
||||
ok_fail[0] += 1
|
||||
print 'ok'
|
||||
except AssertionError:
|
||||
ok_fail[1] += 1
|
||||
print 'FAIL'
|
||||
cases = list(test_cases())
|
||||
cProfile.runctx("[(run_case(f, argv)) for f, argv in cases]",
|
||||
globals(), locals(), filename=filename)
|
||||
print "{0} tests: {1[0]} OK, {1[1]} failed".format(sum(ok_fail), ok_fail)
|
||||
print 'Profile stats saved to', filename
|
||||
|
|
|
@ -45,7 +45,7 @@ class MovesetSearch(object):
|
|||
_cache = WeakKeyDictionary()
|
||||
|
||||
def __init__(self, session, pokemon, version, moves, level=100, costs=None,
|
||||
exclude_versions=(), exclude_pokemon=(), debug_level=False):
|
||||
exclude_versions=(), exclude_pokemon=(), debug_level=0):
|
||||
|
||||
self.session = session
|
||||
|
||||
|
@ -1263,9 +1263,23 @@ class GoalNode(PokemonNode):
|
|||
return True
|
||||
|
||||
###
|
||||
### CLI interface
|
||||
### Interface
|
||||
###
|
||||
|
||||
def verify_moveset(session, pokemon, version, moves, level=100, **kwargs):
|
||||
"""Verify the given moveset.
|
||||
|
||||
Returns a result with a hint on how to obtain the moveset, if it is valid.
|
||||
Otherwise, returns a false value.
|
||||
"""
|
||||
try:
|
||||
search = MovesetSearch(session, pokemon, version, moves, level, **kwargs)
|
||||
except IllegalMoveCombination, e:
|
||||
return False
|
||||
else:
|
||||
for result in search:
|
||||
return result
|
||||
|
||||
def print_result(result, moves=()):
|
||||
template = u"{cost:4} {est:4} {action:45.45}{long:1} {pokemon:10}{level:>3}{nl:1}{versions:2} {moves}"
|
||||
print template.format(cost='Cost', est='Est.', action='Action', pokemon='Pokemon',
|
||||
|
@ -1304,6 +1318,10 @@ def main(argv, session=None):
|
|||
default='black',
|
||||
help='Version to search in.')
|
||||
|
||||
parser.add_argument('-q', '--quiet', action='store_true', default=False,
|
||||
help="Don't print out the result, only indicate it by the return "
|
||||
"value.")
|
||||
|
||||
parser.add_argument('-V', '--exclude-version', metavar='VER', type=unicode,
|
||||
action='append', default=[],
|
||||
help='Versions to exclude (along with their '
|
||||
|
@ -1316,8 +1334,8 @@ def main(argv, session=None):
|
|||
|
||||
parser.add_argument('-d', '--debug', action='append_const', const=1,
|
||||
default=[],
|
||||
help='Output timing and debugging information (can be specified more '
|
||||
'than once).')
|
||||
help='Output timing and debugging information. Can be specified more '
|
||||
'than once for even more verbosity.')
|
||||
|
||||
args = parser.parse_args(argv)
|
||||
args.debug = len(args.debug)
|
||||
|
@ -1331,54 +1349,57 @@ def main(argv, session=None):
|
|||
if args.debug:
|
||||
print 'Parsing arguments'
|
||||
|
||||
class BadArgs(ValueError): pass
|
||||
|
||||
def _get_list(table, idents, name):
|
||||
if not idents:
|
||||
return []
|
||||
result = []
|
||||
query = session.query(table).filter(table.identifier.in_(idents))
|
||||
query = query.order_by(table.id.desc()) # overwrite pokemon alt. forms
|
||||
ident_map = dict((thing.identifier, thing) for thing in query)
|
||||
for ident in idents:
|
||||
try:
|
||||
result.append(util.get(session, table, identifier=ident))
|
||||
except NoResultFound:
|
||||
result.append(ident_map[ident])
|
||||
except KeyError:
|
||||
print>>sys.stderr, ('%s %s not found. Please use '
|
||||
'the identifier.' % (name, ident))
|
||||
return False
|
||||
raise BadArgs
|
||||
return result
|
||||
|
||||
pokemon = _get_list(tables.Pokemon, [args.pokemon], 'Pokemon')[0]
|
||||
try:
|
||||
all_pokemon = _get_list(tables.Pokemon,
|
||||
[args.pokemon] + args.exclude_pokemon, 'Pokemon')
|
||||
all_versions = _get_list(tables.Version,
|
||||
[args.version] + args.exclude_version, 'Version')
|
||||
|
||||
pokemon = all_pokemon[0]
|
||||
moves = _get_list(tables.Move, args.move, 'Move')
|
||||
version = _get_list(tables.Version, [args.version], 'Version')[0]
|
||||
excl_versions = _get_list(tables.Version, args.exclude_version, 'Version')
|
||||
excl_pokemon = _get_list(tables.Pokemon, args.exclude_pokemon, 'Pokemon')
|
||||
version = all_versions[0]
|
||||
excl_versions = all_versions[1:]
|
||||
excl_pokemon = all_pokemon[1:]
|
||||
except BadArgs:
|
||||
return False
|
||||
|
||||
if args.debug:
|
||||
print 'Starting search'
|
||||
|
||||
no_results = True
|
||||
try:
|
||||
search = MovesetSearch(session, pokemon, version, moves, args.level,
|
||||
result = verify_moveset(session, pokemon, version, moves, args.level,
|
||||
exclude_versions=excl_versions, exclude_pokemon=excl_pokemon,
|
||||
debug_level=args.debug)
|
||||
except IllegalMoveCombination, e:
|
||||
print 'Error:', e
|
||||
# XXX: Support more than one result
|
||||
if result:
|
||||
if args.debug:
|
||||
print '-' * 79
|
||||
if not args.quiet:
|
||||
print_result(result, moves=moves)
|
||||
else:
|
||||
if args.debug:
|
||||
print 'Setup done'
|
||||
|
||||
for result in search:
|
||||
if args.debug and search.output_objects:
|
||||
print '**warning: search looked up output objects**'
|
||||
no_results = False
|
||||
print '-' * 79
|
||||
print_result(result, moves=moves)
|
||||
# XXX: Support more than one result
|
||||
break
|
||||
|
||||
if args.debug:
|
||||
print
|
||||
print 'Done'
|
||||
|
||||
if no_results:
|
||||
print ' ' * 79
|
||||
if not args.quiet:
|
||||
print 'Illegal move combination.'
|
||||
|
||||
return (not no_results)
|
||||
return result
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(not main(sys.argv[1:]))
|
||||
|
|
Loading…
Reference in a new issue