This commit is contained in:
AlxAI 2025-02-06 14:33:10 -08:00
parent e8530a146d
commit 93c073e2df
295 changed files with 86794 additions and 0 deletions

View file

@ -0,0 +1,16 @@
# ==============================================================================
# Copyright (C) 2019 - Philip Paquette
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>.
# ==============================================================================

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,7 @@
17,NME ( A l b e r t ) ( v 6 . 0 . 1 )
17,,YES ( NME ( A l b e r t ) ( v 6 . 0 . 1 ) )
17,,MAP ( s t a n d a r d )
17,MDF
17,,MDF ( AUS ENG FRA GER ITA RUS TUR ) ( ( ( AUS BUD TRI VIE ) ( ENG EDI LON LVP ) ( FRA BRE MAR PAR ) ( GER BER KIE MUN ) ( ITA NAP ROM VEN ) ( RUS MOS SEV STP WAR ) ( TUR ANK CON SMY ) ( UNO BEL BUL DEN GRE HOL NWY POR RUM SER SPA SWE TUN ) ) ( ADR AEG ALB APU ARM BAL BAR BLA BOH GOB BUR CLY EAS ECH FIN GAL GAS HEL ION IRI LVN GOL MAO NAF NAO NTH NWG PIC PIE PRU RUH SIL SKA SYR TUS TYR TYS UKR WAL WES YOR ) ) ( ( ADR ( FLT ALB APU ION TRI VEN ) ) ( AEG ( FLT ( BUL SCS ) CON EAS GRE ION SMY ) ) ( ALB ( AMY GRE SER TRI ) ( FLT ADR GRE ION TRI ) ) ( ANK ( AMY ARM CON SMY ) ( FLT ARM BLA CON ) ) ( APU ( AMY NAP ROM VEN ) ( FLT ADR ION NAP VEN ) ) ( ARM ( AMY ANK SEV SMY SYR ) ( FLT ANK BLA SEV ) ) ( BAL ( FLT BER GOB DEN KIE LVN PRU SWE ) ) ( BAR ( FLT NWG NWY ( STP NCS ) ) ) ( BEL ( AMY BUR HOL PIC RUH ) ( FLT ECH HOL NTH PIC ) ) ( BER ( AMY KIE MUN PRU SIL ) ( FLT BAL KIE PRU ) ) ( BLA ( FLT ANK ARM ( BUL ECS ) CON RUM SEV ) ) ( BOH ( AMY GAL MUN SIL TYR VIE ) ) ( GOB ( FLT BAL FIN LVN ( STP SCS ) SWE ) ) ( BRE ( AMY GAS PAR PIC ) ( FLT ECH GAS MAO PIC ) ) ( BUD ( AMY GAL RUM SER TRI VIE ) ) ( BUL ( AMY CON GRE RUM SER ) ( ( FLT ECS ) BLA CON RUM ) ( ( FLT SCS ) AEG CON GRE ) ) ( BUR ( AMY BEL GAS MAR MUN PAR PIC RUH ) ) ( CLY ( AMY EDI LVP ) ( FLT EDI LVP NAO NWG ) ) ( CON ( AMY ANK BUL SMY ) ( FLT AEG ANK BLA ( BUL ECS ) ( BUL SCS ) SMY ) ) ( DEN ( AMY KIE SWE ) ( FLT BAL HEL KIE NTH SKA SWE ) ) ( EAS ( FLT AEG ION SMY SYR ) ) ( EDI ( AMY CLY LVP YOR ) ( FLT CLY NTH NWG YOR ) ) ( ECH ( FLT BEL BRE IRI LON MAO NTH PIC WAL ) ) ( FIN ( AMY NWY STP SWE ) ( FLT GOB ( STP SCS ) SWE ) ) ( GAL ( AMY BOH BUD RUM SIL UKR VIE WAR ) ) ( GAS ( AMY BRE BUR MAR PAR SPA ) ( FLT BRE MAO ( SPA NCS ) ) ) ( GRE ( AMY ALB BUL SER ) ( FLT AEG ALB ( BUL SCS ) ION ) ) ( HEL ( FLT DEN HOL KIE NTH ) ) ( HOL ( AMY BEL KIE RUH ) ( FLT BEL HEL KIE NTH ) ) ( ION ( FLT ADR AEG ALB APU EAS GRE NAP TUN TYS ) ) ( IRI ( FLT ECH LVP MAO NAO WAL ) ) ( KIE ( AMY BER DEN HOL MUN RUH ) ( FLT BAL BER DEN HEL HOL ) ) ( LON ( AMY WAL YOR ) ( FLT ECH NTH WAL YOR ) ) ( LVN ( AMY MOS PRU STP WAR ) ( FLT BAL GOB PRU ( STP SCS ) ) ) ( LVP ( AMY CLY EDI WAL YOR ) ( FLT CLY IRI NAO WAL ) ) ( GOL ( FLT MAR PIE ( SPA SCS ) TUS TYS WES ) ) ( MAO ( FLT BRE ECH GAS IRI NAF NAO POR ( SPA NCS ) ( SPA SCS ) WES ) ) ( MAR ( AMY BUR GAS PIE SPA ) ( FLT GOL PIE ( SPA SCS ) ) ) ( MOS ( AMY LVN SEV STP UKR WAR ) ) ( MUN ( AMY BER BOH BUR KIE RUH SIL TYR ) ) ( NAF ( AMY TUN ) ( FLT MAO TUN WES ) ) ( NAO ( FLT CLY IRI LVP MAO NWG ) ) ( NAP ( AMY APU ROM ) ( FLT APU ION ROM TYS ) ) ( NTH ( FLT BEL DEN EDI ECH HEL HOL LON NWG NWY SKA YOR ) ) ( NWG ( FLT BAR CLY EDI NAO NTH NWY ) ) ( NWY ( AMY FIN STP SWE ) ( FLT BAR NTH NWG SKA ( STP NCS ) SWE ) ) ( PAR ( AMY BRE BUR GAS PIC ) ) ( PIC ( AMY BEL BRE BUR PAR ) ( FLT BEL BRE ECH ) ) ( PIE ( AMY MAR TUS TYR VEN ) ( FLT GOL MAR TUS ) ) ( POR ( AMY SPA ) ( FLT MAO ( SPA NCS ) ( SPA SCS ) ) ) ( PRU ( AMY BER LVN SIL WAR ) ( FLT BAL BER LVN ) ) ( ROM ( AMY APU NAP TUS VEN ) ( FLT NAP TUS TYS ) ) ( RUH ( AMY BEL BUR HOL KIE MUN ) ) ( RUM ( AMY BUD BUL GAL SER SEV UKR ) ( FLT BLA ( BUL ECS ) SEV ) ) ( SER ( AMY ALB BUD BUL GRE RUM TRI ) ) ( SEV ( AMY ARM MOS RUM UKR ) ( FLT ARM BLA RUM ) ) ( SIL ( AMY BER BOH GAL MUN PRU WAR ) ) ( SKA ( FLT DEN NTH NWY SWE ) ) ( SMY ( AMY ANK ARM CON SYR ) ( FLT AEG CON EAS SYR ) ) ( SPA ( AMY GAS MAR POR ) ( ( FLT NCS ) GAS MAO POR ) ( ( FLT SCS ) GOL MAO MAR POR WES ) ) ( STP ( AMY FIN LVN MOS NWY ) ( ( FLT NCS ) BAR NWY ) ( ( FLT SCS ) GOB FIN LVN ) ) ( SWE ( AMY DEN FIN NWY ) ( FLT BAL GOB DEN FIN NWY SKA ) ) ( SYR ( AMY ARM SMY ) ( FLT EAS SMY ) ) ( TRI ( AMY ALB BUD SER TYR VEN VIE ) ( FLT ADR ALB VEN ) ) ( TUN ( AMY NAF ) ( FLT ION NAF TYS WES ) ) ( TUS ( AMY PIE ROM VEN ) ( FLT GOL PIE ROM TYS ) ) ( TYR ( AMY BOH MUN PIE TRI VEN VIE ) ) ( TYS ( FLT ION GOL NAP ROM TUN TUS WES ) ) ( UKR ( AMY GAL MOS RUM SEV WAR ) ) ( VEN ( AMY APU PIE ROM TRI TUS TYR ) ( FLT ADR APU TRI ) ) ( VIE ( AMY BOH BUD GAL TRI TYR ) ) ( WAL ( AMY LON LVP YOR ) ( FLT ECH IRI LON LVP ) ) ( WAR ( AMY GAL LVN MOS PRU SIL UKR ) ) ( WES ( FLT GOL MAO NAF ( SPA SCS ) TUN TYS ) ) ( YOR ( AMY EDI LON LVP WAL ) ( FLT EDI LON NTH ) ) )
17,REJ ( MAP ( s t a n d a r d ) )
17,,OFF
1 17,NME ( A l b e r t ) ( v 6 . 0 . 1 )
2 17,,YES ( NME ( A l b e r t ) ( v 6 . 0 . 1 ) )
3 17,,MAP ( s t a n d a r d )
4 17,MDF
5 17,,MDF ( AUS ENG FRA GER ITA RUS TUR ) ( ( ( AUS BUD TRI VIE ) ( ENG EDI LON LVP ) ( FRA BRE MAR PAR ) ( GER BER KIE MUN ) ( ITA NAP ROM VEN ) ( RUS MOS SEV STP WAR ) ( TUR ANK CON SMY ) ( UNO BEL BUL DEN GRE HOL NWY POR RUM SER SPA SWE TUN ) ) ( ADR AEG ALB APU ARM BAL BAR BLA BOH GOB BUR CLY EAS ECH FIN GAL GAS HEL ION IRI LVN GOL MAO NAF NAO NTH NWG PIC PIE PRU RUH SIL SKA SYR TUS TYR TYS UKR WAL WES YOR ) ) ( ( ADR ( FLT ALB APU ION TRI VEN ) ) ( AEG ( FLT ( BUL SCS ) CON EAS GRE ION SMY ) ) ( ALB ( AMY GRE SER TRI ) ( FLT ADR GRE ION TRI ) ) ( ANK ( AMY ARM CON SMY ) ( FLT ARM BLA CON ) ) ( APU ( AMY NAP ROM VEN ) ( FLT ADR ION NAP VEN ) ) ( ARM ( AMY ANK SEV SMY SYR ) ( FLT ANK BLA SEV ) ) ( BAL ( FLT BER GOB DEN KIE LVN PRU SWE ) ) ( BAR ( FLT NWG NWY ( STP NCS ) ) ) ( BEL ( AMY BUR HOL PIC RUH ) ( FLT ECH HOL NTH PIC ) ) ( BER ( AMY KIE MUN PRU SIL ) ( FLT BAL KIE PRU ) ) ( BLA ( FLT ANK ARM ( BUL ECS ) CON RUM SEV ) ) ( BOH ( AMY GAL MUN SIL TYR VIE ) ) ( GOB ( FLT BAL FIN LVN ( STP SCS ) SWE ) ) ( BRE ( AMY GAS PAR PIC ) ( FLT ECH GAS MAO PIC ) ) ( BUD ( AMY GAL RUM SER TRI VIE ) ) ( BUL ( AMY CON GRE RUM SER ) ( ( FLT ECS ) BLA CON RUM ) ( ( FLT SCS ) AEG CON GRE ) ) ( BUR ( AMY BEL GAS MAR MUN PAR PIC RUH ) ) ( CLY ( AMY EDI LVP ) ( FLT EDI LVP NAO NWG ) ) ( CON ( AMY ANK BUL SMY ) ( FLT AEG ANK BLA ( BUL ECS ) ( BUL SCS ) SMY ) ) ( DEN ( AMY KIE SWE ) ( FLT BAL HEL KIE NTH SKA SWE ) ) ( EAS ( FLT AEG ION SMY SYR ) ) ( EDI ( AMY CLY LVP YOR ) ( FLT CLY NTH NWG YOR ) ) ( ECH ( FLT BEL BRE IRI LON MAO NTH PIC WAL ) ) ( FIN ( AMY NWY STP SWE ) ( FLT GOB ( STP SCS ) SWE ) ) ( GAL ( AMY BOH BUD RUM SIL UKR VIE WAR ) ) ( GAS ( AMY BRE BUR MAR PAR SPA ) ( FLT BRE MAO ( SPA NCS ) ) ) ( GRE ( AMY ALB BUL SER ) ( FLT AEG ALB ( BUL SCS ) ION ) ) ( HEL ( FLT DEN HOL KIE NTH ) ) ( HOL ( AMY BEL KIE RUH ) ( FLT BEL HEL KIE NTH ) ) ( ION ( FLT ADR AEG ALB APU EAS GRE NAP TUN TYS ) ) ( IRI ( FLT ECH LVP MAO NAO WAL ) ) ( KIE ( AMY BER DEN HOL MUN RUH ) ( FLT BAL BER DEN HEL HOL ) ) ( LON ( AMY WAL YOR ) ( FLT ECH NTH WAL YOR ) ) ( LVN ( AMY MOS PRU STP WAR ) ( FLT BAL GOB PRU ( STP SCS ) ) ) ( LVP ( AMY CLY EDI WAL YOR ) ( FLT CLY IRI NAO WAL ) ) ( GOL ( FLT MAR PIE ( SPA SCS ) TUS TYS WES ) ) ( MAO ( FLT BRE ECH GAS IRI NAF NAO POR ( SPA NCS ) ( SPA SCS ) WES ) ) ( MAR ( AMY BUR GAS PIE SPA ) ( FLT GOL PIE ( SPA SCS ) ) ) ( MOS ( AMY LVN SEV STP UKR WAR ) ) ( MUN ( AMY BER BOH BUR KIE RUH SIL TYR ) ) ( NAF ( AMY TUN ) ( FLT MAO TUN WES ) ) ( NAO ( FLT CLY IRI LVP MAO NWG ) ) ( NAP ( AMY APU ROM ) ( FLT APU ION ROM TYS ) ) ( NTH ( FLT BEL DEN EDI ECH HEL HOL LON NWG NWY SKA YOR ) ) ( NWG ( FLT BAR CLY EDI NAO NTH NWY ) ) ( NWY ( AMY FIN STP SWE ) ( FLT BAR NTH NWG SKA ( STP NCS ) SWE ) ) ( PAR ( AMY BRE BUR GAS PIC ) ) ( PIC ( AMY BEL BRE BUR PAR ) ( FLT BEL BRE ECH ) ) ( PIE ( AMY MAR TUS TYR VEN ) ( FLT GOL MAR TUS ) ) ( POR ( AMY SPA ) ( FLT MAO ( SPA NCS ) ( SPA SCS ) ) ) ( PRU ( AMY BER LVN SIL WAR ) ( FLT BAL BER LVN ) ) ( ROM ( AMY APU NAP TUS VEN ) ( FLT NAP TUS TYS ) ) ( RUH ( AMY BEL BUR HOL KIE MUN ) ) ( RUM ( AMY BUD BUL GAL SER SEV UKR ) ( FLT BLA ( BUL ECS ) SEV ) ) ( SER ( AMY ALB BUD BUL GRE RUM TRI ) ) ( SEV ( AMY ARM MOS RUM UKR ) ( FLT ARM BLA RUM ) ) ( SIL ( AMY BER BOH GAL MUN PRU WAR ) ) ( SKA ( FLT DEN NTH NWY SWE ) ) ( SMY ( AMY ANK ARM CON SYR ) ( FLT AEG CON EAS SYR ) ) ( SPA ( AMY GAS MAR POR ) ( ( FLT NCS ) GAS MAO POR ) ( ( FLT SCS ) GOL MAO MAR POR WES ) ) ( STP ( AMY FIN LVN MOS NWY ) ( ( FLT NCS ) BAR NWY ) ( ( FLT SCS ) GOB FIN LVN ) ) ( SWE ( AMY DEN FIN NWY ) ( FLT BAL GOB DEN FIN NWY SKA ) ) ( SYR ( AMY ARM SMY ) ( FLT EAS SMY ) ) ( TRI ( AMY ALB BUD SER TYR VEN VIE ) ( FLT ADR ALB VEN ) ) ( TUN ( AMY NAF ) ( FLT ION NAF TYS WES ) ) ( TUS ( AMY PIE ROM VEN ) ( FLT GOL PIE ROM TYS ) ) ( TYR ( AMY BOH MUN PIE TRI VEN VIE ) ) ( TYS ( FLT ION GOL NAP ROM TUN TUS WES ) ) ( UKR ( AMY GAL MOS RUM SEV WAR ) ) ( VEN ( AMY APU PIE ROM TRI TUS TYR ) ( FLT ADR APU TRI ) ) ( VIE ( AMY BOH BUD GAL TRI TYR ) ) ( WAL ( AMY LON LVP YOR ) ( FLT ECH IRI LON LVP ) ) ( WAR ( AMY GAL LVN MOS PRU SIL UKR ) ) ( WES ( FLT GOL MAO NAF ( SPA SCS ) TUN TYS ) ) ( YOR ( AMY EDI LON LVP WAL ) ( FLT EDI LON NTH ) ) )
6 17,REJ ( MAP ( s t a n d a r d ) )
7 17,,OFF

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,479 @@
# ==============================================================================
# Copyright (C) 2019 - Philip Paquette
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>.
# ==============================================================================
""" Tests for complete DAIDE games """
from collections import namedtuple
import logging
import os
import random
import signal
from tornado import gen
from tornado.concurrent import chain_future, Future
from tornado.ioloop import IOLoop
from tornado.iostream import StreamClosedError
from tornado.tcpclient import TCPClient
from diplomacy import Server
from diplomacy.daide import messages, tokens
from diplomacy.daide.tokens import Token
from diplomacy.daide.utils import str_to_bytes, bytes_to_str
from diplomacy.server.server import is_port_opened
from diplomacy.server.server_game import ServerGame
from diplomacy.client.connection import connect
from diplomacy.utils import common, constants, strings
# Constants
LOGGER = logging.getLogger('diplomacy.daide.tests.test_daide_game')
HOSTNAME = 'localhost'
FILE_FOLDER_NAME = os.path.abspath(os.path.dirname(__file__))
BOT_KEYWORD = '__bot__'
# Named Tuples
DaideComm = namedtuple('DaideComm', ['client_id', 'request', 'resp_notifs'])
ClientRequest = namedtuple('ClientRequest', ['client', 'request'])
# Adapted from: https://stackoverflow.com/questions/492519/timeout-on-a-function-call
def run_with_timeout(callable_fn, timeout):
""" Raises an error on timeout """
def handler(signum, frame):
""" Raises a timeout """
raise TimeoutError()
signal.signal(signal.SIGALRM, handler)
signal.alarm(timeout)
try:
return callable_fn()
except TimeoutError as exc:
raise exc
finally:
signal.alarm(0)
class ClientCommsSimulator:
""" Represents a client's comms """
def __init__(self, client_id):
""" Constructor
:param client_id: the id
"""
self._id = client_id
self._stream = None
self._is_game_joined = False
self._comms = False
@property
def stream(self):
""" Returns the stream """
return self._stream
@property
def comms(self):
""" Returns the comms """
return self._comms
@property
def is_game_joined(self):
""" Returns if the client has joinded the game """
return self._is_game_joined
def set_comms(self, comms):
""" Set the client's communications.
The client's comms will be sorted to have the requests of a phase
preceding the responses / notifications of the phase
:param comms: the game's communications
"""
self._comms = [comm for comm in comms if comm.client_id == self._id]
comm_idx = 0
while comm_idx < len(self._comms):
comm = self._comms[comm_idx]
# Find the request being right after a synchonization point (TME notification)
if not comm.request:
comm_idx += 1
continue
# Next communication to sort
next_comm_idx = comm_idx + 1
while next_comm_idx < len(self._comms):
next_comm = self._comms[next_comm_idx]
# Group the request at the beginning of the communications in the phase
if next_comm.request:
comm_idx += 1
self._comms.insert(comm_idx, self._comms.pop(next_comm_idx))
# Synchonization point is a TME notif as it marks the beginning of a phase
if any(resp_notif.startswith('TME') for resp_notif in next_comm.resp_notifs):
break
next_comm_idx += 1
comm_idx += 1
def pop_next_request(self, comms):
""" Pop the next request from a DAIDE communications list
:return: The next request along with the updated list of communications
or None and the updated list of communications
"""
com = next(iter(comms), None)
request = None
while com and com.client_id == self._id:
if com.request:
request = com.request
comms[0] = DaideComm(com.client_id, '', com.resp_notifs)
LOGGER.info('[%d:%d] preparing to send request [%s]', self._id, self.stream.socket.fileno()+1, request)
break
elif com.resp_notifs:
break
else:
comms.pop(0)
com = next(iter(comms), None)
return request, comms
def pop_next_resp_notif(self, comms):
""" Pop the next response or notifcation from a DAIDE communications list
:return: The next response or notifcation along with the updated list of communications
or None and the updated list of communications
"""
com = next(iter(comms), None)
resp_notif = None
while com and com.client_id == self._id:
if com.request:
break
elif com.resp_notifs:
resp_notif = com.resp_notifs.pop(0)
LOGGER.info('[%d:%d] waiting for resp_notif [%s]', self._id, self.stream.socket.fileno()+1, resp_notif)
break
else:
comms.pop(0)
com = next(iter(comms), None)
return resp_notif, comms
@gen.coroutine
def connect(self, game_port):
""" Connect to the DAIDE server
:param game_port: the DAIDE game's port
"""
self._stream = yield TCPClient().connect('localhost', game_port)
LOGGER.info('Connected to %d', game_port)
message = messages.InitialMessage()
yield self._stream.write(bytes(message))
yield messages.DaideMessage.from_stream(self._stream)
@gen.coroutine
def send_request(self, request):
""" Sends a request
:param request: the request to send
"""
message = messages.DiplomacyMessage()
message.content = str_to_bytes(request)
yield self._stream.write(bytes(message))
@gen.coroutine
def validate_resp_notifs(self, expected_resp_notifs):
""" Validate that expected response / notifications are received regardless of the order
:param expected_resp_notifs: the response / notifications to receive
"""
while expected_resp_notifs:
resp_notif_message = yield messages.DaideMessage.from_stream(self._stream)
resp_notif = bytes_to_str(resp_notif_message.content)
if Token(from_bytes=resp_notif_message.content[:2]) == tokens.HLO:
resp_notif = resp_notif.split(' ')
resp_notif[5] = expected_resp_notifs[0].split(' ')[5]
resp_notif = ' '.join(resp_notif)
self._is_game_joined = True
LOGGER.info('[%d:%d] Received reply [%s]', self._id, self.stream.socket.fileno() + 1, str(resp_notif))
LOGGER.info('[%d:%d] Replies in buffer [%s]', self._id, self.stream.socket.fileno() + 1,
','.join(expected_resp_notifs))
assert resp_notif in expected_resp_notifs
expected_resp_notifs.remove(resp_notif)
@gen.coroutine
def execute_phase(self, game_id, channels):
""" Execute a single communications phase
:param game_id: The game id of the current game
:param channels: A dictionary of power name to its channel (BOT_KEYWORD for dummies)
:return: True if there are communications left to execute in the game
"""
# pylint: disable=too-many-nested-blocks
try:
while self._comms:
request, self._comms = self.pop_next_request(self._comms)
# If request is GOF - Sending empty orders for all human and dummy powers
if request and request.split()[0] == 'GOF':
# Joining all games first
games = {}
for power_name, channel in channels.items():
if power_name == BOT_KEYWORD:
all_dummy_power_names = yield channel.get_dummy_waiting_powers(buffer_size=100)
for dummy_name in all_dummy_power_names.get(game_id, []):
games[dummy_name] = yield channel.join_game(game_id=game_id, power_name=dummy_name)
else:
games[power_name] = yield channel.join_game(game_id=game_id, power_name=power_name)
# Submitting orders
for power_name, game in games.items():
yield game.set_orders(power_name=power_name, orders=[], wait=False)
# Sending request
if request is not None:
yield self.send_request(request)
expected_resp_notifs = []
expected_resp_notif, self._comms = self.pop_next_resp_notif(self._comms)
while expected_resp_notif is not None:
expected_resp_notifs.append(expected_resp_notif)
# Synchonization point is the request being right after a TME notif or
# the next set of responses / notifications
if expected_resp_notif.startswith('TME'):
break
expected_resp_notif, self._comms = self.pop_next_resp_notif(self._comms)
if expected_resp_notifs:
future = self.validate_resp_notifs(expected_resp_notifs)
@gen.coroutine
def validate_resp_notifs():
yield future
run_with_timeout(validate_resp_notifs, 1)
yield future
break
except StreamClosedError as err:
LOGGER.error('Stream closed: %s', err)
return False
return bool(self._comms)
class ClientsCommsSimulator:
""" Represents multi clients's communications """
def __init__(self, nb_clients, csv_file, game_id, channels):
""" Constructor
:param nb_clients: the number of clients
:param csv_file: the csv containing the communications in chronological order
:param game_id: The game id on the server
:param channels: A dictionary of power name to its channel (BOT_KEYWORD for dummies)
"""
with open(csv_file, 'r') as file:
content = file.read()
content = [line.split(',') for line in content.split('\n') if not line.startswith('#')]
self._game_port = None
self._nb_clients = nb_clients
self._comms = [DaideComm(int(line[0]), line[1], line[2:]) for line in content if line[0]]
self._clients = {}
self._game_id = game_id
self._channels = channels
@gen.coroutine
def retrieve_game_port(self, host, port):
""" Retreive and store the game's port
:param host: the host
:param port: the port
:param game_id: the game id
"""
connection = yield connect(host, port)
self._game_port = yield connection.get_daide_port(self._game_id)
yield connection.connection.close()
@gen.coroutine
def execute(self):
""" Executes the communications between clients """
try:
# Synchronize clients joining the game
while self._comms and (not self._clients
or not all(client.is_game_joined for client in self._clients.values())):
try:
next_comm = next(iter(self._comms)) # type: DaideComm
except StopIteration:
break
if next_comm.client_id not in self._clients and len(self._clients) < self._nb_clients:
client = ClientCommsSimulator(next_comm.client_id)
yield client.connect(self._game_port)
self._clients[next_comm.client_id] = client
for client in self._clients.values():
request, self._comms = client.pop_next_request(self._comms)
if request is not None:
yield client.send_request(request)
expected_resp_notif, self._comms = client.pop_next_resp_notif(self._comms)
while expected_resp_notif is not None:
yield client.validate_resp_notifs([expected_resp_notif])
expected_resp_notif, self._comms = client.pop_next_resp_notif(self._comms)
except StreamClosedError as err:
LOGGER.error('Stream closed: %s', err)
execution_running = []
for client in self._clients.values():
client.set_comms(self._comms)
execution_running.append(client.execute_phase(self._game_id, self._channels))
execution_running = yield execution_running
while any(execution_running):
execution_running = yield [client.execute_phase(self._game_id, self._channels)
for client in self._clients.values()]
assert all(not client.comms for client in self._clients.values())
def run_game_data(nb_daide_clients, rules, csv_file):
""" Start a server and a client to test DAIDE communications
:param port: The port of the DAIDE server
:param csv_file: the csv file containing the list of DAIDE communications
"""
server = Server()
io_loop = IOLoop()
io_loop.make_current()
common.Tornado.stop_loop_on_callback_error(io_loop)
@gen.coroutine
def coroutine_func():
""" Concrete call to main function. """
port = random.randint(9000, 9999)
while is_port_opened(port, HOSTNAME):
port = random.randint(9000, 9999)
nb_human_players = 1 if nb_daide_clients < 7 else 0
server.start(port=port)
server_game = ServerGame(map_name='standard',
n_controls=nb_daide_clients + nb_human_players,
rules=rules,
server=server)
# Register game on server.
game_id = server_game.game_id
server.add_new_game(server_game)
server.start_new_daide_server(game_id)
# Creating human player
human_username = 'username'
human_password = 'password'
# Creating bot player to play for dummy powers
bot_username = constants.PRIVATE_BOT_USERNAME
bot_password = constants.PRIVATE_BOT_PASSWORD
# Connecting
connection = yield connect(HOSTNAME, port)
human_channel = yield connection.authenticate(human_username, human_password)
bot_channel = yield connection.authenticate(bot_username, bot_password)
# Joining human to game
channels = {BOT_KEYWORD: bot_channel}
if nb_human_players:
yield human_channel.join_game(game_id=game_id, power_name='AUSTRIA')
channels['AUSTRIA'] = human_channel
comms_simulator = ClientsCommsSimulator(nb_daide_clients, csv_file, game_id, channels)
yield comms_simulator.retrieve_game_port(HOSTNAME, port)
# done_future is only used to prevent pylint E1101 errors on daide_future
done_future = Future()
daide_future = comms_simulator.execute()
chain_future(daide_future, done_future)
for _ in range(3 + nb_daide_clients):
if done_future.done() or server_game.count_controlled_powers() >= (nb_daide_clients + nb_human_players):
break
yield gen.sleep(2.5)
else:
raise TimeoutError()
# Waiting for process to finish
while not done_future.done() and server_game.status == strings.ACTIVE:
yield gen.sleep(2.5)
yield daide_future
try:
io_loop.run_sync(coroutine_func)
finally:
server.stop_daide_server(None)
if server.backend.http_server:
server.backend.http_server.stop()
io_loop.stop()
io_loop.clear_current()
io_loop.close()
server = None
Server.__cache__.clear()
def test_game_reject_map():
""" Test a game where the client rejects the map """
_ = Server() # Initialize cache to prevent timeouts during tests
game_path = os.path.join(FILE_FOLDER_NAME, 'game_data_1_reject_map.csv')
run_with_timeout(lambda: run_game_data(1, ['NO_PRESS', 'IGNORE_ERRORS', 'POWER_CHOICE'], game_path), 60)
def test_game_1():
""" Test a complete 1 player game """
_ = Server() # Initialize cache to prevent timeouts during tests
game_path = os.path.join(FILE_FOLDER_NAME, 'game_data_1.csv')
run_with_timeout(lambda: run_game_data(1, ['NO_PRESS', 'IGNORE_ERRORS', 'POWER_CHOICE'], game_path), 60)
def test_game_history():
""" Test a complete 1 player game and validate the full history (except last phase) """
_ = Server() # Initialize cache to prevent timeouts during tests
game_path = os.path.join(FILE_FOLDER_NAME, 'game_data_1_history.csv')
run_with_timeout(lambda: run_game_data(1, ['NO_PRESS', 'IGNORE_ERRORS', 'POWER_CHOICE'], game_path), 60)
def test_game_7():
""" Test a complete 7 players game """
_ = Server() # Initialize cache to prevent timeouts during tests
game_path = os.path.join(FILE_FOLDER_NAME, 'game_data_7.csv')
run_with_timeout(lambda: run_game_data(7, ['NO_PRESS', 'IGNORE_ERRORS', 'POWER_CHOICE'], game_path), 60)
def test_game_7_draw():
""" Test a complete 7 players game that ends with a draw """
_ = Server() # Initialize cache to prevent timeouts during tests
game_path = os.path.join(FILE_FOLDER_NAME, 'game_data_7_draw.csv')
run_with_timeout(lambda: run_game_data(7, ['NO_PRESS', 'IGNORE_ERRORS', 'POWER_CHOICE'], game_path), 60)
def test_game_7_press():
""" Test a complete 7 players game with press """
_ = Server() # Initialize cache to prevent timeouts during tests
game_path = os.path.join(FILE_FOLDER_NAME, 'game_data_7_press.csv')
run_with_timeout(lambda: run_game_data(7, ['IGNORE_ERRORS', 'POWER_CHOICE'], game_path), 60)

