Skip to content

Commit 4e9ae32

Browse files
committed
Add tests for Ruby modifiers, property analysis, and profiles
40 tests: 29 modifier tests (parametrized remove and guard clause tests, deterministic seeds, specific content assertions), 4 property analysis tests via conftest fixture, 11 profile tests covering both log parsers, parser delegation, eval_sets, and RSpec test path detection.
1 parent f5d3df6 commit 4e9ae32

File tree

8 files changed

+977
-0
lines changed

8 files changed

+977
-0
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import pytest
2+
from swesmith.bug_gen.adapters.ruby import get_entities_from_file_rb
3+
4+
5+
@pytest.fixture
6+
def ruby_test_file_entities(test_file_ruby):
7+
entities = []
8+
get_entities_from_file_rb(entities, test_file_ruby)
9+
assert len(entities) == 12
10+
return entities
11+
12+
13+
def test_parse_query_properties(ruby_test_file_entities):
14+
"""Test that parse_query entity has expected property tags."""
15+
entity_map = {e.name: e for e in ruby_test_file_entities}
16+
entity = entity_map["parse_query"]
17+
18+
assert entity.is_function is True
19+
assert entity.has_if is True
20+
assert entity.has_if_else is True
21+
assert entity.has_assignment is True
22+
assert entity.has_binary_op is True
23+
assert entity.has_function_call is True
24+
25+
26+
def test_normalize_params_properties(ruby_test_file_entities):
27+
"""Test that _normalize_params entity has expected property tags."""
28+
entity_map = {e.name: e for e in ruby_test_file_entities}
29+
entity = entity_map["_normalize_params"]
30+
31+
assert entity.is_function is True
32+
assert entity.has_if is True
33+
assert entity.has_if_else is True
34+
assert entity.has_return is True
35+
assert entity.has_assignment is True
36+
assert entity.has_binary_op is True
37+
assert entity.has_function_call is True
38+
39+
40+
def test_make_params_properties(ruby_test_file_entities):
41+
"""Test that make_params entity (simple method) has minimal tags."""
42+
entity_map = {e.name: e for e in ruby_test_file_entities}
43+
entity = entity_map["make_params"]
44+
45+
assert entity.is_function is True
46+
assert entity.has_if is False
47+
assert entity.has_loop is False
48+
assert entity.has_binary_op is False
49+
50+
51+
def test_comprehensive_ruby_properties(tmp_path):
52+
"""Test _analyze_properties with a comprehensive Ruby function."""
53+
comprehensive_ruby_code = """\
54+
def comprehensive_method(arr, threshold)
55+
return nil if arr.nil?
56+
sum = 0
57+
arr.each do |item|
58+
if item > threshold && item < 1000
59+
sum += item
60+
elsif item <= threshold
61+
sum -= item
62+
end
63+
end
64+
result = sum > 0 ? sum * 2 : 0
65+
process = ->(x) { x + 1 }
66+
process.call(result)
67+
end
68+
"""
69+
70+
test_file = tmp_path / "comprehensive.rb"
71+
test_file.write_text(comprehensive_ruby_code)
72+
73+
entities = []
74+
get_entities_from_file_rb(entities, test_file)
75+
76+
assert len(entities) == 1
77+
entity = entities[0]
78+
79+
assert entity.is_function is True
80+
assert entity.has_if is True
81+
assert entity.has_if_else is True
82+
assert entity.has_return is True
83+
assert entity.has_assignment is True
84+
assert entity.has_binary_op is True
85+
assert entity.has_bool_op is True
86+
assert entity.has_off_by_one is True
87+
assert entity.has_function_call is True
88+
assert entity.has_lambda is True
89+
assert entity.has_ternary is True

tests/bug_gen/procedural/ruby/__init__.py

Whitespace-only changes.
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import pytest
2+
3+
from swesmith.bug_gen.adapters.ruby import get_entities_from_file_rb
4+
from swesmith.bug_gen.procedural.ruby.control_flow import (
5+
ControlIfElseInvertModifier,
6+
ControlShuffleLinesModifier,
7+
GuardClauseInvertModifier,
8+
)
9+
10+
11+
def test_control_if_else_invert(tmp_path):
12+
src = """\
13+
def check(x, y)
14+
z = x + y
15+
if x > 0
16+
if y > 0
17+
"both positive"
18+
else
19+
"mixed"
20+
end
21+
else
22+
"non-positive"
23+
end
24+
end
25+
"""
26+
f = tmp_path / "test.rb"
27+
f.write_text(src)
28+
entities = []
29+
get_entities_from_file_rb(entities, f)
30+
assert len(entities) == 1
31+
32+
pm = ControlIfElseInvertModifier(likelihood=1.0, seed=42)
33+
assert pm.can_change(entities[0])
34+
35+
modified = pm.modify(entities[0])
36+
assert modified is not None
37+
# Outer if/else swapped: "non-positive" now in then-branch
38+
assert '"non-positive"' in modified.rewrite.split("if x > 0")[1].split("else")[0]
39+
40+
41+
def test_control_if_else_invert_no_else(tmp_path):
42+
src = """\
43+
def check(x)
44+
if x > 0
45+
"positive"
46+
end
47+
end
48+
"""
49+
f = tmp_path / "test.rb"
50+
f.write_text(src)
51+
entities = []
52+
get_entities_from_file_rb(entities, f)
53+
assert len(entities) == 1
54+
55+
pm = ControlIfElseInvertModifier(likelihood=1.0, seed=42)
56+
assert not pm.can_change(entities[0])
57+
58+
59+
def test_control_shuffle_lines(tmp_path):
60+
src = """\
61+
def setup
62+
@name = "test"
63+
@count = 0
64+
@ready = true
65+
while @count < 10
66+
@count += 1
67+
end
68+
end
69+
"""
70+
f = tmp_path / "test.rb"
71+
f.write_text(src)
72+
entities = []
73+
get_entities_from_file_rb(entities, f)
74+
assert len(entities) == 1
75+
76+
pm = ControlShuffleLinesModifier(likelihood=1.0, seed=42)
77+
assert pm.can_change(entities[0])
78+
79+
modified = pm.modify(entities[0])
80+
assert modified is not None
81+
# Statements reordered: @ready appears before @count
82+
lines = modified.rewrite.strip().split("\n")
83+
ready_idx = next(i for i, line in enumerate(lines) if "@ready" in line)
84+
count_idx = next(i for i, line in enumerate(lines) if "@count = 0" in line)
85+
assert ready_idx < count_idx
86+
87+
88+
@pytest.mark.parametrize("src,expected_keyword", [
89+
(
90+
"""\
91+
def process(x)
92+
return if x.nil?
93+
y = x + 1
94+
z = y * 2
95+
z
96+
end
97+
""",
98+
"return unless x.nil?",
99+
),
100+
(
101+
"""\
102+
def process(x)
103+
raise unless x.valid?
104+
y = x + 1
105+
z = y * 2
106+
x.perform(z)
107+
end
108+
""",
109+
"raise if x.valid?",
110+
),
111+
])
112+
def test_guard_clause_invert(tmp_path, src, expected_keyword):
113+
f = tmp_path / "test.rb"
114+
f.write_text(src)
115+
entities = []
116+
get_entities_from_file_rb(entities, f)
117+
assert len(entities) == 1
118+
119+
pm = GuardClauseInvertModifier(likelihood=1.0, seed=42)
120+
assert pm.can_change(entities[0])
121+
122+
modified = pm.modify(entities[0])
123+
assert modified is not None
124+
assert expected_keyword in modified.rewrite

0 commit comments

Comments
 (0)