From 4b75005b28555e507acb6bd64ec766cc809c5cdc Mon Sep 17 00:00:00 2001 From: Shlomi Fish Date: Mon, 7 May 2018 23:29:14 +0300 Subject: [PATCH] Start adding support for handling parse errs. in the importFile feature. Still does not work fully. --- pysollib/hint.py | 37 ++++++++++++++++++++----- pysollib/ui/tktile/menubar.py | 12 +++++++- tests/lib/pysol_tests/import_file1.py | 16 ++++++++++- tests/unit/data/624-with-dup-card.board | 8 ++++++ 4 files changed, 64 insertions(+), 9 deletions(-) create mode 100644 tests/unit/data/624-with-dup-card.board diff --git a/pysollib/hint.py b/pysollib/hint.py index e37c08a8..9dd6fc7a 100644 --- a/pysollib/hint.py +++ b/pysollib/hint.py @@ -716,6 +716,18 @@ class SpiderType_Hint(DefaultHint): pass +class PySolHintLayoutImportError(Exception): + + def __init__(self, msg, cards, line_num): + """docstring for __init__""" + self.msg = msg + self.cards = cards + self.line_num = line_num + + def format(self): + return self.msg + ":\n\n" + ', '.join(self.cards) + + # ************************************************************************ # * FreeCell-Solver # ************************************************************************ @@ -744,18 +756,21 @@ class Base_Solver_Hint: def config(self, **kw): self.options.update(kw) - def _card2str_format(self, fmt, card): + def _card2str_format(self, fmt, rank, suit): # row and reserves - rank = (card.rank-self.base_rank) % 13 - return fmt % {'R': "A23456789TJQK"[rank], 'S': "CSHD"[card.suit]} + rank = (rank-self.base_rank) % 13 + return fmt % {'R': "A23456789TJQK"[rank], 'S': "CSHD"[suit]} + + def card2str1_(self, rank, suit): + # row and reserves + return self._card2str_format('%(R)s%(S)s', rank, suit) def card2str1(self, card): - # row and reserves - return self._card2str_format('%(R)s%(S)s', card) + return self.card2str1_(card.rank, card.suit) def card2str2(self, card): # foundations - return self._card2str_format('%(S)s-%(R)s', card) + return self._card2str_format('%(S)s-%(R)s', card.rank, card.suit) # hard solvable: Freecell #47038300998351211829 (65539 iters) @@ -853,6 +868,7 @@ class FreeCellSolver_Hint(Base_Solver_Hint): SUITS_S = "CSHD" SUITS_RE = '[' + SUITS_S + ']' CARD_RE = r'(?:' + RANKS_RE + SUITS_RE + ')' + line_num = 0 def cards(): return game.talon.cards @@ -860,7 +876,13 @@ class FreeCellSolver_Hint(Base_Solver_Hint): def put(target, suit, rank): ret = [i for i, c in enumerate(cards()) if c.suit == suit and c.rank == rank] - assert len(ret) == 1 + if len(ret) < 1: + raise PySolHintLayoutImportError( + "Duplicate cards in input", + [solver.card2str1_(rank, suit)], + line_num + ) + ret = ret[0] game.talon.cards = \ cards()[0:ret] + cards()[(ret+1):] + [cards()[ret]] @@ -889,6 +911,7 @@ class FreeCellSolver_Hint(Base_Solver_Hint): mytext = mydecode(fh.read()) for line_p in mytext.splitlines(): + line_num += 1 line = line_p.rstrip('\r\n') m = re.match(r'^(?:Foundations:|Founds?:)\s*(.*)', line) if m: diff --git a/pysollib/ui/tktile/menubar.py b/pysollib/ui/tktile/menubar.py index c692b3d6..b50a1c07 100644 --- a/pysollib/ui/tktile/menubar.py +++ b/pysollib/ui/tktile/menubar.py @@ -13,6 +13,7 @@ from pysollib.settings import TITLE, WIN_SYSTEM from pysollib.settings import SELECT_GAME_MENU from pysollib.gamedb import GI from pysollib.settings import USE_FREECELL_SOLVER +from pysollib.hint import PySolHintLayoutImportError from pysollib.ui.tktile.tkconst import EVENT_HANDLED, EVENT_PROPAGATE, \ CURSOR_WATCH, COMPOUNDS @@ -1239,7 +1240,16 @@ Unsupported game for import. if os.path.isfile(filename): with open(filename, 'r+b') as fh: game = self.game - game.Solver_Class(game, self).importFile(fh, game, self) + try: + game.Solver_Class(game, self).importFile( + fh, game, self) + except PySolHintLayoutImportError as err: + self._calc_MfxMessageDialog()( + self.top, + title=_('Import game error'), + text=err.format(), + bitmap='error' + ) def mSaveAs(self, *event): if self._cancelDrag(break_pause=False): diff --git a/tests/lib/pysol_tests/import_file1.py b/tests/lib/pysol_tests/import_file1.py index de76ad86..e8f88e34 100644 --- a/tests/lib/pysol_tests/import_file1.py +++ b/tests/lib/pysol_tests/import_file1.py @@ -2,7 +2,7 @@ import unittest from pysollib.acard import AbstractCard -from pysollib.hint import FreeCellSolver_Hint +from pysollib.hint import FreeCellSolver_Hint, PySolHintLayoutImportError import pysollib.stack @@ -132,6 +132,20 @@ KD QC 5C QH 6S 3D 8S 7H 3H 2C AC 7D ''', 'import worked with utf-8 bom') + def test_throw_error_on_duplicate_card(self): + s_game = Mock_S_Game() + h = FreeCellSolver_Hint(s_game, None) + fh = open('tests/unit/data/624-with-dup-card.board', 'r+b') + try: + h.importFileHelper(fh, s_game) + except PySolHintLayoutImportError as err: + self.assertEqual(err.msg, "Duplicate cards in input") + self.assertEqual(err.cards, ["KC"]) + self.assertEqual(err.line_num, 1) + self.assertEqual(err.format(), "Duplicate cards in input:\n\nKC") + return + self.fail("No exception thrown.") + def mymain(): from pycotap import TAPTestRunner diff --git a/tests/unit/data/624-with-dup-card.board b/tests/unit/data/624-with-dup-card.board new file mode 100644 index 00000000..6a1ef183 --- /dev/null +++ b/tests/unit/data/624-with-dup-card.board @@ -0,0 +1,8 @@ +: KC KC 4C QS 2D 4S AS +: 4H TH 2S JH 2H 9S AH +: 3S 6C 9H AD KH QD 7C +: 3C JS 5H KS TC 9C 8C +: 4D 9D 7S JC 5D TS +: KD QC 5C QH 6S 3D +: 5S JD 8D 6D TD 8H +: 8S 7H 3H 2C AC 7D