View file

@ -0,0 +1,886 @@
# ==============================================================================
# Copyright (C) 2019 - Philip Paquette
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>.
# ==============================================================================
""" Tests for request objects """
from diplomacy.daide import requests, tokens
from diplomacy.daide.requests import RequestBuilder
from diplomacy.daide.utils import str_to_bytes
def test_nme_001():
""" Tests the NME request """
daide_str = 'NME ( A l b e r t ) ( v 6 . 0 . 1 )'
expected_str = 'NME (Albert) (v6.0.1)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.NME), 'Expected a NME request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.client_name == 'Albert'
assert request.client_version == 'v6.0.1'
def test_nme_002():
""" Tests the NME request """
daide_str = 'NME ( J o h n D o e ) ( v 1 . 2 )'
expected_str = 'NME (JohnDoe) (v1.2)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.NME), 'Expected a NME request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.client_name == 'JohnDoe'
assert request.client_version == 'v1.2'
def test_obs():
""" Test the OBS request """
daide_str = 'OBS'
expected_str = 'OBS'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.OBS), 'Expected a OBS request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
def test_iam():
""" Test the IAM request """
daide_str = 'IAM ( FRA ) ( #1234 )'
expected_str = 'IAM (FRA) (1234)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.IAM), 'Expected a IAM request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.power_name == 'FRANCE'
assert request.passcode == '1234'
def test_hlo():
""" Test the HLO request """
daide_str = 'HLO'
expected_str = 'HLO'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.HLO), 'Expected a HLO request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
def test_map():
""" Test the MAP request """
daide_str = 'MAP'
expected_str = 'MAP'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.MAP), 'Expected a MAP request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
def test_mdf():
""" Test the MDF request """
daide_str = 'MDF'
expected_str = 'MDF'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.MDF), 'Expected a MDF request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
def test_sco():
""" Test the SCO request """
daide_str = 'SCO'
expected_str = 'SCO'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SCO), 'Expected a SCO request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
def test_now():
""" Test the NOW request """
daide_str = 'NOW'
expected_str = 'NOW'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.NOW), 'Expected a NOW request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
def test_hst_spr():
""" Tests the HST request """
daide_str = 'HST ( SPR #1901 )'
expected_str = 'HST (SPR 1901)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.HST), 'Expected a HST request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == 'S1901M'
def test_sub_spr_hold():
""" Tests the SUB request """
daide_str = 'SUB ( SPR #1901 ) ( ( ENG AMY LVP ) HLD )'
expected_str = 'SUB (SPR 1901) ((ENG AMY LVP) HLD)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == 'S1901M'
assert request.power_name == 'ENGLAND'
assert request.orders == ['A LVP H']
def test_sub_sum_hold():
""" Tests the SUB request """
daide_str = 'SUB ( SUM #1902 ) ( ( ENG AMY LVP ) HLD )'
expected_str = 'SUB (SUM 1902) ((ENG AMY LVP) HLD)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == 'S1902R'
assert request.power_name == 'ENGLAND'
assert request.orders == ['A LVP H']
def test_sub_fal_hold():
""" Tests the SUB request """
daide_str = 'SUB ( FAL #1903 ) ( ( ENG AMY LVP ) HLD )'
expected_str = 'SUB (FAL 1903) ((ENG AMY LVP) HLD)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == 'F1903M'
assert request.power_name == 'ENGLAND'
assert request.orders == ['A LVP H']
def test_sub_aut_hold():
""" Tests the SUB request """
daide_str = 'SUB ( AUT #1904 ) ( ( ENG AMY LVP ) HLD )'
expected_str = 'SUB (AUT 1904) ((ENG AMY LVP) HLD)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == 'F1904R'
assert request.power_name == 'ENGLAND'
assert request.orders == ['A LVP H']
def test_sub_win_hold():
""" Tests the SUB request """
daide_str = 'SUB ( WIN #1905 ) ( ( ENG AMY LVP ) HLD )'
expected_str = 'SUB (WIN 1905) ((ENG AMY LVP) HLD)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == 'W1905A'
assert request.power_name == 'ENGLAND'
assert request.orders == ['A LVP H']
def test_sub_austria_hold():
""" Tests the SUB request """
daide_str = 'SUB ( ( AUS AMY LVP ) HLD )'
expected_str = 'SUB ((AUS AMY LVP) HLD)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'AUSTRIA'
assert request.orders == ['A LVP H']
def test_sub_english_hold():
""" Tests the SUB request """
daide_str = 'SUB ( ( ENG AMY LVP ) HLD )'
expected_str = 'SUB ((ENG AMY LVP) HLD)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'ENGLAND'
assert request.orders == ['A LVP H']
def test_sub_france_hold():
""" Tests the SUB request """
daide_str = 'SUB ( ( FRA AMY LVP ) HLD )'
expected_str = 'SUB ((FRA AMY LVP) HLD)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'FRANCE'
assert request.orders == ['A LVP H']
def test_sub_germany_hold():
""" Tests the SUB request """
daide_str = 'SUB ( ( GER AMY LVP ) HLD )'
expected_str = 'SUB ((GER AMY LVP) HLD)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'GERMANY'
assert request.orders == ['A LVP H']
def test_sub_italy_hold():
""" Tests the SUB request """
daide_str = 'SUB ( ( ITA AMY LVP ) HLD )'
expected_str = 'SUB ((ITA AMY LVP) HLD)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'ITALY'
assert request.orders == ['A LVP H']
def test_sub_russia_hold():
""" Tests the SUB request """
daide_str = 'SUB ( ( RUS AMY LVP ) HLD )'
expected_str = 'SUB ((RUS AMY LVP) HLD)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'RUSSIA'
assert request.orders == ['A LVP H']
def test_sub_turkey_hold():
""" Tests the SUB request """
daide_str = 'SUB ( ( TUR AMY LVP ) HLD )'
expected_str = 'SUB ((TUR AMY LVP) HLD)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'TURKEY'
assert request.orders == ['A LVP H']
def test_sub_fleet_hold():
""" Tests the SUB request """
daide_str = 'SUB ( ( ENG FLT LVP ) HLD )'
expected_str = 'SUB ((ENG FLT LVP) HLD)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'ENGLAND'
assert request.orders == ['F LVP H']
def test_sub_eng_ech_hold():
""" Tests the SUB request """
daide_str = 'SUB ( ( FRA FLT ECH ) HLD )'
expected_str = 'SUB ((FRA FLT ECH) HLD)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'FRANCE'
assert request.orders == ['F ENG H']
def test_sub_gob_bot_hold():
""" Tests the SUB request """
daide_str = 'SUB ( ( FRA FLT GOB ) HLD )'
expected_str = 'SUB ((FRA FLT GOB) HLD)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'FRANCE'
assert request.orders == ['F BOT H']
def test_sub_gol_lyo_hold():
""" Tests the SUB request """
daide_str = 'SUB ( ( FRA FLT GOL ) HLD )'
expected_str = 'SUB ((FRA FLT GOL) HLD)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'FRANCE'
assert request.orders == ['F LYO H']
def test_sub_move():
""" Tests the SUB request """
daide_str = 'SUB ( ( ENG FLT LON ) MTO NTH )'
expected_str = 'SUB ((ENG FLT LON) MTO NTH)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'ENGLAND'
assert request.orders == ['F LON - NTH']
def test_sub_move_coast():
""" Tests the SUB request """
daide_str = 'SUB ( ( ENG FLT BAR ) MTO ( STP NCS ) )'
expected_str = 'SUB ((ENG FLT BAR) MTO (STP NCS))'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'ENGLAND'
assert request.orders == ['F BAR - STP/NC']
def test_sub_support_hold_001():
""" Tests the SUB request """
daide_str = 'SUB ( ( ENG FLT EDI ) SUP ( ENG FLT LON ) )'
expected_str = 'SUB ((ENG FLT EDI) SUP (ENG FLT LON))'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'ENGLAND'
assert request.orders == ['F EDI S F LON']
def test_sub_support_hold_002():
""" Tests the SUB request """
daide_str = 'SUB ( ( ENG FLT NWY ) SUP ( ENG FLT BAR ) )'
expected_str = 'SUB ((ENG FLT NWY) SUP (ENG FLT BAR))'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'ENGLAND'
assert request.orders == ['F NWY S F BAR']
def test_sub_support_hold_003():
""" Tests the SUB request """
daide_str = 'SUB ( ( ENG FLT NWG ) SUP ( ENG AMY YOR ) )'
expected_str = 'SUB ((ENG FLT NWG) SUP (ENG AMY YOR))'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'ENGLAND'
assert request.orders == ['F NWG S A YOR']
def test_sub_support_move_001():
""" Tests the SUB request """
daide_str = 'SUB ( ( ENG FLT EDI ) SUP ( ENG FLT LON ) MTO NTH )'
expected_str = 'SUB ((ENG FLT EDI) SUP (ENG FLT LON) MTO NTH)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'ENGLAND'
assert request.orders == ['F EDI S F LON - NTH']
def test_sub_support_move_002():
""" Tests the SUB request """
daide_str = 'SUB ( ( ENG FLT NWY ) SUP ( ENG FLT BAR ) MTO STP )'
expected_str = 'SUB ((ENG FLT NWY) SUP (ENG FLT BAR) MTO STP)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'ENGLAND'
assert request.orders == ['F NWY S F BAR - STP']
def test_sub_support_move_003():
""" Tests the SUB request """
daide_str = 'SUB ( ( ENG FLT NWG ) SUP ( ENG AMY YOR ) MTO NWY )'
expected_str = 'SUB ((ENG FLT NWG) SUP (ENG AMY YOR) MTO NWY)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'ENGLAND'
assert request.orders == ['F NWG S A YOR - NWY']
def test_sub_move_via_001():
""" Tests the SUB request """
daide_str = 'SUB ( ( ITA AMY TUN ) CTO SYR VIA ( ION EAS ) )'
expected_str = 'SUB ((ITA AMY TUN) CTO SYR VIA (ION EAS))'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'ITALY'
assert request.orders == ['A TUN - SYR VIA']
def test_sub_move_via_002():
""" Tests the SUB request """
daide_str = 'SUB ( ( ENG AMY YOR ) CTO NWY VIA ( NTH ) )'
expected_str = 'SUB ((ENG AMY YOR) CTO NWY VIA (NTH))'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'ENGLAND'
assert request.orders == ['A YOR - NWY VIA']
def test_sub_convoy_001():
""" Tests the SUB request """
daide_str = 'SUB ( ( ITA FLT ION ) CVY ( ITA AMY TUN ) CTO SYR )'
expected_str = 'SUB ((ITA FLT ION) CVY (ITA AMY TUN) CTO SYR)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'ITALY'
assert request.orders == ['F ION C A TUN - SYR']
def test_sub_convoy_002():
""" Tests the SUB request """
daide_str = 'SUB ( ( ITA FLT EAS ) CVY ( ITA AMY TUN ) CTO SYR )'
expected_str = 'SUB ((ITA FLT EAS) CVY (ITA AMY TUN) CTO SYR)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'ITALY'
assert request.orders == ['F EAS C A TUN - SYR']
def test_sub_convoy_003():
""" Tests the SUB request """
daide_str = 'SUB ( ( ENG FLT NTH ) CVY ( ENG AMY YOR ) CTO STP )'
expected_str = 'SUB ((ENG FLT NTH) CVY (ENG AMY YOR) CTO STP)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'ENGLAND'
assert request.orders == ['F NTH C A YOR - STP']
def test_sub_retreat():
""" Tests the SUB request """
daide_str = 'SUB ( ( ENG FLT LON ) RTO NTH )'
expected_str = 'SUB ((ENG FLT LON) RTO NTH)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'ENGLAND'
assert request.orders == ['F LON R NTH']
def test_sub_retreat_coast():
""" Tests the SUB request """
daide_str = 'SUB ( ( ENG FLT LON ) RTO ( STP NCS ) )'
expected_str = 'SUB ((ENG FLT LON) RTO (STP NCS))'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'ENGLAND'
assert request.orders == ['F LON R STP/NC']
def test_sub_disband():
""" Tests the SUB request """
daide_str = 'SUB ( ( RUS FLT GOB ) DSB )'
expected_str = 'SUB ((RUS FLT GOB) DSB)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'RUSSIA'
assert request.orders == ['F BOT D']
def test_sub_build():
""" Tests the SUB request """
daide_str = 'SUB ( ( ITA FLT NAP ) BLD )'
expected_str = 'SUB ((ITA FLT NAP) BLD)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'ITALY'
assert request.orders == ['F NAP B']
def test_sub_remove():
""" Tests the SUB request """
daide_str = 'SUB ( ( RUS FLT GOB ) REM )'
expected_str = 'SUB ((RUS FLT GOB) REM)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'RUSSIA'
assert request.orders == ['F BOT D']
def test_sub_waive():
""" Tests the SUB request """
daide_str = 'SUB ( ENG WVE )'
expected_str = 'SUB (ENG WVE)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'ENGLAND'
assert request.orders == ['WAIVE']
def test_sub_multi_001():
""" Tests the SUB request """
daide_str = 'SUB ( ( ENG AMY LVP ) HLD ) ' \
'( ( ENG FLT LON ) MTO NTH ) ' \
'( ( ENG FLT EDI ) SUP ( ENG FLT LON ) MTO NTH )'
expected_str = 'SUB ((ENG AMY LVP) HLD) ' \
'((ENG FLT LON) MTO NTH) ' \
'((ENG FLT EDI) SUP (ENG FLT LON) MTO NTH)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'ENGLAND'
assert request.orders == ['A LVP H', 'F LON - NTH', 'F EDI S F LON - NTH']
def test_sub_multi_002():
""" Tests the SUB request """
daide_str = 'SUB ( ( ENG FLT BAR ) MTO ( STP NCS ) ) ' \
'( ( ITA FLT NWY ) SUP ( ENG FLT BAR ) MTO STP )'
expected_str = 'SUB ((ENG FLT BAR) MTO (STP NCS)) ' \
'((ITA FLT NWY) SUP (ENG FLT BAR) MTO STP)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'ENGLAND'
assert request.orders == ['F BAR - STP/NC', 'F NWY S F BAR - STP']
def test_sub_multi_003():
""" Tests the SUB request """
daide_str = 'SUB ( ( ITA AMY TUN ) CTO SYR VIA ( ION EAS ) ) ' \
'( ( ITA FLT ION ) CVY ( ITA AMY TUN ) CTO SYR ) ' \
'( ( ITA FLT EAS ) CVY ( ITA AMY TUN ) CTO SYR )'
expected_str = 'SUB ((ITA AMY TUN) CTO SYR VIA (ION EAS)) ' \
'((ITA FLT ION) CVY (ITA AMY TUN) CTO SYR) ' \
'((ITA FLT EAS) CVY (ITA AMY TUN) CTO SYR)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'ITALY'
assert request.orders == ['A TUN - SYR VIA', 'F ION C A TUN - SYR', 'F EAS C A TUN - SYR']
def test_sub_multi_004():
""" Tests the SUB request """
daide_str = 'SUB ( ( ENG AMY YOR ) CTO NWY VIA ( NTH ) ) ' \
'( ( ENG FLT NTH ) CVY ( ENG AMY YOR ) CTO NWY ) ' \
'( ( ENG FLT NWG ) SUP ( ENG AMY YOR ) MTO NWY )'
expected_str = 'SUB ((ENG AMY YOR) CTO NWY VIA (NTH)) ' \
'((ENG FLT NTH) CVY (ENG AMY YOR) CTO NWY) ' \
'((ENG FLT NWG) SUP (ENG AMY YOR) MTO NWY)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SUB), 'Expected a SUB request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.power_name == 'ENGLAND'
assert request.orders == ['A YOR - NWY VIA', 'F NTH C A YOR - NWY', 'F NWG S A YOR - NWY']
def test_mis():
""" Test the MIS request """
daide_str = 'MIS'
expected_str = 'MIS'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.MIS), 'Expected a MIS request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
def test_gof():
""" Test the GOF request """
daide_str = 'GOF'
expected_str = 'GOF'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.GOF), 'Expected a GOF request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
def test_tme():
""" Tests the TME request """
daide_str = 'TME'
expected_str = 'TME'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.TME), 'Expected a TME request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.seconds is None
def test_tme_sec():
""" Tests the TME request """
daide_str = 'TME ( #60 )'
expected_str = 'TME (60)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.TME), 'Expected a TME request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.seconds == 60
def test_drw_001():
""" Test the DRW request """
daide_str = 'DRW'
expected_str = 'DRW'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.DRW), 'Expected a DRW request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.powers == []
def test_drw_002():
""" Test the DRW request """
daide_str = 'DRW ( FRA ENG ITA )'
expected_str = 'DRW (FRA ENG ITA)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.DRW), 'Expected a DRW request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.powers == ['FRANCE', 'ENGLAND', 'ITALY']
def test_snd_001():
""" Tests the SND request """
daide_str = 'SND ( FRA ENG ) ( PRP ( PCE ( FRA ENG GER ) ) )'
expected_str = 'SND (FRA ENG) (PRP (PCE (FRA ENG GER)))'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SND), 'Expected a SND request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.powers == ['FRANCE', 'ENGLAND']
assert request.message_bytes == str_to_bytes('PRP ( PCE ( FRA ENG GER ) )')
def test_snd_002():
""" Tests the SND request """
daide_str = 'SND ( SPR #1901 ) ( FRA ENG ) ( PRP ( PCE ( FRA ENG GER ) ) )'
expected_str = 'SND (SPR 1901) (FRA ENG) (PRP (PCE (FRA ENG GER)))'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SND), 'Expected a SND request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == 'S1901M'
assert request.powers == ['FRANCE', 'ENGLAND']
assert request.message_bytes == str_to_bytes('PRP ( PCE ( FRA ENG GER ) )')
def test_snd_003():
""" Tests the SND request """
daide_str = 'SND ( FRA ENG ) ( CCL ( PRP ( PCE ( FRA ENG GER ) ) ) )'
expected_str = 'SND (FRA ENG) (CCL (PRP (PCE (FRA ENG GER))))'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SND), 'Expected a SND request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.powers == ['FRANCE', 'ENGLAND']
assert request.message_bytes == str_to_bytes('CCL ( PRP ( PCE ( FRA ENG GER ) ) )')
def test_snd_004():
""" Tests the SND request """
daide_str = 'SND ( FRA ENG ) ( FCT ( PCE ( FRA ENG GER ) ) )'
expected_str = 'SND (FRA ENG) (FCT (PCE (FRA ENG GER)))'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SND), 'Expected a SND request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.powers == ['FRANCE', 'ENGLAND']
assert request.message_bytes == str_to_bytes('FCT ( PCE ( FRA ENG GER ) )')
def test_snd_005():
""" Tests the SND request """
daide_str = 'SND ( FRA ENG ) ( TRY ( PRP PCE ALY VSS DRW SLO NOT YES REJ BWX ) )'
expected_str = 'SND (FRA ENG) (TRY (PRP PCE ALY VSS DRW SLO NOT YES REJ BWX))'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SND), 'Expected a SND request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.powers == ['FRANCE', 'ENGLAND']
assert request.message_bytes == str_to_bytes('TRY ( PRP PCE ALY VSS DRW SLO NOT YES REJ BWX )')
def test_snd_006():
""" Tests the SND request """
daide_str = 'SND ( FRA GER ) ( YES ( PRP ( ALY ( FRA ENG GER ) VSS ( ITA ) ) ) )'
expected_str = 'SND (FRA GER) (YES (PRP (ALY (FRA ENG GER) VSS (ITA))))'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SND), 'Expected a SND request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.powers == ['FRANCE', 'GERMANY']
assert request.message_bytes == str_to_bytes('YES ( PRP ( ALY ( FRA ENG GER ) VSS ( ITA ) ) )')
def test_snd_007():
""" Tests the SND request """
daide_str = 'SND ( FRA GER ) ( REJ ( PRP ( ALY ( FRA ENG GER ) VSS ( ITA ) ) ) )'
expected_str = 'SND (FRA GER) (REJ (PRP (ALY (FRA ENG GER) VSS (ITA))))'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SND), 'Expected a SND request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.powers == ['FRANCE', 'GERMANY']
assert request.message_bytes == str_to_bytes('REJ ( PRP ( ALY ( FRA ENG GER ) VSS ( ITA ) ) )')
def test_snd_008():
""" Tests the SND request """
daide_str = 'SND ( FRA GER ) ( BWX ( PRP ( ALY ( FRA ENG GER ) VSS ( ITA ) ) ) )'
expected_str = 'SND (FRA GER) (BWX (PRP (ALY (FRA ENG GER) VSS (ITA))))'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SND), 'Expected a SND request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.powers == ['FRANCE', 'GERMANY']
assert request.message_bytes == str_to_bytes('BWX ( PRP ( ALY ( FRA ENG GER ) VSS ( ITA ) ) )')
def test_snd_009():
""" Tests the SND request """
daide_str = 'SND ( FRA GER ) ( HUH ( ERR PRP ( ALY ( FRA ENG GER ) VSS ( ITA ) ) ) )'
expected_str = 'SND (FRA GER) (HUH (ERR PRP (ALY (FRA ENG GER) VSS (ITA))))'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.SND), 'Expected a SND request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.phase == ''
assert request.powers == ['FRANCE', 'GERMANY']
assert request.message_bytes == str_to_bytes('HUH ( ERR PRP ( ALY ( FRA ENG GER ) VSS ( ITA ) ) )')
def test_not_sub():
""" Tests the NOT request """
daide_str = 'NOT ( SUB )'
expected_str = 'NOT (SUB)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.NOT), 'Expected a NOT request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert isinstance(request.request, requests.SUB), 'Expected a SUB not request'
def test_not_sub_orders():
""" Tests the NOT request """
daide_str = 'NOT ( SUB ( ( ENG AMY YOR ) CTO NWY VIA ( NTH ) ) ' \
'( ( ENG FLT NTH ) CVY ( ENG AMY YOR ) CTO NWY ) ' \
'( ( ENG FLT NWG ) SUP ( ENG AMY YOR ) MTO NWY ) )'
expected_str = 'NOT (SUB ((ENG AMY YOR) CTO NWY VIA (NTH)) ' \
'((ENG FLT NTH) CVY (ENG AMY YOR) CTO NWY) ' \
'((ENG FLT NWG) SUP (ENG AMY YOR) MTO NWY))'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.NOT), 'Expected a NOT request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert isinstance(request.request, requests.SUB), 'Expected a SUB not request'
def test_not_gof():
""" Tests the NOT request """
daide_str = 'NOT ( GOF )'
expected_str = 'NOT (GOF)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.NOT), 'Expected a NOT request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert isinstance(request.request, requests.GOF), 'Expected a GOF not request'
def test_not_tme():
""" Tests the NOT request """
daide_str = 'NOT ( TME )'
expected_str = 'NOT (TME)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.NOT), 'Expected a NOT request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert isinstance(request.request, requests.TME), 'Expected a TME not request'
def test_not_tme_sec():
""" Tests the NOT request """
daide_str = 'NOT ( TME ( #60 ) )'
expected_str = 'NOT (TME (60))'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.NOT), 'Expected a NOT request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert isinstance(request.request, requests.TME), 'Expected a TME not request'
def test_not_drw():
""" Tests the NOT request """
daide_str = 'NOT ( DRW )'
expected_str = 'NOT (DRW)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.NOT), 'Expected a NOT request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert isinstance(request.request, requests.DRW), 'Expected a DRW not request'
def test_yes():
""" Tests the YES request """
daide_str = 'YES ( MAP ( s t a n d a r d ) )'
expected_str = 'YES (MAP (standard))'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.YES), 'Expected a YES request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert tokens.Token(from_bytes=request.response_bytes[:2]) == tokens.MAP
def test_rej():
""" Tests the REJ request """
daide_str = 'REJ ( SVE ( g a m e n a m e ) )'
expected_str = 'REJ (SVE (gamename))'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.REJ), 'Expected a REJ request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert tokens.Token(from_bytes=request.response_bytes[:2]) == tokens.SVE
def test_prn_sub():
""" Tests the PRN request """
daide_str = 'PRN ( SUB ( ( ENG AMY LVP ) HLD ) ' \
'( ( ENG FLT LON ) MTO NTH ) ' \
'( ( ENG FLT EDI ) SUP ( ENG FLT LON ) MTO NTH )'
request_message_daide_str = 'SUB ( ( ENG AMY LVP ) HLD ) ' \
'( ( ENG FLT LON ) MTO NTH ) ' \
'( ( ENG FLT EDI ) SUP ( ENG FLT LON ) MTO NTH'
expected_str = 'PRN (SUB ((ENG AMY LVP) HLD) ' \
'((ENG FLT LON) MTO NTH) ' \
'((ENG FLT EDI) SUP (ENG FLT LON) MTO NTH)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.PRN), 'Expected a PRN request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.message_bytes == str_to_bytes(request_message_daide_str)
def test_huh_sub():
""" Tests the HUH request """
daide_str = 'HUH ( )'
expected_str = 'HUH ()'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.HUH), 'Expected a HUH request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.message_bytes == b''
def test_adm():
""" Tests the ADM request """
daide_str = 'ADM ( I \' m h a v i n g c o n n e c t i o n p r o b l e m s )'
expected_str = 'ADM (I\'m having connection problems)'
request = RequestBuilder.from_bytes(str_to_bytes(daide_str))
assert isinstance(request, requests.ADM), 'Expected a ADM request'
assert bytes(request) == str_to_bytes(daide_str)
assert str(request) == expected_str
assert request.adm_message == 'I\'m having connection problems'

