Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 41 additions & 9 deletions CHaser.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,38 @@
import socket
import ipaddress
import os
import getopt
import sys


class Client:
def __init__(self):
self.port = input("ポート番号を入力してください → ")
self.name = input("ユーザー名を入力してください → ")[:15]
self.host = input("サーバーのIPアドレスを入力してください → ")
if len(sys.argv) > 1:
try:
optlist, args = getopt.getopt(sys.argv[1:], 'h:n:p:')
except getopt.GetoptError as err:
print(err) # will print something like "option -a not recognized"
sys.exit(2)
for o, a in optlist:
if o == '-n':
self.name = a
elif o == '-p':
self.port = a
elif o == '-h':
self.host = a
else:
assert False, "unhandled option"
else:
self.port = input("ポート番号を入力してください → ")
self.name = input("ユーザー名を入力してください → ")[:15]
self.host = input("サーバーのIPアドレスを入力してください → ")

if not self.port:
self.port = 2009
if not self.name:
self.name = 'User1'
if not self.host:
self.host = '127.0.0.1'

if not self.__ip_judge(self.host):
os._exit(1)
Expand All @@ -32,32 +58,39 @@ def __ip_judge(self, host):
def __str_send(self, send_str):
try:
self.client.sendall(send_str.encode("utf-8"))
except:
except Exception:
print("send error:{0}\0".format(send_str))

def __order(self, order_str, gr_flag = False):
def __order(self, order_str, gr_flag=False):
"""
@order_str (strig): Command. must be 2 chars and upper case.
@gr_flag (boolean): GetReady flag.
"""
try:
if gr_flag:
responce = self.client.recv(4096)

if(b'@' in responce):
pass # Connection completed.
pass # Connection completed.
else:
print("Connection failed.")
print("Connection failed. {0}".format(responce))

self.__str_send(order_str + "\r\n")

# response is 11 digits integer.
responce = self.client.recv(4096)[0:11].decode("utf-8")

if not gr_flag:
self.__str_send("#\r\n")

# if first digit is `0` game is over.
if responce[0] == '1':
return [int(x) for x in responce[1:10]]
elif responce[0] == '0':
raise OSError("Game Set!")
else:
print("responce[0] = {0} : Response error.".format(responce[0]))
msg = "responce[0] = {0} : Response error."
print(msg.format(responce[0]))
raise OSError("Responce Error")

except OSError as e:
Expand Down Expand Up @@ -115,4 +148,3 @@ def put_left(self):

def put_down(self):
return self.__order("pd")

118 changes: 118 additions & 0 deletions test_CHaser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from io import StringIO
import contextlib
import sys
import unittest
import CHaser


class contextlib_redirect_stdin(contextlib._RedirectStream):
"""
標準入力を横取りするためのおまじない
"""
_stream = "stdin"


class TestCHaser(unittest.TestCase):
"""
contextlibを使って標準入力・出力・エラーを横取りし
Clientの起動パラメーターを渡してのテストを行う
"""
def tearDown(self) -> None:
"""
sys.argvはテストケースをまたいで残るため都度リセットする
"""
del sys.argv[1:]
return super().tearDown()

def test_noargs(self):
"""
コマンドライン引数なしでClientを初期化したテストケース
StringIOを使って input 関数に入力を行う
"""
buf_in = StringIO()
buf_in.write("9999\n")
buf_in.write("MyName\n")
buf_in.write("0.0.0.0\n")
buf_in.seek(0)
buf_out = StringIO()
buf_err = StringIO()
with contextlib.redirect_stdout(buf_out), \
contextlib.redirect_stderr(buf_err), \
contextlib_redirect_stdin(buf_in):
try:
client = CHaser.Client()
self.assertEquals(9999, client.port)
self.assertEquals("MyName", client.name)
self.assertEquals("0.0.0.0", client.host)
except ConnectionRefusedError:
pass

def test_default_values(self):
"""
inputに空文字列を送った場合のテストケース
"""
buf_in = StringIO()
buf_in.write("\n")
buf_in.write("\n")
buf_in.write("\n")
buf_in.seek(0)
buf_out = StringIO()
buf_err = StringIO()
with contextlib.redirect_stdout(buf_out), \
contextlib.redirect_stderr(buf_err), \
contextlib_redirect_stdin(buf_in):
try:
client = CHaser.Client()
self.assertEquals(2009, client.port)
self.assertEquals("User1", client.name)
self.assertEquals("127.0.0.1", client.host)
except ConnectionRefusedError:
pass

def test_argv(self):
"""
コマンドライン引数を渡してClientを初期化したテストケース
"""
sys.argv.append("-p")
sys.argv.append("2010")
sys.argv.append("-n")
sys.argv.append("User2")
sys.argv.append("-h")
sys.argv.append("127.0.0.1")
buf_in = StringIO()
buf_out = StringIO()
buf_err = StringIO()
with contextlib.redirect_stdout(buf_out), \
contextlib.redirect_stderr(buf_err), \
contextlib_redirect_stdin(buf_in):
try:
client = CHaser.Client()
self.assertEquals(2010, client.port)
self.assertEquals("User2", client.name)
self.assertEquals("127.0.0.1", client.host)
except ConnectionRefusedError:
pass

def test_invalid_argv(self):
"""
不正なコマンドライン引数を渡したテストケース
"""
sys.argv.append("-a")
buf_in = StringIO()
buf_out = StringIO()
buf_err = StringIO()
with contextlib.redirect_stdout(buf_out), \
contextlib.redirect_stderr(buf_err), \
contextlib_redirect_stdin(buf_in):
try:
CHaser.Client()
except SystemExit:
expect = "option -a not recognized\n"
self.assertEquals(expect, buf_out.getvalue())


if __name__ == '__main__':
unittest.main()