diff --git a/mockredis/script.py b/mockredis/script.py index c0a3d48..4031c28 100644 --- a/mockredis/script.py +++ b/mockredis/script.py @@ -47,7 +47,14 @@ def _call(*call_args): response = client.call(*call_args) return self._python_to_lua(response) - lua_globals.redis = {"call": _call} + def reply_table(field, msg): + return lua.eval("{{{}='{}'}}".format(field, msg)) + + lua_globals.redis = {"call": _call, + # TODO wrap _call with try to implement "pcall": _pcall, + "status_reply": lambda status: reply_table('ok', status), + "error_reply": lambda error: reply_table('err', error) + } return self._lua_to_python(lua.execute(self.script), return_status=True) @staticmethod diff --git a/mockredis/tests/fixtures.py b/mockredis/tests/fixtures.py index 980c07b..b0a9102 100644 --- a/mockredis/tests/fixtures.py +++ b/mockredis/tests/fixtures.py @@ -3,7 +3,7 @@ """ from contextlib import contextmanager -from nose.tools import assert_raises, raises +from nose.tools import assert_raises, raises, assert_raises_regexp, make_decorator from mockredis.noseplugin import WithRedis @@ -39,6 +39,21 @@ def raises_response_error(func): return raises(WithRedis.ResponseError)(func) +def raises_response_error_regex(regex): + """ + Test decorator that handles ResponseError or its mock equivalent + (currently ValueError) and verify it's message. + + mockredis does not currently raise redis-py's exceptions because it + does not current depend on redis-py strictly. + """ + def real_decorator(func): + def assert_func(*arg, **kw): + return assert_raises_regexp(WithRedis.ResponseError, regex, func, *arg, **kw) + return make_decorator(func)(assert_func) + return real_decorator + + @contextmanager def assert_raises_redis_error(): """ diff --git a/mockredis/tests/test_constants.py b/mockredis/tests/test_constants.py index 3d9030d..1c2fa5c 100644 --- a/mockredis/tests/test_constants.py +++ b/mockredis/tests/test_constants.py @@ -9,6 +9,9 @@ VAL3 = "val3" VAL4 = "val4" +OK_REPLY = "Good" +ERR_REPLY = "Bad" + LPOP_SCRIPT = "return redis.call('LPOP', KEYS[1])" bVAL1 = VAL1.encode('utf8') diff --git a/mockredis/tests/test_script.py b/mockredis/tests/test_script.py index bb000b6..e79e1d5 100644 --- a/mockredis/tests/test_script.py +++ b/mockredis/tests/test_script.py @@ -15,9 +15,9 @@ LIST1, LIST2, SET1, VAL1, VAL2, VAL3, VAL4, - LPOP_SCRIPT -) -from mockredis.tests.fixtures import raises_response_error + LPOP_SCRIPT, + OK_REPLY, ERR_REPLY) +from mockredis.tests.fixtures import raises_response_error, raises_response_error_regex if sys.version_info >= (3, 0): @@ -389,6 +389,17 @@ def test_lua_err_return(self): script = self.redis.register_script(script_content) script() + def test_lua_status_reply(self): + script_content = "return redis.status_reply('{}')".format(OK_REPLY) + script = self.redis.register_script(script_content) + eq_(OK_REPLY, script()) + + @raises_response_error_regex(ERR_REPLY) + def test_lua_err_reply(self): + script_content = "return redis.error_reply('{}')".format(ERR_REPLY) + script = self.redis.register_script(script_content) + script() + def test_concurrent_lua(self): script_content = """ local entry = redis.call('HGETALL', ARGV[1])