mirror of
https://github.com/monero-project/monero.git
synced 2025-02-21 16:33:50 +02:00
Merge pull request #9761
ad782ded1
utils: Simplify python RPC Response implementation (iamamyth)
This commit is contained in:
commit
2fae69f623
@ -33,32 +33,22 @@ import json
|
||||
|
||||
class Response(dict):
|
||||
def __init__(self, d):
|
||||
for k in d.keys():
|
||||
if type(d[k]) == dict:
|
||||
self[k] = Response(d[k])
|
||||
elif type(d[k]) == list:
|
||||
self[k] = []
|
||||
for i in range(len(d[k])):
|
||||
if type(d[k][i]) == dict:
|
||||
self[k].append(Response(d[k][i]))
|
||||
else:
|
||||
self[k].append(d[k][i])
|
||||
else:
|
||||
self[k] = d[k]
|
||||
for k, v in d.items():
|
||||
self[k] = self._decode(v)
|
||||
|
||||
@staticmethod
|
||||
def _decode(o):
|
||||
if isinstance(o, dict):
|
||||
return Response(o)
|
||||
elif isinstance(o, list):
|
||||
return [Response._decode(i) for i in o]
|
||||
else:
|
||||
return o
|
||||
|
||||
def __getattr__(self, key):
|
||||
return self[key]
|
||||
def __setattr__(self, key, value):
|
||||
self[key] = value
|
||||
def __eq__(self, other):
|
||||
if type(other) == dict:
|
||||
return self == Response(other)
|
||||
if self.keys() != other.keys():
|
||||
return False
|
||||
for k in self.keys():
|
||||
if self[k] != other[k]:
|
||||
return False
|
||||
return True
|
||||
|
||||
class JSONRPC(object):
|
||||
def __init__(self, url, username=None, password=None):
|
||||
@ -73,7 +63,7 @@ class JSONRPC(object):
|
||||
headers={'content-type': 'application/json'},
|
||||
auth=HTTPDigestAuth(self.username, self.password) if self.username is not None else None)
|
||||
res = res.json()
|
||||
|
||||
|
||||
assert 'error' not in res, res
|
||||
|
||||
if result_field:
|
||||
|
134
utils/python-rpc/framework/test_rpc.py
Normal file
134
utils/python-rpc/framework/test_rpc.py
Normal file
@ -0,0 +1,134 @@
|
||||
#!/usr/bin/env python3
|
||||
import functools
|
||||
import unittest
|
||||
|
||||
from rpc import Response
|
||||
|
||||
|
||||
class TestResponse(unittest.TestCase):
|
||||
def test_init__empty(self):
|
||||
r = Response({})
|
||||
assert isinstance(r, Response)
|
||||
assert len(r) == 0
|
||||
|
||||
def test_init__scalar_values(self):
|
||||
r = Response(dict(k='v', k2='vv'))
|
||||
assert len(r) == 2
|
||||
assert r['k'] == 'v'
|
||||
assert r['k2'] == 'vv'
|
||||
|
||||
def test_init__response_value(self):
|
||||
child = Response(dict(ck='cv'))
|
||||
root = dict(k=child)
|
||||
r = Response(root)
|
||||
assert len(r) == 1
|
||||
assert isinstance(r['k'], Response)
|
||||
assert r['k'] == child
|
||||
assert r['k'] is not child
|
||||
|
||||
def test_init__dict_value(self):
|
||||
child = dict(ck='cv')
|
||||
root = dict(k=child)
|
||||
r = Response(root)
|
||||
assert len(r) == 1
|
||||
assert isinstance(r['k'], Response)
|
||||
assert r['k'] == Response(child)
|
||||
assert r['k'] is not child
|
||||
|
||||
def test_init__list_value(self):
|
||||
value = [1, 2]
|
||||
r = Response(dict(k=value))
|
||||
assert len(r) == 1
|
||||
assert r['k'] == value
|
||||
assert r['k'] is not value
|
||||
|
||||
def test_init__list_value_with_nested_response(self):
|
||||
nested = dict(ck=[1])
|
||||
root = dict(k=[nested])
|
||||
r = Response(root)
|
||||
assert len(r) == 1
|
||||
assert r['k'] == [Response(nested)]
|
||||
assert isinstance(r['k'][0], Response)
|
||||
|
||||
def test_init__list_value_with_nested_list(self):
|
||||
nested = [1, 2]
|
||||
root = dict(k=[nested])
|
||||
r = Response(root)
|
||||
assert len(r) == 1
|
||||
assert r['k'] == [nested]
|
||||
|
||||
def test_getattr__present(self):
|
||||
r = Response(dict(k='v'))
|
||||
assert r.k == 'v'
|
||||
|
||||
def test_getattr__missing(self):
|
||||
# This should raise an AttributeError to match the python data model.
|
||||
# However, to maintain backwards compatibility, it raises a KeyError.
|
||||
r = Response({})
|
||||
with self.assertRaises(KeyError):
|
||||
r.k
|
||||
|
||||
def test_setattr(self):
|
||||
r = Response({})
|
||||
r.k = 'v'
|
||||
assert r.k == 'v'
|
||||
assert r['k'] == 'v'
|
||||
|
||||
def test_eq__identity(self):
|
||||
r = Response({})
|
||||
assert r == r
|
||||
|
||||
def test_eq__empty(self):
|
||||
assert Response({}) == Response({})
|
||||
|
||||
def test_eq__nonnested_matching(self):
|
||||
assert Response(dict(k='v')) == Response(dict(k='v'))
|
||||
|
||||
def test_eq__nonnested_size_mismatch(self):
|
||||
assert Response(dict(k='v')) != Response(dict(k='v', k2='v'))
|
||||
|
||||
def test_eq__nonnested_key_mismatch(self):
|
||||
assert Response(dict(k='v')) != Response(dict(k2='v'))
|
||||
|
||||
def test_eq__nonnested_value_mismatch(self):
|
||||
assert Response(dict(k='v')) != Response(dict(k='v2'))
|
||||
|
||||
def test_eq__nested(self):
|
||||
def data():
|
||||
return dict(k='v', c=dict(ck='cv'))
|
||||
|
||||
assert Response(data()) == Response(data())
|
||||
|
||||
def test_eq__list_nonnested(self):
|
||||
def data():
|
||||
return dict(k=[1, 2])
|
||||
|
||||
assert Response(data()) == Response(data())
|
||||
|
||||
def test_eq__list_nested_response(self):
|
||||
def data():
|
||||
return dict(k=[Response(dict(ck=[1]))])
|
||||
|
||||
assert Response(data()) == Response(data())
|
||||
|
||||
def test_eq__list_nested_list(self):
|
||||
def data():
|
||||
return dict(k=[[Response(dict(k=1))]])
|
||||
|
||||
assert Response(data()) == Response(data())
|
||||
|
||||
def test_eq__dict__empty(self):
|
||||
assert Response({}) == {}
|
||||
|
||||
def test_eq__dict__nonnested(self):
|
||||
assert Response(dict(k='v')) == dict(k='v')
|
||||
|
||||
def test_eq__dict__nested(self):
|
||||
def data():
|
||||
return dict(k='v', c=dict(ck='cv'))
|
||||
|
||||
assert Response(data()) == data()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Loading…
Reference in New Issue
Block a user