Skip to content

Commit

Permalink
Merge pull request niklasf#252 from Mk-Chan/master
Browse files Browse the repository at this point in the history
Xboard option parsing and tests
  • Loading branch information
niklasf authored Dec 13, 2017
2 parents 8e0357a + 234e42e commit d60a067
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 12 deletions.
30 changes: 19 additions & 11 deletions chess/xboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,7 @@ def _feature(self, features):
params = features.split("=")[1].split()
name = params[0]
type = params[1][1:]
default = None
min = None
max = None
var = []
Expand All @@ -413,9 +414,14 @@ def _feature(self, features):
var.append(choice[1:])
else:
var.append(choice)
print(var)
print(default)
else:
elif type == "check":
default = int(params[2])
elif type in ("string", "file", "path"):
if len(params) > 2:
default = params[2]
else:
default = ""
elif type == "spin":
default = int(params[2])
min = int(params[3])
max = int(params[4])
Expand Down Expand Up @@ -711,6 +717,7 @@ def command():
def option(self, options, async_callback=None):
"""
Sets values for the engine's available options.
For 'button', 'reset' and 'save', flips the engine's value.
:param options: A dictionary with option names as keys.
Expand All @@ -722,22 +729,23 @@ def option(self, options, async_callback=None):
# Building string manually to avoid spaces
option_string = "option " + name
option = self.features.get_option(name)
has_value = option.type in ["spin", "check", "combo", "string"]
has_value = option.type in ["spin", "check", "combo", "string", "file", "path"]
if has_value and value is not None:
value = str(value)
if option.type in ["string", "file", "path"]:
value = "\"" + value + "\""
option_string += "=" + value
option_lines.append(option_string)
elif not has_value and value is None:
elif not has_value:
option_lines.append(option_string)

def command():
with self.semaphore:
with self.pong_received:
for option_line in option_lines:
self.send_line(option_line)
for option_line in option_lines:
self.send_line(option_line)

if self.terminated.is_set():
raise EngineTerminatedException()
if self.terminated.is_set():
raise EngineTerminatedException()

return self._queue_command(command, async_callback)

Expand Down Expand Up @@ -960,7 +968,7 @@ def egtpath(self, egt_type, egt_path, async_callback=None):
:return: Nothing.
"""
if not egt_type in self.features.get("egt"):
if egt_type not in self.features.get("egt"):
raise EngineStateException("engine does not support the '{}' egt".format(egt_type))

builder = ["egtpath", egt_type, egt_path]
Expand Down
47 changes: 46 additions & 1 deletion test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2445,7 +2445,20 @@ def setUp(self):
self.engine = chess.xboard.Engine()
self.mock = chess.engine.MockProcess(self.engine)
self.mock.expect("xboard")
self.mock.expect("protover 2", ("feature egt=syzygy,gaviota", ))
feature_list = (
"feature egt=syzygy,gaviota",
"feature option=\"spinvar -spin 50 0 100\"",
"feature option=\"combovar -combo HI /// HELLO /// BYE\"",
"feature option=\"checkvar -check 0\"",
"feature option=\"stringvar -string \"\"\"",
"feature option=\"filevar -file \"\"\"",
"feature option=\"pathvar -path \"\"\"",
"feature option=\"buttonvar -button\"",
"feature option=\"resetvar -reset\"",
"feature option=\"savevar -save\"",

)
self.mock.expect("protover 2", feature_list)
self.mock.expect("post")
self.mock.expect("easy")
self.mock.expect("ping 123", ("pong 123", ))
Expand Down Expand Up @@ -2512,6 +2525,7 @@ def test_human_offer_draw_during_engine_search(self):
self.engine.st(10)
self.mock.expect("go")
self.engine.go(async_callback=True)
time.sleep(0.01)

self.mock.expect("draw", ("offer draw", ))
self.mock.expect("result 1/2-1/2")
Expand Down Expand Up @@ -2566,6 +2580,37 @@ def test_egtpath(self):
self.engine.egtpath("syzygy", "/abc")
self.mock.assert_done()

def test_options(self):
"""
Could do with dictionary instead, but that fails to preserve order
on some versions of Python.
Done with an *OrderedDict* just for testing purposes, the order is
not actually important.
"""
option_map = collections.OrderedDict()
option_map["spinvar"] = 99
option_map["combovar"] = "BYE"
option_map["checkvar"] = 1
option_map["stringvar"] = "teststring"
option_map["filevar"] = "filename"
option_map["pathvar"] = "path/to/some/dir"
option_map["buttonvar"] = None
option_map["resetvar"] = None
option_map["savevar"] = None

self.mock.expect("option spinvar=99")
self.mock.expect("option combovar=BYE")
self.mock.expect("option checkvar=1")
self.mock.expect("option stringvar=\"teststring\"")
self.mock.expect("option filevar=\"filename\"")
self.mock.expect("option pathvar=\"path/to/some/dir\"")
self.mock.expect("option buttonvar")
self.mock.expect("option resetvar")
self.mock.expect("option savevar")
self.engine.option(option_map)
self.mock.assert_done()


class UciEngineTestCase(unittest.TestCase):

Expand Down

0 comments on commit d60a067

Please sign in to comment.