Skip to content

Commit cb6b4a0

Browse files
committed
More tests for method class and cleanup from PR #2383 comments
1 parent e6f306c commit cb6b4a0

File tree

3 files changed

+99
-35
lines changed

3 files changed

+99
-35
lines changed

tests/core/method-class/test_method.py

Lines changed: 78 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
)
44
import pytest
55

6+
from eth_utils import (
7+
ValidationError,
8+
)
69
from eth_utils.toolz import (
710
compose,
811
)
@@ -69,7 +72,7 @@ def test_get_formatters_non_falsy_config_retrieval():
6972
first_formatter = (method.request_formatters(method_name).first,)
7073
all_other_formatters = method.request_formatters(method_name).funcs
7174
assert len(first_formatter + all_other_formatters) == 2
72-
# assert method.request_formatters('eth_nonmatching') == 'nonmatch'
75+
assert (method.request_formatters('eth_getBalance').first,) == first_formatter
7376

7477

7578
def test_input_munger_parameter_passthrough_matching_arity():
@@ -89,24 +92,87 @@ def test_input_munger_parameter_passthrough_mismatch_arity():
8992
method.input_munger(object(), ['first', 'second', 'third'], {})
9093

9194

92-
def test_input_munger_falsy_config_result_in_default_munger():
95+
def test_default_input_munger_with_no_input_parameters():
9396
method = Method(
94-
mungers=[],
97+
json_rpc_method='eth_method',
98+
)
99+
assert method.input_munger(object(), [], {}) == []
100+
101+
102+
@pytest.mark.parametrize('empty', ([], (), None), ids=['empty-list', 'empty-tuple', 'None'])
103+
def test_empty_input_munger_with_no_input_parameters(empty):
104+
method = Method(
105+
mungers=empty,
95106
json_rpc_method='eth_method',
96107
)
97108
assert method.input_munger(object(), [], {}) == []
98109

99110

100111
def test_default_input_munger_with_input_parameters():
101112
method = Method(
102-
mungers=[],
103113
json_rpc_method='eth_method',
104114
)
105115
assert method.input_munger(object(), [1], {}) == [1]
106116

107117

