From 1f908903a56885b490bdfa9b6e514036e5cc8b72 Mon Sep 17 00:00:00 2001 From: orlnub123 <30984274+orlnub123@users.noreply.github.com> Date: Thu, 29 Mar 2018 20:48:51 +0300 Subject: [PATCH] 2.2.0 --- README.rst | 16 +-- cleverbot/__init__.py | 2 +- cleverbot/async_/cleverbot.py | 13 ++- cleverbot/base.py | 63 +++++++++--- cleverbot/cleverbot.py | 11 ++ cleverbot/errors.py | 5 +- tests/async_tests/test_cleverbot.py | 154 ++++++++++++++++++++++++---- tests/test_cleverbot.py | 145 ++++++++++++++++++++++---- 8 files changed, 336 insertions(+), 73 deletions(-) diff --git a/README.rst b/README.rst index 9fb1fda..1858684 100644 --- a/README.rst +++ b/README.rst @@ -69,12 +69,12 @@ asynchronously import it as below instead: from cleverbot import async_ as cleverbot -Then initialize Cleverbot with your API key and optionally a cleverbot state -and or timeout: +Then initialize Cleverbot with your API key and optionally a cleverbot state, +timeout and or tweak if you want to adjust Cleverbot's mood: .. code:: py - cb = cleverbot.Cleverbot('YOUR_API_KEY', cs='76nxdxIJ02AAA', timeout=60) + cb = cleverbot.Cleverbot('YOUR_API_KEY', cs='76nxdxIJ02AAA', timeout=60, tweak1=0, tweak2=100, tweak3=100) The cleverbot state is the encoded state of the conversation that you get from talking to Cleverbot and includes the whole conversation history. @@ -94,9 +94,9 @@ Talk straight to Cleverbot: You can pass in keyword arguments to ``say`` such as ``cs`` to change the conversation, ``vtext`` to change the current conversation's history, or even -``cb_settings_tweak`` to change Cleverbot's mood. Read the "Parameters" section -of `the official Cleverbot API docs `_ -for more information. +``tweak`` as an alias for ``cb_settings_tweak`` to change Cleverbot's mood. +Read the "Parameters" section of `the official Cleverbot API docs +`_ for more information. Alternatively, start a new conversation and talk from it: @@ -191,8 +191,8 @@ you can use ``cb.save``: with open('cleverbot.txt', 'wb') as file: cb.save(file) -This saves the key and timeout you've given to Cleverbot and its conversations -and also the current cleverbot state of each. +This saves the key, timeout and tweaks you've given to Cleverbot and its +conversations and also the current cleverbot state of each. In order to load and recreate the previously saved state as a new Cleverbot instance use ``cleverbot.load``: diff --git a/cleverbot/__init__.py b/cleverbot/__init__.py index f4301b8..81b03ea 100644 --- a/cleverbot/__init__.py +++ b/cleverbot/__init__.py @@ -1,4 +1,4 @@ -__version__ = '2.1.1' +__version__ = '2.2.0' from .cleverbot import Cleverbot, load from .errors import CleverbotError, APIError, DecodeError, Timeout diff --git a/cleverbot/async_/cleverbot.py b/cleverbot/async_/cleverbot.py index ec3841f..e67d582 100644 --- a/cleverbot/async_/cleverbot.py +++ b/cleverbot/async_/cleverbot.py @@ -17,6 +17,7 @@ def say(self, input=None, **kwargs): Arguments: input: The input argument is what you want to say to Cleverbot, such as "hello". + tweak1-3: Changes Cleverbot's mood. **kwargs: Keyword arguments to update the request parameters with. Returns: @@ -38,8 +39,18 @@ def say(self, input=None, **kwargs): params['cs'] = self.data['cs'] except KeyError: pass - # Python 3.4 compatibility + for tweak in ('tweak1', 'tweak2', 'tweak3'): + if getattr(self, tweak, None) is not None: + params['cb_settings_' + tweak] = getattr(self, tweak) if kwargs: + for tweak in ('tweak1', 'tweak2', 'tweak3'): + setting = 'cb_settings_' + tweak + if tweak in kwargs and setting not in kwargs: + kwargs[setting] = kwargs.pop(tweak) + elif tweak in kwargs and setting in kwargs: + message = "Supplied both {!r} and {!r}" + raise TypeError(message.format(tweak, setting)) + # Python 3.4 compatibility params.update(kwargs) headers = { diff --git a/cleverbot/base.py b/cleverbot/base.py index 7e18845..01a25f5 100644 --- a/cleverbot/base.py +++ b/cleverbot/base.py @@ -10,7 +10,7 @@ def __getattr__(self, attr): try: return self.data[attr] except KeyError: - message = "'{0}' object has no attribute '{1}'" + message = "{0!r} object has no attribute {1!r}" raise AttributeError(message.format(self.__class__.__name__, attr)) @property @@ -35,9 +35,11 @@ def __init__(self, key, **kwargs): # Python 2 compatible keyword-only args if 'cs' in kwargs: self.data['cs'] = kwargs.pop('cs') self.timeout = kwargs.pop('timeout', None) + for tweak in ('tweak1', 'tweak2', 'tweak3'): + setattr(self, tweak, kwargs.pop(tweak, None)) self.conversations = None if kwargs: - message = "__init__() got an unexpected keyword argument '{0}'" + message = "__init__() got an unexpected keyword argument {0!r}" raise TypeError(message.format(next(iter(kwargs)))) def conversation(self, name, convo): @@ -70,19 +72,22 @@ def save(self, file): Arguments: file: A file object that accepts bytes to save the data to. """ - obj = ({'key': self.key, 'cs': self.cs, 'timeout': self.timeout}, []) - for convo in self.conversations: - if isinstance(self.conversations, dict): - name, convo = convo, self.conversations[convo] - convo_dict = {'name': name, 'cs': convo.data.get('cs')} - else: - convo_dict = {'cs': convo.data.get('cs')} - for item in ('key', 'timeout'): - try: - convo_dict[item] = convo.__dict__[item] - except KeyError: - pass - obj[1].append(convo_dict) + obj = ({'key': self.key, 'cs': self.cs, 'timeout': self.timeout, + 'tweak1': self.tweak1, 'tweak2': self.tweak2, + 'tweak3': self.tweak3}, []) + if self.conversations is not None: + for convo in self.conversations: + if isinstance(self.conversations, dict): + name, convo = convo, self.conversations[convo] + convo_dict = {'name': name, 'cs': convo.data.get('cs')} + else: + convo_dict = {'cs': convo.data.get('cs')} + for item in ('key', 'timeout', 'tweak1', 'tweak2', 'tweak3'): + try: + convo_dict[item] = convo.__dict__[item] + except KeyError: + pass + obj[1].append(convo_dict) pickle.dump(obj, file, pickle.HIGHEST_PROTOCOL) def load(self, file): @@ -104,12 +109,12 @@ class ConversationBase(AttributeMixin): def __init__(self, cleverbot, **kwargs): self.cleverbot = cleverbot self.data = {} - for item in ('key', 'cs', 'timeout'): + for item in ('key', 'cs', 'timeout', 'tweak1', 'tweak2', 'tweak3'): if item in kwargs: setattr(self, item, kwargs.pop(item)) self.session = cleverbot.session if kwargs: - message = "__init__() got an unexpected keyword argument '{0}'" + message = "__init__() got an unexpected keyword argument {0!r}" raise TypeError(message.format(next(iter(kwargs)))) @property @@ -128,5 +133,29 @@ def timeout(self): def timeout(self, value): self.__dict__['timeout'] = value + @property + def tweak1(self): + return self.__dict__.get('tweak1', self.cleverbot.tweak1) + + @tweak1.setter + def tweak1(self, value): + self.__dict__['tweak1'] = value + + @property + def tweak2(self): + return self.__dict__.get('tweak2', self.cleverbot.tweak2) + + @tweak2.setter + def tweak2(self, value): + self.__dict__['tweak2'] = value + + @property + def tweak3(self): + return self.__dict__.get('tweak3', self.cleverbot.tweak3) + + @tweak3.setter + def tweak3(self, value): + self.__dict__['tweak3'] = value + def reset(self): self.data = {} diff --git a/cleverbot/cleverbot.py b/cleverbot/cleverbot.py index cddd206..6751d3f 100644 --- a/cleverbot/cleverbot.py +++ b/cleverbot/cleverbot.py @@ -15,6 +15,7 @@ def say(self, input=None, **kwargs): Arguments: input: The input argument is what you want to say to Cleverbot, such as "hello". + tweak1-3: Changes Cleverbot's mood. **kwargs: Keyword arguments to update the request parameters with. Returns: @@ -29,9 +30,19 @@ def say(self, input=None, **kwargs): 'key': self.key, 'input': input, 'cs': self.data.get('cs'), + 'cb_settings_tweak1': self.tweak1, + 'cb_settings_tweak2': self.tweak2, + 'cb_settings_tweak3': self.tweak3, 'wrapper': 'cleverbot.py' } if kwargs: + for tweak in ('tweak1', 'tweak2', 'tweak3'): + setting = 'cb_settings_' + tweak + if tweak in kwargs and setting not in kwargs: + kwargs[setting] = kwargs.pop(tweak) + elif tweak in kwargs and setting in kwargs: + message = "Supplied both {0!r} and {1!r}" + raise TypeError(message.format(tweak, setting)) params.update(kwargs) headers = { diff --git a/cleverbot/errors.py b/cleverbot/errors.py index 4af8f82..34640cb 100644 --- a/cleverbot/errors.py +++ b/cleverbot/errors.py @@ -7,8 +7,9 @@ class APIError(CleverbotError): documentation for an updated list of all the possible errors. """ - def __init__(self, error, status): - super(APIError, self).__init__(error) + def __init__(self, error=None, status=None): + message = "An unspecified error occurred" + super(APIError, self).__init__(error if error is not None else message) self.error = error self.status = status diff --git a/tests/async_tests/test_cleverbot.py b/tests/async_tests/test_cleverbot.py index 073c9f3..3525894 100644 --- a/tests/async_tests/test_cleverbot.py +++ b/tests/async_tests/test_cleverbot.py @@ -1,20 +1,25 @@ import asyncio import io -from cleverbot import async_ as cleverbot import pytest +from cleverbot import async_ as cleverbot + @pytest.fixture -def cb(monkeypatch, request): - cb = cleverbot.Cleverbot('API_KEY', cs='76nxdxIJ02AAA', timeout=60) +def cb(request, monkeypatch): + cb = cleverbot.Cleverbot('API_KEY', cs='76nxdxIJ02AAA', timeout=60, + tweak1=25, tweak2=50, tweak3=75) if hasattr(request, 'param'): @asyncio.coroutine def mock_get(url, params, headers, timeout): + class MockResponse(object): def __init__(self): if request.param.get('timeout'): raise asyncio.TimeoutError + if request.param.get('params'): + assert params == request.param['params'] self.status = request.param.get('status', 200) @asyncio.coroutine @@ -31,7 +36,8 @@ def json(self): @pytest.fixture def cb_nameless(): - cb = cleverbot.Cleverbot('API_KEY', cs='76nxdxIJ02AAA', timeout=60) + cb = cleverbot.Cleverbot('API_KEY', cs='76nxdxIJ02AAA', timeout=60, + tweak1=25, tweak2=50, tweak3=75) for i, s in enumerate(map(str, range(200))): cb.conversation(key=s, cs=s, timeout=i) yield cb @@ -40,7 +46,8 @@ def cb_nameless(): @pytest.fixture def cb_named(): - cb = cleverbot.Cleverbot('API_KEY', cs='76nxdxIJ02AAA', timeout=60) + cb = cleverbot.Cleverbot('API_KEY', cs='76nxdxIJ02AAA', timeout=60, + tweak1=25, tweak2=50, tweak3=75) for i, s in enumerate(map(str, range(200))): cb.conversation(s, key=s, cs=s, timeout=i) yield cb @@ -50,10 +57,14 @@ def cb_named(): class TestCleverbot: def test_init(self): - cb = cleverbot.Cleverbot('API_KEY', cs='76nxdxIJ02AAA', timeout=60) + cb = cleverbot.Cleverbot('API_KEY', cs='76nxdxIJ02AAA', timeout=60, + tweak1=25, tweak2=50, tweak3=75) assert cb.key == 'API_KEY' assert cb.cs == '76nxdxIJ02AAA' assert cb.timeout == 60 + assert cb.tweak1 == 25 + assert cb.tweak2 == 50 + assert cb.tweak3 == 75 cb.close() def test_cs(self): @@ -67,6 +78,34 @@ def test_getattr(self, cb): cb.data = {'test': 'value'} assert cb.test == 'value' + @pytest.mark.asyncio + @pytest.mark.parametrize( + 'cb', [ + {'params': { + 'input': 'test', 'key': 'key', 'cs': 'cs', 'timeout': 10, + 'wrapper': 'cleverbot.py', 'cb_settings_tweak1': 5, + 'cb_settings_tweak2': 10, 'cb_settings_tweak3': 15, + 'test': 'test' + }} + ], indirect=True + ) + def test_say_params(self, cb): + yield from cb.say('test', key='key', cs='cs', timeout=10, tweak1=5, + tweak2=10, tweak3=15, test='test') + + @pytest.mark.asyncio + @pytest.mark.parametrize( + 'cb', [ + {'params': { + 'key': 'API_KEY', 'cs': '76nxdxIJ02AAA', + 'wrapper': 'cleverbot.py', 'cb_settings_tweak1': 25, + 'cb_settings_tweak2': 50, 'cb_settings_tweak3': 75 + }} + ], indirect=True + ) + def test_say_params_empty(self, cb): + yield from cb.say() + @pytest.mark.asyncio @pytest.mark.parametrize( 'cb', [ @@ -94,44 +133,70 @@ def test_say_apierror(self, cb): assert e.status == 401 raise + @pytest.mark.asyncio + @pytest.mark.parametrize( + 'cb', [{'status': 401, 'json': {}}], indirect=True) + def test_say_apierror_empty(self, cb): + with pytest.raises(cleverbot.APIError): + yield from cb.say() + @pytest.mark.asyncio @pytest.mark.parametrize('cb', [{'timeout': True}], indirect=True) def test_say_timeout(self, cb): with pytest.raises(cleverbot.Timeout): - yield from cb.say() + try: + yield from cb.say() + except cleverbot.Timeout as e: + assert e.timeout == cb.timeout + raise def test_conversation_empty(self, cb): convo = cb.conversation() assert convo.key == cb.key assert convo.cs is None assert convo.timeout == cb.timeout + assert convo.tweak1 == cb.tweak1 + assert convo.tweak2 == cb.tweak2 + assert convo.tweak3 == cb.tweak3 def test_conversation_nameless(self, cb): - convo = cb.conversation(key='key', cs='cs', timeout=10) + convo = cb.conversation( + key='key', cs='cs', timeout=10, tweak1=5, tweak2=10, tweak3=15) assert convo.key == 'key' assert convo.cs == 'cs' assert convo.timeout == 10 + assert convo.tweak1 == 5 + assert convo.tweak2 == 10 + assert convo.tweak3 == 15 def test_conversation_named(self, cb): - convo = cb.conversation('name', key='key', cs='cs', timeout=10) + convo = cb.conversation('name', key='key', cs='cs', timeout=10, + tweak1=5, tweak2=10, tweak3=15) assert convo.key == 'key' assert convo.cs == 'cs' assert convo.timeout == 10 + assert convo.tweak1 == 5 + assert convo.tweak2 == 10 + assert convo.tweak3 == 15 def test_conversations_nameless(self, cb): for i, s in enumerate(map(str, range(200))): - cb.conversation(key=s, cs=s*2, timeout=i) + cb.conversation( + key=s, cs=s*2, timeout=i, tweak1=i, tweak2=i+5, tweak3=i+10) convos = cb.conversations for convo, (i, s) in zip(convos, enumerate(map(str, range(200)))): - for item, value in zip(('key', 'cs', 'timeout'), (s, s*2, i)): + items = zip(('key', 'cs', 'timeout', 'tweak1', 'tweak2', 'tweak3'), + (s, s*2, i, i, i+5, i+10)) + for item, value in items: assert getattr(convo, item) == value def test_conversations_named(self, cb): - convos = {s: cb.conversation(s, key=s, cs=s*2, timeout=i) + convos = {s: cb.conversation(s, key=s, cs=s*2, timeout=i, tweak1=i, + tweak2=i+5, tweak3=i+10) for i, s in enumerate(map(str, range(200)))} for name, convo1 in cb.conversations.items(): convo2 = convos[name] - for item in ('key', 'cs', 'timeout'): + for item in ('key', 'cs', 'timeout', 'tweak1', 'tweak2', 'tweak3'): assert getattr(convo1, item) == getattr(convo2, item) def test_reset_nameless(self, cb_nameless): @@ -150,15 +215,19 @@ def test_reset_named(self, cb_named): class TestConversation: @pytest.fixture - def convo(self, cb, monkeypatch, request): - convo = cb.conversation(key='API_KEY', cs='76nxdxIJ02AAA', timeout=60) + def convo(self, cb, request, monkeypatch): + convo = cb.conversation(key='API_KEY', cs='76nxdxIJ02AAA', timeout=60, + tweak1=25, tweak2=50, tweak3=75) if hasattr(request, 'param'): @asyncio.coroutine def mock_get(url, params, headers, timeout): + class MockResponse(object): def __init__(self): if request.param.get('timeout'): raise asyncio.TimeoutError + if request.param.get('params'): + assert params == request.param['params'] self.status = request.param.get('status', 200) @asyncio.coroutine @@ -181,6 +250,34 @@ def test_getattr(self, convo): convo.data = {'test': 'value'} assert convo.test == 'value' + @pytest.mark.asyncio + @pytest.mark.parametrize( + 'convo', [ + {'params': { + 'input': 'test', 'key': 'key', 'cs': 'cs', 'timeout': 10, + 'wrapper': 'cleverbot.py', 'cb_settings_tweak1': 5, + 'cb_settings_tweak2': 10, 'cb_settings_tweak3': 15, + 'test': 'test' + }} + ], indirect=True + ) + def test_say_params(self, convo): + yield from convo.say('test', key='key', cs='cs', timeout=10, tweak1=5, + tweak2=10, tweak3=15, test='test') + + @pytest.mark.asyncio + @pytest.mark.parametrize( + 'convo', [ + {'params': { + 'key': 'API_KEY', 'cs': '76nxdxIJ02AAA', + 'wrapper': 'cleverbot.py', 'cb_settings_tweak1': 25, + 'cb_settings_tweak2': 50, 'cb_settings_tweak3': 75 + }} + ], indirect=True + ) + def test_say_params_empty(self, convo): + yield from convo.say() + @pytest.mark.asyncio @pytest.mark.parametrize( 'convo', [ @@ -208,11 +305,22 @@ def test_say_apierror(self, convo): assert e.status == 401 raise + @pytest.mark.asyncio + @pytest.mark.parametrize( + 'convo', [{'status': 401, 'json': {}}], indirect=True) + def test_say_apierror_empty(self, convo): + with pytest.raises(cleverbot.APIError): + yield from convo.say() + @pytest.mark.asyncio @pytest.mark.parametrize('convo', [{'timeout': True}], indirect=True) def test_say_timeout(self, convo): with pytest.raises(cleverbot.Timeout): - yield from convo.say() + try: + yield from convo.say() + except cleverbot.Timeout as e: + assert e.timeout == convo.timeout + raise def test_reset(self, convo): convo.reset() @@ -237,7 +345,7 @@ def test_cleverbot_load_nameless(self, cb, cb_nameless): with io.BytesIO(f.getvalue()) as f: cb.load(f) for convo1, convo2 in zip(cb.conversations, cb_nameless.conversations): - for item in ('key', 'cs', 'timeout'): + for item in ('key', 'cs', 'timeout', 'tweak1', 'tweak2', 'tweak3'): assert getattr(convo1, item) == getattr(convo2, item) def test_cleverbot_load_named(self, cb, cb_named): @@ -248,7 +356,7 @@ def test_cleverbot_load_named(self, cb, cb_named): cb.load(f) for name, convo1 in cb.conversations.items(): convo2 = convos[name] - for item in ('key', 'cs', 'timeout'): + for item in ('key', 'cs', 'timeout', 'tweak1', 'tweak2', 'tweak3'): assert getattr(convo1, item) == getattr(convo2, item) def test_load_nameless(self, cb_nameless): @@ -256,11 +364,12 @@ def test_load_nameless(self, cb_nameless): cb_nameless.save(f) with io.BytesIO(f.getvalue()) as f: cb = cleverbot.load(f) - for item in ('key', 'cs', 'timeout'): + for item in ('key', 'cs', 'timeout', 'tweak1', 'tweak2', 'tweak3'): assert getattr(cb, item) == getattr(cb_nameless, item) for convo1, convo2 in zip(cb.conversations, cb_nameless.conversations): - for item in ('key', 'cs', 'timeout'): + for item in ('key', 'cs', 'timeout', 'tweak1', 'tweak2', 'tweak3'): assert getattr(convo1, item) == getattr(convo2, item) + cb.close() def test_load_named(self, cb_named): convos = cb_named.conversations @@ -268,9 +377,10 @@ def test_load_named(self, cb_named): cb_named.save(f) with io.BytesIO(f.getvalue()) as f: cb = cleverbot.load(f) - for item in ('key', 'cs', 'timeout'): + for item in ('key', 'cs', 'timeout', 'tweak1', 'tweak2', 'tweak3'): assert getattr(cb, item) == getattr(cb_named, item) for name, convo1 in cb.conversations.items(): convo2 = convos[name] - for item in ('key', 'cs', 'timeout'): + for item in ('key', 'cs', 'timeout', 'tweak1', 'tweak2', 'tweak3'): assert getattr(convo1, item) == getattr(convo2, item) + cb.close() diff --git a/tests/test_cleverbot.py b/tests/test_cleverbot.py index 05ee898..4941301 100644 --- a/tests/test_cleverbot.py +++ b/tests/test_cleverbot.py @@ -1,13 +1,15 @@ import io -import cleverbot import pytest import requests +import cleverbot + @pytest.fixture -def cb(monkeypatch, request): - cb = cleverbot.Cleverbot('API_KEY', cs='76nxdxIJ02AAA', timeout=60) +def cb(request, monkeypatch): + cb = cleverbot.Cleverbot('API_KEY', cs='76nxdxIJ02AAA', timeout=60, + tweak1=25, tweak2=50, tweak3=75) if hasattr(request, 'param'): def mock_get(url, params, headers, timeout): @@ -15,6 +17,8 @@ class MockResponse(object): def __init__(self): if request.param.get('timeout'): raise requests.Timeout + if request.param.get('params'): + assert params == request.param['params'] self.status_code = request.param.get('status', 200) def json(self): @@ -29,7 +33,8 @@ def json(self): @pytest.fixture def cb_nameless(): - cb = cleverbot.Cleverbot('API_KEY', cs='76nxdxIJ02AAA', timeout=60) + cb = cleverbot.Cleverbot('API_KEY', cs='76nxdxIJ02AAA', timeout=60, + tweak1=25, tweak2=50, tweak3=75) for i, s in enumerate(map(str, range(200))): cb.conversation(key=s, cs=s, timeout=i) return cb @@ -37,7 +42,8 @@ def cb_nameless(): @pytest.fixture def cb_named(): - cb = cleverbot.Cleverbot('API_KEY', cs='76nxdxIJ02AAA', timeout=60) + cb = cleverbot.Cleverbot('API_KEY', cs='76nxdxIJ02AAA', timeout=60, + tweak1=25, tweak2=50, tweak3=75) for i, s in enumerate(map(str, range(200))): cb.conversation(s, key=s, cs=s, timeout=i) return cb @@ -46,10 +52,14 @@ def cb_named(): class TestCleverbot: def test_init(self): - cb = cleverbot.Cleverbot('API_KEY', cs='76nxdxIJ02AAA', timeout=60) + cb = cleverbot.Cleverbot('API_KEY', cs='76nxdxIJ02AAA', timeout=60, + tweak1=25, tweak2=50, tweak3=75) assert cb.key == 'API_KEY' assert cb.cs == '76nxdxIJ02AAA' assert cb.timeout == 60 + assert cb.tweak1 == 25 + assert cb.tweak2 == 50 + assert cb.tweak3 == 75 def test_cs(self): cb = cleverbot.Cleverbot(None, cs='76nxdxIJ02AAA') @@ -61,6 +71,32 @@ def test_getattr(self, cb): cb.data = {'test': 'value'} assert cb.test == 'value' + @pytest.mark.parametrize( + 'cb', [ + {'params': { + 'input': 'test', 'key': 'key', 'cs': 'cs', + 'wrapper': 'cleverbot.py', 'cb_settings_tweak1': 5, + 'cb_settings_tweak2': 10, 'cb_settings_tweak3': 15, + 'test': 'test' + }} + ], indirect=True + ) + def test_say_params(self, cb): + cb.say('test', key='key', cs='cs', tweak1=5, tweak2=10, tweak3=15, + test='test') + + @pytest.mark.parametrize( + 'cb', [ + {'params': { + 'input': None, 'key': 'API_KEY', 'cs': '76nxdxIJ02AAA', + 'wrapper': 'cleverbot.py', 'cb_settings_tweak1': 25, + 'cb_settings_tweak2': 50, 'cb_settings_tweak3': 75 + }} + ], indirect=True + ) + def test_say_params_empty(self, cb): + cb.say() + @pytest.mark.parametrize( 'cb', [ {'status': 200, 'json': { @@ -86,44 +122,69 @@ def test_say_apierror(self, cb): assert e.status == 401 raise + @pytest.mark.parametrize( + 'cb', [{'status': 401, 'json': {}}], indirect=True) + def test_say_apierror_empty(self, cb): + with pytest.raises(cleverbot.APIError): + cb.say() + @pytest.mark.parametrize('cb', [{'timeout': True}], indirect=True) def test_say_timeout(self, cb): with pytest.raises(cleverbot.Timeout): - cb.say() + try: + cb.say() + except cleverbot.Timeout as e: + assert e.timeout == cb.timeout + raise def test_conversation_empty(self, cb): convo = cb.conversation() assert convo.key == cb.key assert convo.cs is None assert convo.timeout == cb.timeout + assert convo.tweak1 == cb.tweak1 + assert convo.tweak2 == cb.tweak2 + assert convo.tweak3 == cb.tweak3 def test_conversation_nameless(self, cb): - convo = cb.conversation(key='key', cs='cs', timeout=10) + convo = cb.conversation( + key='key', cs='cs', timeout=10, tweak1=5, tweak2=10, tweak3=15) assert convo.key == 'key' assert convo.cs == 'cs' assert convo.timeout == 10 + assert convo.tweak1 == 5 + assert convo.tweak2 == 10 + assert convo.tweak3 == 15 def test_conversation_named(self, cb): - convo = cb.conversation('name', key='key', cs='cs', timeout=10) + convo = cb.conversation('name', key='key', cs='cs', timeout=10, + tweak1=5, tweak2=10, tweak3=15) assert convo.key == 'key' assert convo.cs == 'cs' assert convo.timeout == 10 + assert convo.tweak1 == 5 + assert convo.tweak2 == 10 + assert convo.tweak3 == 15 def test_conversations_nameless(self, cb): for i, s in enumerate(map(str, range(200))): - cb.conversation(key=s, cs=s*2, timeout=i) + cb.conversation( + key=s, cs=s*2, timeout=i, tweak1=i, tweak2=i+5, tweak3=i+10) convos = cb.conversations for convo, (i, s) in zip(convos, enumerate(map(str, range(200)))): - for item, value in zip(('key', 'cs', 'timeout'), (s, s*2, i)): + items = zip(('key', 'cs', 'timeout', 'tweak1', 'tweak2', 'tweak3'), + (s, s*2, i, i, i+5, i+10)) + for item, value in items: assert getattr(convo, item) == value def test_conversations_named(self, cb): convos = {} for i, s in enumerate(map(str, range(200))): - convos[s] = cb.conversation(s, key=s, cs=s*2, timeout=i) + convos[s] = cb.conversation( + s, key=s, cs=s*2, timeout=i, tweak1=i, tweak2=i+5, tweak3=i+10) for name, convo1 in cb.conversations.items(): convo2 = convos[name] - for item in ('key', 'cs', 'timeout'): + for item in ('key', 'cs', 'timeout', 'tweak1', 'tweak2', 'tweak3'): assert getattr(convo1, item) == getattr(convo2, item) def test_reset_nameless(self, cb_nameless): @@ -142,14 +203,18 @@ def test_reset_named(self, cb_named): class TestConversation: @pytest.fixture - def convo(self, cb, monkeypatch, request): - convo = cb.conversation(key='API_KEY', cs='76nxdxIJ02AAA', timeout=60) + def convo(self, cb, request, monkeypatch): + convo = cb.conversation(key='API_KEY', cs='76nxdxIJ02AAA', timeout=60, + tweak1=25, tweak2=50, tweak3=75) if hasattr(request, 'param'): def mock_get(url, params, headers, timeout): + class MockResponse(object): def __init__(self): if request.param.get('timeout'): raise requests.Timeout + if request.param.get('params'): + assert params == request.param['params'] self.status_code = request.param.get('status', 200) def json(self): @@ -171,6 +236,32 @@ def test_getattr(self, convo): convo.data = {'test': 'value'} assert convo.test == 'value' + @pytest.mark.parametrize( + 'convo', [ + {'params': { + 'input': 'test', 'key': 'key', 'cs': 'cs', + 'wrapper': 'cleverbot.py', 'cb_settings_tweak1': 5, + 'cb_settings_tweak2': 10, 'cb_settings_tweak3': 15, + 'test': 'test' + }} + ], indirect=True + ) + def test_say_params(self, convo): + convo.say('test', key='key', cs='cs', tweak1=5, tweak2=10, tweak3=15, + test='test') + + @pytest.mark.parametrize( + 'convo', [ + {'params': { + 'input': None, 'key': 'API_KEY', 'cs': '76nxdxIJ02AAA', + 'wrapper': 'cleverbot.py', 'cb_settings_tweak1': 25, + 'cb_settings_tweak2': 50, 'cb_settings_tweak3': 75 + }} + ], indirect=True + ) + def test_say_params_empty(self, convo): + convo.say() + @pytest.mark.parametrize( 'convo', [ {'status': 200, 'json': { @@ -196,10 +287,20 @@ def test_say_apierror(self, convo): assert e.status == 401 raise + @pytest.mark.parametrize( + 'convo', [{'status': 401, 'json': {}}], indirect=True) + def test_say_apierror_empty(self, convo): + with pytest.raises(cleverbot.APIError): + convo.say() + @pytest.mark.parametrize('convo', [{'timeout': True}], indirect=True) def test_say_timeout(self, convo): with pytest.raises(cleverbot.Timeout): - convo.say() + try: + convo.say() + except cleverbot.Timeout as e: + assert e.timeout == convo.timeout + raise def test_reset(self, convo): convo.reset() @@ -224,7 +325,7 @@ def test_cleverbot_load_nameless(self, cb, cb_nameless): with io.BytesIO(f.getvalue()) as f: cb.load(f) for convo1, convo2 in zip(cb.conversations, cb_nameless.conversations): - for item in ('key', 'cs', 'timeout'): + for item in ('key', 'cs', 'timeout', 'tweak1', 'tweak2', 'tweak3'): assert getattr(convo1, item) == getattr(convo2, item) def test_cleverbot_load_named(self, cb, cb_named): @@ -235,7 +336,7 @@ def test_cleverbot_load_named(self, cb, cb_named): cb.load(f) for name, convo1 in cb.conversations.items(): convo2 = convos[name] - for item in ('key', 'cs', 'timeout'): + for item in ('key', 'cs', 'timeout', 'tweak1', 'tweak2', 'tweak3'): assert getattr(convo1, item) == getattr(convo2, item) def test_load_nameless(self, cb_nameless): @@ -243,10 +344,10 @@ def test_load_nameless(self, cb_nameless): cb_nameless.save(f) with io.BytesIO(f.getvalue()) as f: cb = cleverbot.load(f) - for item in ('key', 'cs', 'timeout'): + for item in ('key', 'cs', 'timeout', 'tweak1', 'tweak2', 'tweak3'): assert getattr(cb, item) == getattr(cb_nameless, item) for convo1, convo2 in zip(cb.conversations, cb_nameless.conversations): - for item in ('key', 'cs', 'timeout'): + for item in ('key', 'cs', 'timeout', 'tweak1', 'tweak2', 'tweak3'): assert getattr(convo1, item) == getattr(convo2, item) def test_load_named(self, cb_named): @@ -255,9 +356,9 @@ def test_load_named(self, cb_named): cb_named.save(f) with io.BytesIO(f.getvalue()) as f: cb = cleverbot.load(f) - for item in ('key', 'cs', 'timeout'): + for item in ('key', 'cs', 'timeout', 'tweak1', 'tweak2', 'tweak3'): assert getattr(cb, item) == getattr(cb_named, item) for name, convo1 in cb.conversations.items(): convo2 = convos[name] - for item in ('key', 'cs', 'timeout'): + for item in ('key', 'cs', 'timeout', 'tweak1', 'tweak2', 'tweak3'): assert getattr(convo1, item) == getattr(convo2, item)