View file

@ -0,0 +1,339 @@
# ==============================================================================
# Copyright (C) 2019 - Philip Paquette
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>.
# ==============================================================================
""" Tests for request objects """
from diplomacy import Game
from diplomacy.daide import responses
from diplomacy.daide.utils import str_to_bytes
import diplomacy.utils.errors as err
from diplomacy.utils.order_results import OK, BOUNCE, DISLODGED
def test_map():
""" Tests the MAP response """
daide_str = 'MAP ( s t a n d a r d )'
response = responses.MAP('standard')
assert isinstance(response, responses.MAP), 'Expected a MAP response'
assert bytes(response) == str_to_bytes(daide_str)
def test_hlo():
""" Tests the HLO response """
daide_str = 'HLO ( FRA ) ( #1234 ) ( ( LVL #0 ) ( MTL #1200 ) ( RTL #1200 ) ( BTL #1200 ) ( AOA ) )'
response = responses.HLO('FRANCE', 1234, 0, 1200, ['NO_CHECK'])
assert isinstance(response, responses.HLO), 'Expected a HLO response'
assert bytes(response) == str_to_bytes(daide_str)
def test_hlo_no_deadline():
""" Tests the HLO response """
daide_str = 'HLO ( FRA ) ( #1234 ) ( ( LVL #0 ) ( AOA ) )'
response = responses.HLO('FRANCE', 1234, 0, 0, ['NO_CHECK'])
assert isinstance(response, responses.HLO), 'Expected a HLO response'
assert bytes(response) == str_to_bytes(daide_str)
def test_sco():
""" Tests the SCO response """
daide_str = 'SCO ( AUS BUD TRI VIE ) ( ENG EDI LON LVP ) ( FRA BRE MAR PAR ) ' \
'( GER BER KIE MUN ) ( ITA NAP ROM VEN ) ( RUS MOS SEV STP WAR ) ' \
'( TUR ANK CON SMY ) ( UNO BEL BUL DEN GRE HOL NWY POR RUM SER SPA SWE TUN )'
game = Game(map_name='standard')
power_centers = {power.name: power.centers for power in game.powers.values()}
response = responses.SCO(power_centers, map_name='standard')
assert isinstance(response, responses.SCO), 'Expected a SCO response'
assert bytes(response) == str_to_bytes(daide_str)
def test_now():
""" Tests the NOW response """
daide_str = 'NOW ( SPR #1901 ) ( AUS AMY BUD ) ( AUS AMY VIE ) ( AUS FLT TRI ) ( ENG FLT EDI )' \
' ( ENG FLT LON ) ( ENG AMY LVP ) ( FRA FLT BRE ) ( FRA AMY MAR ) ( FRA AMY PAR )' \
' ( GER FLT KIE ) ( GER AMY BER ) ( GER AMY MUN ) ( ITA FLT NAP ) ( ITA AMY ROM )' \
' ( ITA AMY VEN ) ( RUS AMY WAR ) ( RUS AMY MOS ) ( RUS FLT SEV )' \
' ( RUS FLT ( STP SCS ) ) ( TUR FLT ANK ) ( TUR AMY CON ) ( TUR AMY SMY )'
game = Game(map_name='standard')
phase_name = game.get_current_phase()
units = {power.name: power.units for power in game.powers.values()}
retreats = {power.name: power.retreats for power in game.powers.values()}
response = responses.NOW(phase_name=phase_name, powers_units=units, powers_retreats=retreats)
assert isinstance(response, responses.NOW), 'Expected a NOW response'
assert bytes(response) == str_to_bytes(daide_str)
def test_thx_001():
""" Tests the THX response """
daide_str = 'THX ( ( ENG FLT NWG ) SUP ( ENG AMY YOR ) MTO NWY ) ( MBV )'
order_daide_str = '( ( ENG FLT NWG ) SUP ( ENG AMY YOR ) MTO NWY )'
response = responses.THX(order_bytes=str_to_bytes(order_daide_str), results=[])
assert isinstance(response, responses.THX), 'Expected a THX response'
assert bytes(response) == str_to_bytes(daide_str)
def test_thx_002():
""" Tests the THX response """
daide_str = 'THX ( ( ENG FLT NWG ) SUP ( ENG AMY YOR ) MTO NWY ) ( NYU )'
order_daide_str = '( ( ENG FLT NWG ) SUP ( ENG AMY YOR ) MTO NWY )'
response = responses.THX(order_bytes=str_to_bytes(order_daide_str),
results=[error.code for error in [err.GAME_ORDER_TO_FOREIGN_UNIT % 'A MAR']])
assert isinstance(response, responses.THX), 'Expected a THX response'
assert bytes(response) == str_to_bytes(daide_str)
def test_thx_003():
""" Tests the THX response """
daide_str = 'THX ( ( ENG FLT NWG ) SUP ( ENG AMY YOR ) MTO NWY ) ( MBV )'
order_daide_str = '( ( ENG FLT NWG ) SUP ( ENG AMY YOR ) MTO NWY )'
response = responses.THX(order_bytes=str_to_bytes(order_daide_str),
results=[error.code for error in [OK, err.MAP_LEAST_TWO_POWERS]])
assert isinstance(response, responses.THX), 'Expected a THX response'
assert bytes(response) == str_to_bytes(daide_str)
def test_mis_001():
""" Tests the MIS response """
daide_str = 'MIS ( FRA FLT BRE ) ( FRA AMY MAR ) ( FRA AMY PAR )'
game = Game(map_name='standard')
phase_name = 'S1901M'
power = game.get_power('FRANCE')
response = responses.MIS(phase_name=phase_name, power=power)
assert isinstance(response, responses.MIS), 'Expected a MIS response'
assert bytes(response) == str_to_bytes(daide_str)
def test_mis_002():
""" Tests the MIS response """
daide_str = 'MIS ( TUR FLT ANK MRT ( ARM ) ) ' \
'( TUR FLT CON MRT ( BLA SMY ( BUL ECS ) ( BUL SCS ) ) ) ' \
'( TUR AMY SMY MRT ( SYR ) )'
game = Game(map_name='standard')
phase_name = 'S1901R'
power = game.get_power('TURKEY')
power.units = ['F ANK', 'F CON', 'A SMY']
power.retreats['F ANK'] = ['ARM']
power.retreats['F CON'] = ['BLA', 'SMY', 'BUL/EC', 'BUL/SC']
power.retreats['A SMY'] = ['SYR']
response = responses.MIS(phase_name=phase_name, power=power)
assert isinstance(response, responses.MIS), 'Expected a MIS response'
assert bytes(response) == str_to_bytes(daide_str)
def test_mis_003():
""" Tests the MIS response """
daide_str = 'MIS ( #0 )'
game = Game(map_name='standard')
phase_name = 'W1901A'
power = game.get_power('FRANCE')
response = responses.MIS(phase_name=phase_name, power=power)
assert isinstance(response, responses.MIS), 'Expected a MIS response'
assert bytes(response) == str_to_bytes(daide_str)
def test_mis_004():
""" Tests the MIS response """
daide_str = 'MIS ( #1 )'
game = Game(map_name='standard')
phase_name = 'W1901A'
power = game.get_power('FRANCE')
power.centers = power.centers[:-1]
response = responses.MIS(phase_name=phase_name, power=power)
assert isinstance(response, responses.MIS), 'Expected a MIS response'
assert bytes(response) == str_to_bytes(daide_str)
def test_mis_005():
""" Tests the MIS response """
daide_str = 'MIS ( #-1 )'
game = Game(map_name='standard')
phase_name = 'W1901A'
power = game.get_power('FRANCE')
power.units = power.units[:-1]
response = responses.MIS(phase_name=phase_name, power=power)
assert isinstance(response, responses.MIS), 'Expected a MIS response'
assert bytes(response) == str_to_bytes(daide_str)
def test_mis_006():
""" Tests the MIS response """
daide_str = 'MIS ( #1 )'
game = Game(map_name='standard')
phase_name = 'W1901A'
power = game.get_power('FRANCE')
power.units = power.units + ['F LON']
response = responses.MIS(phase_name=phase_name, power=power)
assert isinstance(response, responses.MIS), 'Expected a MIS response'
assert bytes(response) == str_to_bytes(daide_str)
def test_mis_007():
""" Tests the MIS response """
daide_str = 'MIS ( FRA FLT BRE ) ( FRA AMY MAR )'
game = Game(map_name='standard')
game.set_orders('FRANCE', ['A PAR - BUR'])
phase_name = 'S1901M'
power = game.get_power('FRANCE')
response = responses.MIS(phase_name=phase_name, power=power)
assert isinstance(response, responses.MIS), 'Expected a MIS response'
assert bytes(response) == str_to_bytes(daide_str)
def test_mis_008():
""" Tests the MIS response """
daide_str = 'MIS ( FRA FLT BRE ) ( FRA AMY MAR )'
game = Game(map_name='standard')
game.add_rule('NO_CHECK')
game.set_orders('FRANCE', ['A PAR - BUR'])
phase_name = 'S1901M'
power = game.get_power('FRANCE')
response = responses.MIS(phase_name=phase_name, power=power)
assert isinstance(response, responses.MIS), 'Expected a MIS response'
assert bytes(response) == str_to_bytes(daide_str)
def test_mis_009():
""" Tests the MIS response """
daide_str = 'MIS ( FRA FLT BRE ) ( FRA AMY MAR )'
game = Game(map_name='standard')
phase_name = 'S1901M'
power = game.get_power('FRANCE')
power.orders['REORDER 1'] = 'A PAR - BUR'
response = responses.MIS(phase_name=phase_name, power=power)
assert isinstance(response, responses.MIS), 'Expected a MIS response'
assert bytes(response) == str_to_bytes(daide_str)
def test_mis_010():
""" Tests the MIS response """
daide_str = 'MIS ( FRA FLT BRE ) ( FRA AMY MAR )'
game = Game(map_name='standard')
phase_name = 'S1901M'
power = game.get_power('FRANCE')
power.orders['INVALID'] = 'A PAR - BUR'
response = responses.MIS(phase_name=phase_name, power=power)
assert isinstance(response, responses.MIS), 'Expected a MIS response'
assert bytes(response) == str_to_bytes(daide_str)
def test_mis_011():
""" Tests the MIS response """
daide_str = 'MIS ( #0 )'
game = Game(map_name='standard')
phase_name = 'W1901A'
power = game.get_power('FRANCE')
power.centers += ['LON']
response = responses.MIS(phase_name=phase_name, power=power)
assert isinstance(response, responses.MIS), 'Expected a MIS response'
assert bytes(response) == str_to_bytes(daide_str)
def test_mis_012():
""" Tests the MIS response """
daide_str = 'MIS ( #-1 )'
game = Game(map_name='standard')
phase_name = 'W1901A'
power = game.get_power('FRANCE')
power.centers += ['LON']
power.units = power.units[:2]
response = responses.MIS(phase_name=phase_name, power=power)
assert isinstance(response, responses.MIS), 'Expected a MIS response'
assert bytes(response) == str_to_bytes(daide_str)
def test_ord_001():
""" Tests the ORD response """
daide_str = 'ORD ( SPR #1901 ) ( ( ENG FLT NWG ) SUP ( ENG AMY YOR ) MTO NWY ) ( SUC )'
order_daide_str = '( ENG FLT NWG ) SUP ( ENG AMY YOR ) MTO NWY'
game = Game(map_name='standard')
phase_name = game.map.phase_abbr(game.phase)
response = responses.ORD(phase_name=phase_name, order_bytes=str_to_bytes(order_daide_str), results=[])
assert isinstance(response, responses.ORD), 'Expected a ORD response'
assert bytes(response) == str_to_bytes(daide_str)
def test_ord_002():
""" Tests the ORD response """
daide_str = 'ORD ( SPR #1901 ) ( ( ENG FLT NWG ) SUP ( ENG AMY YOR ) MTO NWY ) ( NSO )'
order_daide_str = '( ENG FLT NWG ) SUP ( ENG AMY YOR ) MTO NWY'
game = Game(map_name='standard')
phase_name = game.map.phase_abbr(game.phase)
response = responses.ORD(phase_name=phase_name, order_bytes=str_to_bytes(order_daide_str),
results=[BOUNCE.code])
assert isinstance(response, responses.ORD), 'Expected a ORD response'
assert bytes(response) == str_to_bytes(daide_str)
def test_ord_003():
""" Tests the ORD response """
daide_str = 'ORD ( SPR #1901 ) ( ( ENG FLT NWG ) SUP ( ENG AMY YOR ) MTO NWY ) ( NSO )'
order_daide_str = '( ENG FLT NWG ) SUP ( ENG AMY YOR ) MTO NWY'
game = Game(map_name='standard')
phase_name = game.map.phase_abbr(game.phase)
response = responses.ORD(phase_name=phase_name, order_bytes=str_to_bytes(order_daide_str),
results=[DISLODGED])
assert isinstance(response, responses.ORD), 'Expected a ORD response'
assert bytes(response) == str_to_bytes(daide_str)
def test_ord_004():
""" Tests the ORD response """
daide_str = 'ORD ( SPR #1901 ) ( ( ENG FLT NWG ) SUP ( ENG AMY YOR ) MTO NWY ) ( NSO )'
order_daide_str = '( ENG FLT NWG ) SUP ( ENG AMY YOR ) MTO NWY'
game = Game(map_name='standard')
phase_name = game.map.phase_abbr(game.phase)
response = responses.ORD(phase_name=phase_name, order_bytes=str_to_bytes(order_daide_str),
results=[BOUNCE.code, DISLODGED])
assert isinstance(response, responses.ORD), 'Expected a ORD response'
assert bytes(response) == str_to_bytes(daide_str)
def test_tme():
""" Tests the TME response """
daide_str = 'TME ( #60 )'
response = responses.TME(seconds=60)
assert isinstance(response, responses.TME), 'Expected a TME response'
assert bytes(response) == str_to_bytes(daide_str)
def test_yes():
""" Tests the YES response """
daide_str = 'YES ( TME ( #60 ) )'
request_daide_str = 'TME ( #60 )'
response = responses.YES(request_bytes=str_to_bytes(request_daide_str))
assert isinstance(response, responses.YES), 'Expected a YES response'
assert bytes(response) == str_to_bytes(daide_str)
def test_rej():
""" Tests the REJ response """
daide_str = 'REJ ( TME ( #60 ) )'
request_daide_str = 'TME ( #60 )'
response = responses.REJ(request_bytes=str_to_bytes(request_daide_str))
assert isinstance(response, responses.REJ), 'Expected a REJ response'
assert bytes(response) == str_to_bytes(daide_str)
def test_not():
""" Tests the NOT response """
daide_str = 'NOT ( CCD ( FRA ) )'
response_daide_str = 'CCD ( FRA )'
response = responses.NOT(response_bytes=str_to_bytes(response_daide_str))
assert isinstance(response, responses.NOT), 'Expected a NOT response'
assert bytes(response) == str_to_bytes(daide_str)
def test_ccd():
""" Tests the CCD response """
daide_str = 'CCD ( AUS )'
response = responses.CCD(power_name='AUSTRIA')
assert isinstance(response, responses.CCD), 'Expected a CCD response'
assert bytes(response) == str_to_bytes(daide_str)
def test_out():
""" Tests the OUT response """
daide_str = 'OUT ( AUS )'
response = responses.OUT(power_name='AUSTRIA')
assert isinstance(response, responses.OUT), 'Expected a OUT response'
assert bytes(response) == str_to_bytes(daide_str)
def test_prn():
""" Tests the PRN response """
daide_str = 'PRN ( SUB ( ( ENG AMY LVP ) HLD ) ' \
'( ( ENG FLT LON ) MTO NTH ) ' \
'( ( ENG FLT EDI ) SUP ( ENG FLT LON ) MTO NTH )'
request_daide_str = 'SUB ( ( ENG AMY LVP ) HLD ) ' \
'( ( ENG FLT LON ) MTO NTH ) ' \
'( ( ENG FLT EDI ) SUP ( ENG FLT LON ) MTO NTH'
response = responses.PRN(request_bytes=str_to_bytes(request_daide_str))
assert isinstance(response, responses.PRN), 'Expected a PRN response'
assert bytes(response) == str_to_bytes(daide_str)
def test_huh():
""" Tests the HUH response """
daide_str = 'HUH ( ERR )'
response = responses.HUH(b'', 0)
assert isinstance(response, responses.HUH), 'Expected a HUH response'
assert bytes(response) == str_to_bytes(daide_str)

