summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAineopintojen-harjoitustyo-Algoritmit-j <github-hy-tiralabra@v.hix.fi>2024-02-03 15:05:55 +0200
committerAineopintojen-harjoitustyo-Algoritmit-j <github-hy-tiralabra@v.hix.fi>2024-02-03 15:05:55 +0200
commit729455edf7fe92ba46ba2ea274bc3b5f4879b71b (patch)
treef300018c08775323f1cab4699633767500710b59
parentb45017cdb4d9f723202b2f110e28029f974a7c86 (diff)
Adding tests to whole app.
-rw-r--r--.coveragerc2
-rw-r--r--__main__.py8
-rw-r--r--board/board.py2
-rw-r--r--cmdline.py2
-rw-r--r--pyproject.toml1
-rw-r--r--tests/data/dssp_win.txt11
-rw-r--r--tests/test_app.py194
-rw-r--r--tui/kbd.py30
8 files changed, 234 insertions, 16 deletions
diff --git a/.coveragerc b/.coveragerc
index 7b967e8..dbfb5ad 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -1,6 +1,6 @@
[run]
branch = True
-omit = tests/*
+omit = tests/*, tui/kbd.py
[report]
exclude_lines =
diff --git a/__main__.py b/__main__.py
index 6dad3f8..c98633b 100644
--- a/__main__.py
+++ b/__main__.py
@@ -27,13 +27,19 @@ if args.file is None:
del app
else:
run_count = 0
- print(f"Pelataan miinaharavat tiedostosta {args.file}")
with open(args.file, "r", encoding="utf-8") as bfile:
board = []
while True:
line = bfile.readline()
if not line or (line[0]!='.' and line[0]!='@'):
if board:
+ win_percent = (100*win_count/run_count) if run_count else 0
+ print(end=
+ f" \rAjo ...{args.file[-18:]:} ({run_count+1}): "
+ f"({win_percent:.1f}%).."
+ )
+ if not args.quiet:
+ print()
args.board = board
app = App(args)
win_count += app.run()
diff --git a/board/board.py b/board/board.py
index c1ec798..59135d7 100644
--- a/board/board.py
+++ b/board/board.py
@@ -66,7 +66,7 @@ class Board():
for line in board:
if len(line)!=w:
return False
- if self.__get_board_mines(board) not in range (1, w*h - 1):
+ if self.__get_board_mines(board) not in range (1, w*h):
return False
return True
diff --git a/cmdline.py b/cmdline.py
index dd9e3a6..8df3408 100644
--- a/cmdline.py
+++ b/cmdline.py
@@ -53,7 +53,7 @@ hint_group.add_argument(
)
hint_group.add_argument(
'-b', '--bot', metavar='<B>',
- choices=range(2),
+ choices=range(3),
type=int,
default=2,
help='Valitsee tekoälyn <B>, missä: 0: Ei tekoälyä 1: Yksinkertainen, 2: DSSP (oletus)',
diff --git a/pyproject.toml b/pyproject.toml
index 2058c31..e459042 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -8,7 +8,6 @@ readme = "README.md"
[tool.poetry.dependencies]
python = "^3.10"
-
[tool.poetry.group.dev.dependencies]
pytest = "^7.4.4"
coverage = "^7.4.0"
diff --git a/tests/data/dssp_win.txt b/tests/data/dssp_win.txt
new file mode 100644
index 0000000..4a19dee
--- /dev/null
+++ b/tests/data/dssp_win.txt
@@ -0,0 +1,11 @@
+# Lautoja jotka DSSP selvittää
+
+.........
+.........
+.........
+.........
+.........
+.........
+.........
+.........
+.@@.@@.@.
diff --git a/tests/test_app.py b/tests/test_app.py
new file mode 100644
index 0000000..cae4e30
--- /dev/null
+++ b/tests/test_app.py
@@ -0,0 +1,194 @@
+"""test_app.py - Testaa pelin suoritusta"""
+# pylint: disable = missing-class-docstring, too-few-public-methods
+
+from io import StringIO
+import unittest
+from unittest.mock import patch
+
+from app import App
+
+from tui import Action
+
+class KbdTest:
+ # pylint: disable = unused-argument, missing-function-docstring
+ def __init__(self, actions):
+ self.actions = actions
+ def read_action(self):
+ return self.actions.pop(0) if self.actions else (Action.NOOP)
+ def read_matrix_action(self, w, h, x, y):
+ return (self.actions.pop(0), 0, 0) if self.actions else (Action.NOOP,0,0)
+
+
+class TestAppClass(unittest.TestCase):
+ """ Testit itse appille """
+ class default_args:
+ autoplay = 2
+ intermediate = None
+ expert = None
+ board = None
+ mines = None
+ size = None
+ bot = None
+ quiet = None
+
+ sure_win_board = [
+ [0,0,0,0,0,0,0,0,0],
+ [0,0,0,0,0,0,0,0,0],
+ [0,0,0,0,0,0,0,0,0],
+ [0,0,0,0,0,0,0,0,0],
+ [0,0,0,0,1,0,0,0,0],
+ [0,0,0,0,0,0,0,0,0],
+ [0,0,0,0,0,0,0,0,0],
+ [0,0,0,0,0,0,0,0,0],
+ [0,0,0,0,0,0,0,0,0]
+ ]
+
+ sure_lose_board = [
+ [1,1,1,1,1,1,1,1,1],
+ [1,1,1,1,1,1,1,1,1],
+ [1,1,1,1,1,1,1,1,1],
+ [1,1,1,1,1,1,1,1,1],
+ [1,1,1,1,0,1,1,1,1],
+ [1,1,1,1,1,1,1,1,1],
+ [1,1,1,1,1,1,1,1,1],
+ [1,1,1,1,1,1,1,1,1],
+ [1,1,1,1,1,1,1,1,1]
+ ]
+
+ dssp_win_board = [
+ [0,0,0,0,0,0,0,0,0],
+ [0,0,0,0,0,0,0,0,0],
+ [0,0,0,0,0,0,0,0,0],
+ [0,0,0,0,0,0,0,0,0],
+ [0,0,0,0,0,0,0,0,0],
+ [0,0,0,0,0,0,0,0,0],
+ [0,0,0,0,0,0,0,0,0],
+ [0,0,0,0,0,0,0,0,0],
+ [0,1,1,0,1,1,0,1,0]
+ ]
+
+
+ def test_run(self):
+ """ Testataan että edes pyörähtää """
+ app = App(self.default_args)
+ app.run()
+ del app
+
+ def test_quit(self):
+ """ Testataan Quittaamista """
+ app = App()
+ app.ui.kbd=KbdTest([
+ Action.QUIT,
+ Action.OPEN
+ ])
+ app.run()
+ del app
+
+ def test_many_games(self):
+ """ Varman voiton lauta palauttaa true """
+ class args(self.default_args):
+ quiet = True
+ for _ in range(50):
+ app = App(args)
+ app.run()
+ del app
+ args.intermediate = True
+ for _ in range(20):
+ app = App(args)
+ app.run()
+ del app
+ args.expert = True
+ for _ in range(10):
+ app = App(args)
+ app.run()
+ del app
+
+ def test_sure_win(self):
+ """ Varman voiton lauta palauttaa true """
+ class args(self.default_args):
+ board = self.sure_win_board
+ quiet = True
+ app = App(args)
+ self.assertTrue(app.run())
+ del app
+
+ def test_dssp_win(self):
+ """ Varman voiton lauta palauttaa true """
+ class args(self.default_args):
+ board = self.dssp_win_board
+ app = App(args)
+ self.assertTrue(app.run())
+ del app
+
+ def test_no_dssp_win_with_simple(self):
+ """ Varman voiton lauta palauttaa true """
+ class args(self.default_args):
+ board = self.dssp_win_board
+ quiet = True
+ bot = 1
+ while True:
+ app = App(args)
+ if not app.run():
+ break
+ del app
+
+ def test_sure_lose(self):
+ """ Varman häviön lauta palauttaa false """
+ class args(self.default_args):
+ board = self.sure_lose_board
+ app = App(args)
+ self.assertFalse(app.run())
+ del app
+
+ def test_custom_size(self):
+ """ Varman häviön lauta palauttaa false """
+ class args(self.default_args):
+ size = (4, 4)
+ with patch('sys.stdout', new = StringIO()) as captured:
+ app = App(args)
+ app.run()
+ self.assertIn("Mukautettu (4x4", captured.getvalue())
+ del app
+
+ def test_sure_win_with_actions(self):
+ """ Varman voiton lauta palauttaa true """
+ class args(self.default_args):
+ board = self.sure_win_board
+ autoplay = 0
+ bot = 0
+ app = App(args)
+ app.ui.kbd=KbdTest([
+ Action.SAFE,
+ Action.OPEN
+ ])
+ self.assertTrue(app.run())
+ del app
+
+ def test_sure_lose_with_actions(self):
+ """ Varman voiton lauta palauttaa true """
+ class args(self.default_args):
+ board = self.sure_lose_board
+ autoplay = 0
+ app = App(args)
+ app.ui.kbd=KbdTest([
+ Action.FLAG,
+ Action.MINE,
+ Action.OPEN
+ ])
+ self.assertFalse(app.run())
+ del app
+
+ def test_auto_play_hints(self):
+ """ Vihjeiden automaattipelaaminen toimii """
+ class args(self.default_args):
+ board = self.dssp_win_board
+ autoplay = 1
+ app = App(args)
+ app.ui.kbd=KbdTest([
+ Action.NOOP,
+ Action.NOOP,
+ Action.OPEN,
+ Action.HINT
+ ])
+ self.assertTrue(app.run())
+ del app
diff --git a/tui/kbd.py b/tui/kbd.py
index 81840ae..a31e56f 100644
--- a/tui/kbd.py
+++ b/tui/kbd.py
@@ -1,6 +1,6 @@
""" tui/kbd.py - näppäimistön käsittellijä """
# pylint: disable = multiple-imports
-import termios, fcntl, sys, os
+import termios, fcntl, sys, os, io
from time import sleep
from .static import ActionKeys, Action
@@ -21,21 +21,29 @@ class Kbd():
# Vaatii hieman terminaaliasetusten muokkaamista jotta yksittäiset
# napin painallukset voidaan lukea
# https://stackoverflow.com/questions/983354/how-do-i-wait-for-a-pressed-key
- fd = sys.stdin.fileno()
- self.oldterm = termios.tcgetattr(fd)
+ try:
+ fd = sys.stdin.fileno()
+ self.oldterm = termios.tcgetattr(fd)
- newattr = termios.tcgetattr(fd)
- newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
- termios.tcsetattr(fd, termios.TCSANOW, newattr)
+ newattr = termios.tcgetattr(fd)
+ newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
+ termios.tcsetattr(fd, termios.TCSANOW, newattr)
- self.oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
- fcntl.fcntl(fd, fcntl.F_SETFL, self.oldflags | os.O_NONBLOCK)
+ self.oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
+ fcntl.fcntl(fd, fcntl.F_SETFL, self.oldflags | os.O_NONBLOCK)
+ # Testeissä ei voi mukata termilaalia
+ except io.UnsupportedOperation:
+ pass
def __del__(self):
# palautetaan terminaali takaisin alkupetäiseen uskoon
- fd = sys.stdin.fileno()
- termios.tcsetattr(fd, termios.TCSAFLUSH, self.oldterm)
- fcntl.fcntl(fd, fcntl.F_SETFL, self.oldflags)
+ try:
+ fd = sys.stdin.fileno()
+ termios.tcsetattr(fd, termios.TCSAFLUSH, self.oldterm)
+ fcntl.fcntl(fd, fcntl.F_SETFL, self.oldflags)
+ # Testeissä ei voi mukata termilaalia
+ except io.UnsupportedOperation:
+ pass
def read_action(self):
""" lukee näppäimistölä käyttäjän toiminnon """