Skip to content

Commit 774398f

Browse files
test: correct errors in tests
1 parent bf44b2a commit 774398f

File tree

9 files changed

+48
-33
lines changed

9 files changed

+48
-33
lines changed

natrix/ast_node.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -186,20 +186,19 @@ def memory_accesses(self) -> List[MemoryAccess]:
186186
if self.ast_type != "FunctionDef":
187187
raise ValueError("Not a function")
188188

189-
# Get all nodes that might have variable_reads or variable_writes
190-
all_nodes = self.get_descendants()
191-
if not all_nodes:
189+
attrs = self.get_descendants("Attribute")
190+
if not attrs:
192191
return []
193192

194193
accesses: List[MemoryAccess] = []
195194

196-
for node in all_nodes:
195+
for attr in attrs:
197196
for access_type in ("variable_reads", "variable_writes"):
198-
if access_type in node.node_dict:
199-
for item in node.get(access_type):
197+
if access_type in attr.node_dict:
198+
for item in attr.get(access_type):
200199
accesses.append(
201200
MemoryAccess(
202-
node=node,
201+
node=attr,
203202
type="read"
204203
if access_type == "variable_reads"
205204
else "write",

natrix/rules/unused_arg.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def visit_FunctionDef(self, node: FunctionDefNode):
2828
# Skip interface function definitions
2929
if node.is_from_interface:
3030
return
31-
31+
3232
# Collect declared arguments in a dictionary, {arg_name: arg_node}
3333
declared_args = {}
3434
for arg_info in node.get("args.args"):

tests/conftest.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,8 @@ def twocrypto_contract():
6666
@pytest.fixture()
6767
def for_loop_underscore_contract():
6868
return output_loader("for_loop_underscore")
69+
70+
71+
@pytest.fixture()
72+
def test_unused_arg_contract():
73+
return output_loader("test_unused_arg")

tests/contracts/test_unused_arg.vy

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# pragma version 0.4.0
2+
3+
def function_with_unused_arg(_used_arg: uint256, _unused_arg: address) -> uint256:
4+
return _used_arg * 2
5+
6+
def function_with_all_used_args(_arg1: uint256, _arg2: address) -> uint256:
7+
if _arg2 == empty(address):
8+
return _arg1
9+
return _arg1 + 1
10+
11+
# Interface function - arguments should not be flagged
12+
interface ITest:
13+
def some_interface_function(_interface_arg: uint256) -> bool: view

tests/rules/test_print_left.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ def test_print_left(uncached_contract):
66

77
issues = rule.run(uncached_contract)
88
assert len(issues) == 2
9-
assert issues[0].position == "12:8"
10-
assert issues[1].position == "15:8"
9+
assert issues[0].position == "17:8"
10+
assert issues[1].position == "20:8"
1111
assert (
1212
issues[0].message
1313
== "Found a 'print' statement; consider removing it in production code."

tests/rules/test_storage_caching.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ def test_storage_caching(uncached_contract):
66

77
issues = rule.run(uncached_contract)
88
assert len(issues) == 1
9-
assert issues[0].position == "28:7"
9+
assert issues[0].position == "33:7"
1010
assert (
1111
issues[0].message
1212
== "Storage variable 'a' is accessed multiple times; consider caching it to save gas."

tests/rules/test_unused_arg.py

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,39 @@
11
from natrix.rules.unused_arg import UnusedArgRule
2-
from natrix.ast_tools import parse_file
32

43

5-
def test_unused_arg():
4+
def test_unused_arg(test_unused_arg_contract):
65
"""
76
Test that the UnusedArgRule correctly identifies unused function arguments.
8-
7+
98
This test verifies that:
109
1. Unused arguments in regular functions are flagged
1110
2. Interface function definitions are not flagged
1211
"""
13-
# Parse the test file with unused arguments
14-
ast = parse_file("tests/test_unused_arg.vy")
15-
1612
rule = UnusedArgRule()
17-
issues = rule.run(ast)
18-
13+
issues = rule.run(test_unused_arg_contract)
14+
1915
# Check that only the unused argument is flagged
2016
assert len(issues) == 1
21-
assert issues[0].position == "2:49" # Line for _unused_arg
17+
assert issues[0].position == "3:49" # Line for _unused_arg
2218
assert "_unused_arg" in issues[0].message
2319
assert "function_with_unused_arg" in issues[0].message
24-
20+
2521
# Verify that used arguments are not flagged
2622
for issue in issues:
2723
assert "_used_arg" not in issue.message
2824
assert "_arg1" not in issue.message
2925
assert "_arg2" not in issue.message
3026

3127

32-
def test_interface_functions_not_flagged():
28+
def test_interface_functions_not_flagged(twocrypto_contract):
3329
"""
3430
Test that the UnusedArgRule does not flag interface function arguments.
35-
31+
3632
Uses the Twocrypto.vy contract which has interface function definitions.
3733
"""
38-
# Load the Twocrypto contract directly
39-
twocrypto_contract = parse_file("tests/contracts/Twocrypto.vy")
40-
4134
rule = UnusedArgRule()
4235
issues = rule.run(twocrypto_contract)
43-
36+
4437
# Check that no interface function arguments are flagged
4538
for issue in issues:
4639
# Make sure none of the interface function arguments are flagged

tests/rules/test_unused_variable.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ def test_unused_variable(uncached_contract):
3232
), "No issue found for 'another_unused_var'"
3333

3434
# Check the positions - these should be the declaration positions, not the reassignment positions
35-
assert hey_unused_var_issue.position == "6:4"
36-
assert another_unused_var_issue.position == "7:4"
35+
assert hey_unused_var_issue.position == "11:4"
36+
assert another_unused_var_issue.position == "12:4"
3737

3838
# Check the messages
3939
assert (
@@ -92,10 +92,12 @@ def test_for_loop_underscore(for_loop_underscore_contract):
9292
sorted_issues = sorted(issues, key=lambda x: int(x.position.split(":")[0]))
9393

9494
# Check exact line numbers and messages to prevent regressions
95-
assert sorted_issues[0].position == "23:4" # Line for another_unused_var
96-
assert sorted_issues[1].position == "24:4" # Line for hey_unused_var
97-
assert "another_unused_var" in sorted_issues[0].message
98-
assert "hey_unused_var" in sorted_issues[1].message
95+
assert sorted_issues[0].position == "6:8" # Line for i in for loop
96+
assert sorted_issues[1].position == "15:8" # Line for x variable
97+
assert sorted_issues[2].position == "18:4" # Line for unused_var
98+
assert "i" in sorted_issues[0].message
99+
assert "x" in sorted_issues[1].message
100+
assert "unused_var" in sorted_issues[2].message
99101

100102
# Verify that 'owner' is not in the issues
101103
for issue in issues:

tests/test_unused_arg.vy

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Test contract for unused argument rule
2+
def example_function(used_arg: uint256, _unused_arg: uint256) -> uint256:
3+
return used_arg

0 commit comments

Comments
 (0)