View file

@ -0,0 +1,268 @@
# ==============================================================================
# Copyright (C) 2019 - Philip Paquette
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>.
# ==============================================================================
""" Tests the DAIDE tokens"""
from enum import Enum
from diplomacy.daide.tokens import Token
class ExpectedTokens(Enum):
""" Copy of the tokens definition from aiclient/adjudicator/TOKENS.h """
# Source: http://www.ellought.demon.co.uk/dipai/aiclient.zip
# Powers
TOKEN_POWER_AUS = 0x4100
TOKEN_POWER_ENG = 0x4101
TOKEN_POWER_FRA = 0x4102
TOKEN_POWER_GER = 0x4103
TOKEN_POWER_ITA = 0x4104
TOKEN_POWER_RUS = 0x4105
TOKEN_POWER_TUR = 0x4106
# Units
TOKEN_UNIT_AMY = 0x4200
TOKEN_UNIT_FLT = 0x4201
# Orders
TOKEN_ORDER_CTO = 0x4320
TOKEN_ORDER_CVY = 0x4321
TOKEN_ORDER_HLD = 0x4322
TOKEN_ORDER_MTO = 0x4323
TOKEN_ORDER_SUP = 0x4324
TOKEN_ORDER_VIA = 0x4325
TOKEN_ORDER_DSB = 0x4340
TOKEN_ORDER_RTO = 0x4341
TOKEN_ORDER_BLD = 0x4380
TOKEN_ORDER_REM = 0x4381
TOKEN_ORDER_WVE = 0x4382
# Order Note
TOKEN_ORDER_NOTE_MBV = 0x4400
TOKEN_ORDER_NOTE_BPR = 0x4401
TOKEN_ORDER_NOTE_CST = 0x4402
TOKEN_ORDER_NOTE_ESC = 0x4403
TOKEN_ORDER_NOTE_FAR = 0x4404
TOKEN_ORDER_NOTE_HSC = 0x4405
TOKEN_ORDER_NOTE_NAS = 0x4406
TOKEN_ORDER_NOTE_NMB = 0x4407
TOKEN_ORDER_NOTE_NMR = 0x4408
TOKEN_ORDER_NOTE_NRN = 0x4409
TOKEN_ORDER_NOTE_NRS = 0x440A
TOKEN_ORDER_NOTE_NSA = 0x440B
TOKEN_ORDER_NOTE_NSC = 0x440C
TOKEN_ORDER_NOTE_NSF = 0x440D
TOKEN_ORDER_NOTE_NSP = 0x440E
TOKEN_ORDER_NOTE_NSU = 0x4410
TOKEN_ORDER_NOTE_NVR = 0x4411
TOKEN_ORDER_NOTE_NYU = 0x4412
TOKEN_ORDER_NOTE_YSC = 0x4413
# Results
TOKEN_RESULT_SUC = 0x4500
TOKEN_RESULT_BNC = 0x4501
TOKEN_RESULT_CUT = 0x4502
TOKEN_RESULT_DSR = 0x4503
TOKEN_RESULT_FLD = 0x4504
TOKEN_RESULT_NSO = 0x4505
TOKEN_RESULT_RET = 0x4506
# Coasts
TOKEN_COAST_NCS = 0x4600
TOKEN_COAST_NEC = 0x4602
TOKEN_COAST_ECS = 0x4604
TOKEN_COAST_SEC = 0x4606
TOKEN_COAST_SCS = 0x4608
TOKEN_COAST_SWC = 0x460A
TOKEN_COAST_WCS = 0x460C
TOKEN_COAST_NWC = 0x460E
# Seasons
TOKEN_SEASON_SPR = 0x4700
TOKEN_SEASON_SUM = 0x4701
TOKEN_SEASON_FAL = 0x4702
TOKEN_SEASON_AUT = 0x4703
TOKEN_SEASON_WIN = 0x4704
# Commands
TOKEN_COMMAND_CCD = 0x4800
TOKEN_COMMAND_DRW = 0x4801
TOKEN_COMMAND_FRM = 0x4802
TOKEN_COMMAND_GOF = 0x4803
TOKEN_COMMAND_HLO = 0x4804
TOKEN_COMMAND_HST = 0x4805
TOKEN_COMMAND_HUH = 0x4806
TOKEN_COMMAND_IAM = 0x4807
TOKEN_COMMAND_LOD = 0x4808
TOKEN_COMMAND_MAP = 0x4809
TOKEN_COMMAND_MDF = 0x480A
TOKEN_COMMAND_MIS = 0x480B
TOKEN_COMMAND_NME = 0x480C
TOKEN_COMMAND_NOT = 0x480D
TOKEN_COMMAND_NOW = 0x480E
TOKEN_COMMAND_OBS = 0x480F
TOKEN_COMMAND_OFF = 0x4810
TOKEN_COMMAND_ORD = 0x4811
TOKEN_COMMAND_OUT = 0x4812
TOKEN_COMMAND_PRN = 0x4813
TOKEN_COMMAND_REJ = 0x4814
TOKEN_COMMAND_SCO = 0x4815
TOKEN_COMMAND_SLO = 0x4816
TOKEN_COMMAND_SND = 0x4817
TOKEN_COMMAND_SUB = 0x4818
TOKEN_COMMAND_SVE = 0x4819
TOKEN_COMMAND_THX = 0x481A
TOKEN_COMMAND_TME = 0x481B
TOKEN_COMMAND_YES = 0x481C
TOKEN_COMMAND_ADM = 0x481D
TOKEN_COMMAND_SMR = 0x481E
# Parameters
TOKEN_PARAMETER_AOA = 0x4900
TOKEN_PARAMETER_BTL = 0x4901
TOKEN_PARAMETER_ERR = 0x4902
TOKEN_PARAMETER_LVL = 0x4903
TOKEN_PARAMETER_MRT = 0x4904
TOKEN_PARAMETER_MTL = 0x4905
TOKEN_PARAMETER_NPB = 0x4906
TOKEN_PARAMETER_NPR = 0x4907
TOKEN_PARAMETER_PDA = 0x4908
TOKEN_PARAMETER_PTL = 0x4909
TOKEN_PARAMETER_RTL = 0x490A
TOKEN_PARAMETER_UNO = 0x490B
TOKEN_PARAMETER_DSD = 0x490D
# Press
TOKEN_PRESS_ALY = 0x4A00
TOKEN_PRESS_AND = 0x4A01
TOKEN_PRESS_BWX = 0x4A02
TOKEN_PRESS_DMZ = 0x4A03
TOKEN_PRESS_ELS = 0x4A04
TOKEN_PRESS_EXP = 0x4A05
TOKEN_PRESS_FCT = 0x4A06
TOKEN_PRESS_FOR = 0x4A07
TOKEN_PRESS_FWD = 0x4A08
TOKEN_PRESS_HOW = 0x4A09
TOKEN_PRESS_IDK = 0x4A0A
TOKEN_PRESS_IFF = 0x4A0B
TOKEN_PRESS_INS = 0x4A0C
TOKEN_PRESS_OCC = 0x4A0E
TOKEN_PRESS_ORR = 0x4A0F
TOKEN_PRESS_PCE = 0x4A10
TOKEN_PRESS_POB = 0x4A11
TOKEN_PRESS_PRP = 0x4A13
TOKEN_PRESS_QRY = 0x4A14
TOKEN_PRESS_SCD = 0x4A15
TOKEN_PRESS_SRY = 0x4A16
TOKEN_PRESS_SUG = 0x4A17
TOKEN_PRESS_THK = 0x4A18
TOKEN_PRESS_THN = 0x4A19
TOKEN_PRESS_TRY = 0x4A1A
TOKEN_PRESS_VSS = 0x4A1C
TOKEN_PRESS_WHT = 0x4A1D
TOKEN_PRESS_WHY = 0x4A1E
TOKEN_PRESS_XDO = 0x4A1F
TOKEN_PRESS_XOY = 0x4A20
TOKEN_PRESS_YDO = 0x4A21
TOKEN_PRESS_CHO = 0x4A22
TOKEN_PRESS_BCC = 0x4A23
TOKEN_PRESS_UNT = 0x4A24
# Provinces
TOKEN_PROVINCE_BOH = 0x5000
TOKEN_PROVINCE_BUR = 0x5001
TOKEN_PROVINCE_GAL = 0x5002
TOKEN_PROVINCE_RUH = 0x5003
TOKEN_PROVINCE_SIL = 0x5004
TOKEN_PROVINCE_TYR = 0x5005
TOKEN_PROVINCE_UKR = 0x5006
TOKEN_PROVINCE_BUD = 0x5107
TOKEN_PROVINCE_MOS = 0x5108
TOKEN_PROVINCE_MUN = 0x5109
TOKEN_PROVINCE_PAR = 0x510A
TOKEN_PROVINCE_SER = 0x510B
TOKEN_PROVINCE_VIE = 0x510C
TOKEN_PROVINCE_WAR = 0x510D
TOKEN_PROVINCE_ADR = 0x520E
TOKEN_PROVINCE_AEG = 0x520F
TOKEN_PROVINCE_BAL = 0x5210
TOKEN_PROVINCE_BAR = 0x5211
TOKEN_PROVINCE_BLA = 0x5212
TOKEN_PROVINCE_EAS = 0x5213
TOKEN_PROVINCE_ECH = 0x5214
TOKEN_PROVINCE_GOB = 0x5215
TOKEN_PROVINCE_GOL = 0x5216
TOKEN_PROVINCE_HEL = 0x5217
TOKEN_PROVINCE_ION = 0x5218
TOKEN_PROVINCE_IRI = 0x5219
TOKEN_PROVINCE_MAO = 0x521A
TOKEN_PROVINCE_NAO = 0x521B
TOKEN_PROVINCE_NTH = 0x521C
TOKEN_PROVINCE_NWG = 0x521D
TOKEN_PROVINCE_SKA = 0x521E
TOKEN_PROVINCE_TYS = 0x521F
TOKEN_PROVINCE_WES = 0x5220
TOKEN_PROVINCE_ALB = 0x5421
TOKEN_PROVINCE_APU = 0x5422
TOKEN_PROVINCE_ARM = 0x5423
TOKEN_PROVINCE_CLY = 0x5424
TOKEN_PROVINCE_FIN = 0x5425
TOKEN_PROVINCE_GAS = 0x5426
TOKEN_PROVINCE_LVN = 0x5427
TOKEN_PROVINCE_NAF = 0x5428
TOKEN_PROVINCE_PIC = 0x5429
TOKEN_PROVINCE_PIE = 0x542A
TOKEN_PROVINCE_PRU = 0x542B
TOKEN_PROVINCE_SYR = 0x542C
TOKEN_PROVINCE_TUS = 0x542D
TOKEN_PROVINCE_WAL = 0x542E
TOKEN_PROVINCE_YOR = 0x542F
TOKEN_PROVINCE_ANK = 0x5530
TOKEN_PROVINCE_BEL = 0x5531
TOKEN_PROVINCE_BER = 0x5532
TOKEN_PROVINCE_BRE = 0x5533
TOKEN_PROVINCE_CON = 0x5534
TOKEN_PROVINCE_DEN = 0x5535
TOKEN_PROVINCE_EDI = 0x5536
TOKEN_PROVINCE_GRE = 0x5537
TOKEN_PROVINCE_HOL = 0x5538
TOKEN_PROVINCE_KIE = 0x5539
TOKEN_PROVINCE_LON = 0x553A
TOKEN_PROVINCE_LVP = 0x553B
TOKEN_PROVINCE_MAR = 0x553C
TOKEN_PROVINCE_NAP = 0x553D
TOKEN_PROVINCE_NWY = 0x553E
TOKEN_PROVINCE_POR = 0x553F
TOKEN_PROVINCE_ROM = 0x5540
TOKEN_PROVINCE_RUM = 0x5541
TOKEN_PROVINCE_SEV = 0x5542
TOKEN_PROVINCE_SMY = 0x5543
TOKEN_PROVINCE_SWE = 0x5544
TOKEN_PROVINCE_TRI = 0x5545
TOKEN_PROVINCE_TUN = 0x5546
TOKEN_PROVINCE_VEN = 0x5547
TOKEN_PROVINCE_BUL = 0x5748
TOKEN_PROVINCE_SPA = 0x5749
TOKEN_PROVINCE_STP = 0x574A
def test_tokens():
""" Test all tokens """
for token in ExpectedTokens:
token_str = token.name[-3:]
token_bytes = token.value.to_bytes(2, byteorder='big')
token_from_str = Token(from_str=token_str)
token_from_bytes = Token(from_bytes=token_bytes)
assert str(token_from_str) == token_str
assert str(token_from_bytes) == token_str
assert bytes(token_from_str) == token_bytes
assert bytes(token_from_bytes) == token_bytes