118+
@pytest.mark.parametrize('empty', ([], (), None), ids=['empty-list', 'empty-tuple', 'None'])
119+
def test_empty_input_mungers_with_input_parameters(empty):
120+
method = Method(
121+
mungers=empty,
122+
json_rpc_method='eth_method',
123+
)
124+
assert method.input_munger(object(), [1], {}) == [1]
125+
126+
127+
def test_default_munger_for_property_with_no_input_parameters():
128+
method = Method(
129+
is_property=True,
130+
json_rpc_method='eth_method',
131+
)
132+
assert method.input_munger(object(), [], {}) == ()
133+
134+
135+
@pytest.mark.parametrize('empty', ([], (), None), ids=['empty-list', 'empty-tuple', 'None'])
136+
def test_empty_mungers_for_property_with_no_input_parameters(empty):
137+
method = Method(
138+
is_property=True,
139+
mungers=empty,
140+
json_rpc_method='eth_method',
141+
)
142+
assert method.input_munger(object(), [], {}) == ()
143+
144+
145+
def test_default_munger_for_property_with_input_parameters_raises_ValidationError():
146+
method = Method(
147+
is_property=True,
148+
json_rpc_method='eth_method',
149+
)
150+
with pytest.raises(ValidationError, match='Parameters cannot be passed to a property'):
151+
method.input_munger(object(), [1], {})
152+
153+
154+
@pytest.mark.parametrize('empty', ([], (), None), ids=['empty-list', 'empty-tuple', 'None'])
155+
def test_empty_mungers_for_property_with_input_parameters_raises_ValidationError(empty):
156+
method = Method(
157+
is_property=True,
158+
mungers=empty,
159+
json_rpc_method='eth_method',
160+
)
161+
with pytest.raises(ValidationError, match='Parameters cannot be passed to a property'):
162+
method.input_munger(object(), [1], {})
163+
164+
165+
def test_property_with_mungers_raises_ValidationError():
166+
with pytest.raises(ValidationError, match='Mungers cannot be used with a property'):
167+
Method(
168+
is_property=True,
169+
mungers=[lambda m, z, y: 'success'],
170+
json_rpc_method='eth_method',
171+
)
172+
173+
108174
@pytest.mark.parametrize(
109-
"method_config,args,kwargs,expected_request_result,expected_result_formatters_len",
175+
"method_config,args,kwargs,expected_request_result",
110176
(
111177
(
112178
{
@@ -115,17 +181,15 @@ def test_default_input_munger_with_input_parameters():
115181
[],
116182
{},
117183
ValueError,
118-
2
119184
),
120185
(
121186
{
122187
'mungers': [],
123188
'json_rpc_method': 'eth_getBalance',
124189
},
125-
['unexpected_argument'],
190+
['only_the_first_argument_but_expects_two'],
126191
{},
127192
IndexError,
128-
2
129193
),
130194
(
131195
{
@@ -135,7 +199,6 @@ def test_default_input_munger_with_input_parameters():
135199
['0x0000000000000000000000000000000000000000', 3],
136200
{},
137201
('eth_getBalance', (('0x' + '00' * 20), "0x3")),
138-
2
139202
),
140203
(
141204
{
@@ -145,7 +208,6 @@ def test_default_input_munger_with_input_parameters():
145208
['0x0000000000000000000000000000000000000000', 3],
146209
{},
147210
('eth_getBalance', (('0x' + '00' * 20), "0x3")),
148-
2
149211
),
150212
(
151213
{
@@ -158,7 +220,6 @@ def test_default_input_munger_with_input_parameters():
158220
[1, 2, 3, ('0x' + '00' * 20)],
159221
{},
160222
('eth_getBalance', (('0x' + '00' * 20), "1")),
161-
2,
162223
),
163224
(
164225
{
@@ -171,7 +232,6 @@ def test_default_input_munger_with_input_parameters():
171232
[1, 2, 3, 4],
172233
{},
173234
TypeError,
174-
2,
175235
),
176236
(
177237
{
@@ -181,7 +241,6 @@ def test_default_input_munger_with_input_parameters():
181241
('0x0000000000000000000000000000000000000000', 3),
182242
{},
183243
('eth_getBalance', ('0x0000000000000000000000000000000000000000', '0x3')),
184-
2,
185244
),
186245
(
187246
{
@@ -190,7 +249,6 @@ def test_default_input_munger_with_input_parameters():
190249
('0x0000000000000000000000000000000000000000', 3),
191250
{},
192251
('eth_getBalance', ('0x0000000000000000000000000000000000000000', '0x3')),
193-
2,
194252
),
195253
(
196254
{
@@ -203,7 +261,6 @@ def test_default_input_munger_with_input_parameters():
203261
[('0x' + '00' * 20), 1, 2, 3],
204262
{},
205263
('eth_getBalance', (('0x' + '00' * 20), '1')),
206-
2,
207264
),
208265
(
209266
{
@@ -213,7 +270,6 @@ def test_default_input_munger_with_input_parameters():
213270
[],
214271
{},
215272
('eth_chainId', ()),
216-
2,
217273
),
218274
(
219275
{
@@ -223,16 +279,15 @@ def test_default_input_munger_with_input_parameters():
223279
[],
224280
{},
225281
('eth_chainId', ()),
226-
2,
227282
),
228283
),
229284
ids=[
230285
'raises-error-no-rpc-method',
231-
'test-unexpected-arg',
286+
'test-missing-argument',
232287
'test-rpc-method-as-string',
233288
'test-rpc-method-as-callable',
234289
'test-arg-munger',
235-
'test-munger-wrong-length-arg',
290+
'test-munger-too-many-args',
236291
'test-request-formatters-default-root-munger-explicit',
237292
'test-request-formatters-default-root-munger-implicit',
238293
'test-mungers-and-request-formatters',
@@ -245,7 +300,7 @@ def test_process_params(
245300
args,
246301
kwargs,
247302
expected_request_result,
248-
expected_result_formatters_len):
303+
):
249304

250305
if isclass(expected_request_result) and issubclass(expected_request_result, Exception):
251306
with pytest.raises(expected_request_result):
@@ -257,7 +312,9 @@ def test_process_params(
257312
assert request_params == expected_request_result
258313
first_formatter = (output_formatter[0].first,)
259314
all_other_formatters = output_formatter[0].funcs
260-
assert len(first_formatter + all_other_formatters) == expected_result_formatters_len
315+
316+
# the expected result formatters length is 2
317+
assert len(first_formatter + all_other_formatters) == 2
261318

262319

263320
def keywords(module, keyword_one, keyword_two):

tests/core/module-class/test_module.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,17 +59,20 @@ def test_attach_methods_to_module(web3_with_external_modules):
5959
def test_attach_methods_with_mungers(web3_with_external_modules):
6060
w3 = web3_with_external_modules
6161

62+
# `method1` uses `eth_getBlockByNumber` but makes use of unique mungers
6263
w3.module1.attach_methods({
6364
'method1': Method('eth_getBlockByNumber', mungers=[
64-
lambda _method, block_id, f, _z: (block_id, f),
65-
lambda _m, block_id, _f: (block_id - 1,),
65+
lambda _method, block_id, full_transactions: (block_id, full_transactions),
66+
# take the user-provided `block_id` and subtract 1
67+
lambda _method, block_id, full_transactions: (block_id - 1, full_transactions),
6668
]),
6769
})
6870

69-
assert w3.eth.get_block(0)['baseFeePerGas'] == 1000000000
70-
assert w3.eth.get_block(1)['baseFeePerGas'] == 875000000
71+
assert w3.eth.get_block(0, False)['baseFeePerGas'] == 1000000000
72+
assert w3.eth.get_block(1, False)['baseFeePerGas'] == 875000000
7173

72-
# `method1` should take a higher block number than `eth_getBlockByNumber` due to mungers and no
73-
# other params should matter
74-
assert w3.module1.method1(1, False, '_is_never_used_')['baseFeePerGas'] == 1000000000
75-
assert w3.module1.method1(2, '_will_be_overridden_', None)['baseFeePerGas'] == 875000000
74+
# Testing the mungers work:
75+
# `method1` also calls 'eth_getBlockByNumber' but subtracts 1 from the user-provided `block_id`
76+
# due to the second munger. So, `0` from above is a `1` here and `1` is `2`.
77+
assert w3.module1.method1(1, False)['baseFeePerGas'] == 1000000000
78+
assert w3.module1.method1(2, False)['baseFeePerGas'] == 875000000

web3/method.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
)
1616
import warnings
1717

18+
from eth_utils import (
19+
ValidationError,
20+
)
1821
from eth_utils.curried import (
1922
to_tuple,
2023
)
@@ -62,6 +65,9 @@ def inner(args: Any) -> TReturn:
6265

6366

6467
def _set_mungers(mungers: Optional[Sequence[Munger]], is_property: bool) -> Sequence[Any]:
68+
if is_property and mungers:
69+
raise ValidationError("Mungers cannot be used with a property.")
70+
6571
return (
6672
mungers if mungers
6773
else [default_munger] if is_property
@@ -70,10 +76,9 @@ def _set_mungers(mungers: Optional[Sequence[Munger]], is_property: bool) -> Sequ
7076

7177

7278
def default_munger(_module: "Module", *args: Any, **kwargs: Any) -> Tuple[()]:
73-
if not args and not kwargs:
74-
return ()
75-
else:
76-
raise TypeError("Parameters passed to method without parameter mungers defined.")
79+
if args or kwargs:
80+
raise ValidationError("Parameters cannot be passed to a property.")
81+
return ()
7782

7883

7984
def default_root_munger(_module: "Module", *args: Any) -> List[Any]:
@@ -136,7 +141,6 @@ def __init__(
136141
self.mungers = _set_mungers(mungers, is_property)
137142
self.request_formatters = request_formatters or get_request_formatters
138143
self.result_formatters = result_formatters or get_result_formatters
139-
self.error_formatters = get_error_formatters
140144
self.null_result_formatters = null_result_formatters or get_null_result_formatters
141145
self.method_choice_depends_on_args = method_choice_depends_on_args
142146
self.is_property = is_property
@@ -205,7 +209,7 @@ def process_params(
205209
method = self.method_selector_fn()
206210
response_formatters = (
207211
self.result_formatters(method, module),
208-
self.error_formatters(method),
212+
get_error_formatters(method),
209213
self.null_result_formatters(method),
210214
)
211215
request = (

0 commit comments

Comments
 (0)