Skip to content

Commit cead10c

Browse files
Merge pull request #3 from plasma-umass/coverup-thyself
CoverUp, cover-up thyself.
2 parents fdb7582 + 9d47b7a commit cead10c

28 files changed

+695
-0
lines changed

tests/test_claude_coverup_1.py

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# file src/coverup/llm.py:47-51
2+
# lines [48, 49, 51]
3+
# branches ['48->49', '48->51']
4+
5+
import pytest
6+
from unittest.mock import patch
7+
from coverup.llm import token_rate_limit_for_model
8+
9+
@pytest.fixture
10+
def mock_model_rate_limits():
11+
with patch('coverup.llm.MODEL_RATE_LIMITS', {'model_a': {'token': (10, 20)}, 'model_b': {'token': (30, 40)}}):
12+
yield
13+
14+
def test_token_rate_limit_for_model(mock_model_rate_limits):
15+
# Test case when model_name is in MODEL_RATE_LIMITS
16+
assert token_rate_limit_for_model('model_a') == (10, 20)
17+
assert token_rate_limit_for_model('model_b') == (30, 40)
18+
19+
# Test case when model_name is not in MODEL_RATE_LIMITS
20+
assert token_rate_limit_for_model('unknown_model') is None

tests/test_claude_coverup_2.py

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# file src/coverup/utils.py:49-51
2+
# lines [50, 51]
3+
# branches ['50->exit', '50->51']
4+
5+
import pytest
6+
from coverup.utils import format_branches
7+
8+
@pytest.fixture
9+
def mock_branches():
10+
return [(1, 2), (3, 0), (5, 6)]
11+
12+
def test_format_branches(mock_branches):
13+
formatted_branches = list(format_branches(mock_branches))
14+
assert formatted_branches == ['1->2', '3->exit', '5->6']

tests/test_claude_coverup_4.py

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# file src/coverup/coverup.py:203-222
2+
# lines [204, 206, 207, 208, 209, 211, 213, 214, 215, 216, 217, 219, 220, 222]
3+
# branches ['213->214', '213->222', '214->215', '214->219', '215->213', '215->216', '216->215', '216->217', '219->213', '219->220']
4+
5+
import ast
6+
import pytest
7+
from coverup.coverup import find_imports
8+
9+
@pytest.fixture
10+
def python_code_with_syntax_error():
11+
return "invalid python code"
12+
13+
@pytest.fixture
14+
def python_code_with_imports():
15+
return """
16+
import os
17+
import sys
18+
from pathlib import Path
19+
import re
20+
"""
21+
22+
def test_find_imports_with_syntax_error(python_code_with_syntax_error):
23+
result = find_imports(python_code_with_syntax_error)
24+
assert result == []
25+
26+
def test_find_imports_with_valid_code(python_code_with_imports):
27+
result = find_imports(python_code_with_imports)
28+
assert set(result) == {"os", "sys", "pathlib", "re"}

tests/test_claude_coverup_5.py

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# file src/coverup/coverup.py:333-338
2+
# lines [335, 336, 337, 338]
3+
# branches ['336->exit', '336->337']
4+
5+
import pytest
6+
from unittest.mock import Mock
7+
from coverup.coverup import State, Progress
8+
9+
@pytest.fixture
10+
def state():
11+
return State(initial_coverage=0.0)
12+
13+
def test_set_progress_bar_with_bar(state):
14+
mock_bar = Mock(spec=Progress)
15+
state.usage = 'some_usage'
16+
state.counters = {'key': 'value'}
17+
18+
state.set_progress_bar(mock_bar)
19+
20+
assert state.bar == mock_bar
21+
mock_bar.update_usage.assert_called_once_with('some_usage')
22+
mock_bar.update_counters.assert_called_once_with({'key': 'value'})
23+
24+
def test_set_progress_bar_without_bar(state):
25+
state.set_progress_bar(None)
26+
27+
assert state.bar is None

tests/test_claude_coverup_6.py

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# file src/coverup/coverup.py:590-594
2+
# lines [591, 592, 593, 594]
3+
# branches []
4+
5+
import sys
6+
from pathlib import Path
7+
from unittest.mock import patch
8+
import os
9+
from coverup import coverup
10+
11+
def test_add_to_pythonpath(tmp_path):
12+
source_dir = tmp_path / "source"
13+
source_dir.mkdir()
14+
15+
with patch.dict('os.environ', {'PYTHONPATH': '/existing/path'}):
16+
coverup.add_to_pythonpath(source_dir)
17+
assert str(source_dir.parent) in sys.path[0]
18+
assert os.environ['PYTHONPATH'] == f"{str(source_dir.parent)}:/existing/path"
19+
20+
with patch.dict('os.environ', clear=True):
21+
coverup.add_to_pythonpath(source_dir)
22+
assert str(source_dir.parent) in sys.path[0]
23+
assert os.environ['PYTHONPATH'] == str(source_dir.parent)

tests/test_claude_coverup_7.py

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# file src/coverup/coverup.py:323-325
2+
# lines [325]
3+
# branches []
4+
5+
import pytest
6+
from unittest.mock import Mock
7+
from coverup.coverup import State
8+
9+
@pytest.fixture
10+
def state():
11+
initial_coverage = {"line1": True, "line2": False}
12+
state = State(initial_coverage)
13+
return state
14+
15+
def test_get_initial_coverage(state):
16+
expected_coverage = {"line1": True, "line2": False}
17+
assert state.get_initial_coverage() == expected_coverage

tests/test_claude_coverup_8.py

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# file src/coverup/coverup.py:328-330
2+
# lines [330]
3+
# branches []
4+
5+
import pytest
6+
from unittest.mock import Mock
7+
from coverup.coverup import State
8+
9+
@pytest.fixture
10+
def state():
11+
initial_coverage = Mock()
12+
return State(initial_coverage)
13+
14+
def test_set_final_coverage(state):
15+
expected_coverage = {'file1.py': 80, 'file2.py': 90}
16+
state.set_final_coverage(expected_coverage)
17+
assert state.final_coverage == expected_coverage

tests/test_claude_coverup_9.py

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# file src/coverup/coverup.py:254-256
2+
# lines [256]
3+
# branches []
4+
5+
import pytest
6+
import typing as T
7+
from unittest.mock import patch, MagicMock
8+
from coverup.coverup import get_required_modules
9+
10+
@pytest.fixture
11+
def mock_module_available():
12+
return {
13+
'module1': 1,
14+
'module2': 0,
15+
'module3': 1,
16+
'module4': 0
17+
}
18+
19+
def test_get_required_modules(mock_module_available):
20+
with patch('coverup.coverup.module_available', new=mock_module_available):
21+
result = get_required_modules()
22+
expected = ['module2', 'module4']
23+
assert sorted(result) == sorted(expected)

tests/test_openai_coverup_1.py

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# file src/coverup/coverup.py:453-457
2+
# lines []
3+
# branches ['456->456']
4+
5+
import pytest
6+
from coverup.coverup import extract_python
7+
8+
def test_extract_python_without_code_block():
9+
with pytest.raises(RuntimeError) as exc_info:
10+
extract_python("This is a response without a Python code block.")
11+
assert "Unable to extract Python code from response" in str(exc_info.value)

tests/test_openai_coverup_10.py

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# file src/coverup/coverup.py:341-347
2+
# lines [343, 344, 346, 347]
3+
# branches ['343->344', '343->346', '346->exit', '346->347']
4+
5+
import pytest
6+
from unittest.mock import Mock
7+
from src.coverup.coverup import State
8+
9+
@pytest.fixture
10+
def state_with_bar():
11+
initial_coverage = {'token1': 0, 'token2': 0}
12+
state = State(initial_coverage)
13+
state.usage = {'token1': 0, 'token2': 0}
14+
state.bar = Mock()
15+
return state
16+
17+
def test_add_usage_with_bar(state_with_bar):
18+
additional_usage = {'token1': 1, 'token2': 2}
19+
state_with_bar.add_usage(additional_usage)
20+
21+
assert state_with_bar.usage['token1'] == 1
22+
assert state_with_bar.usage['token2'] == 2
23+
state_with_bar.bar.update_usage.assert_called_once_with({'token1': 1, 'token2': 2})

tests/test_openai_coverup_11.py

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# file src/coverup/delta.py:5-32
2+
# lines [16, 18]
3+
# branches ['12->18', '13->16']
4+
5+
import pytest
6+
from pathlib import Path
7+
from src.coverup.delta import _compact
8+
9+
def test_compact_with_non_path_objects(monkeypatch):
10+
# Mocking Path to avoid filesystem dependency using monkeypatch
11+
monkeypatch.setattr('src.coverup.delta.Path', Path)
12+
13+
# Create a test set with non-Path objects
14+
test_set = {42, 'test_name', 3.14}
15+
16+
# Call the _compact function with the test set
17+
result = _compact(test_set)
18+
19+
# Verify that the non-Path objects are converted to strings and included in the result
20+
assert '42' in result
21+
assert 'test_name' in result
22+
assert '3.14' in result
23+
24+
# Verify that the result does not contain any range representation
25+
assert '-' not in result

tests/test_openai_coverup_12.py

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# file src/coverup/segment.py:66-67
2+
# lines [67]
3+
# branches []
4+
5+
import pytest
6+
from src.coverup.segment import CodeSegment
7+
8+
@pytest.fixture
9+
def code_segment():
10+
segment = CodeSegment(
11+
filename='test_file.py',
12+
name='test_segment',
13+
begin=1,
14+
end=10,
15+
lines_of_interest=set(range(1, 11)),
16+
missing_lines=set(),
17+
executed_lines=set(),
18+
missing_branches=set(),
19+
context={}
20+
)
21+
return segment
22+
23+
def test_missing_count_with_missing_lines_and_branches(code_segment):
24+
# Setup: Add missing lines and branches to the segment
25+
code_segment.missing_lines = {1, 2, 3}
26+
code_segment.missing_branches = {4, 5}
27+
28+
# Exercise: Call the method under test
29+
missing_count = code_segment.missing_count()
30+
31+
# Verify: Check if the missing count is correct
32+
assert missing_count == 5, "The missing count should be the sum of missing lines and branches"
33+
34+
# Cleanup: No cleanup required as the fixture will provide a fresh instance for each test

tests/test_openai_coverup_13.py

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# file src/coverup/segment.py:36-56
2+
# lines [46, 47]
3+
# branches ['45->46', '46->47', '46->56']
4+
5+
import pytest
6+
from coverup.segment import CodeSegment
7+
from unittest.mock import mock_open, patch
8+
9+
@pytest.fixture
10+
def code_segment():
11+
cs = CodeSegment(
12+
filename="fake_file.py",
13+
name="test_segment",
14+
begin=1,
15+
end=3,
16+
lines_of_interest=set(),
17+
missing_lines=set(),
18+
executed_lines=set(),
19+
missing_branches=set(),
20+
context=[]
21+
)
22+
return cs
23+
24+
def test_get_excerpt_without_executed_lines(code_segment, monkeypatch):
25+
mock_file_content = "line1\nline2\nline3\n"
26+
monkeypatch.setattr("builtins.open", mock_open(read_data=mock_file_content))
27+
excerpt = code_segment.get_excerpt()
28+
expected_excerpt = " line1\n line2\n"
29+
assert excerpt == expected_excerpt

tests/test_openai_coverup_14.py

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# file src/coverup/coverup.py:254-256
2+
# lines [256]
3+
# branches []
4+
5+
import pytest
6+
from unittest.mock import patch
7+
from coverup.coverup import get_required_modules
8+
9+
# Assuming module_available is a global variable or accessible within the scope
10+
# If it's not, you would need to mock or patch the appropriate object to provide it.
11+
12+
def test_get_required_modules():
13+
# Mock the module_available dictionary to include modules with different statuses
14+
mocked_module_available = {
15+
'module1': 0, # Not available
16+
'module2': 1, # Available
17+
'module3': 0, # Not available
18+
}
19+
20+
with patch('coverup.coverup.module_available', mocked_module_available):
21+
# Call the function under test
22+
result = get_required_modules()
23+
24+
# Verify that the result only includes the modules that were not available
25+
assert 'module1' in result
26+
assert 'module2' not in result
27+
assert 'module3' in result
28+
29+
# Verify that the length of the result is correct
30+
assert len(result) == 2
31+
32+
# No cleanup is necessary as the patch context manager will automatically undo the patch after the block

tests/test_openai_coverup_15.py

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# file src/coverup/utils.py:26-46
2+
# lines [30, 31, 33, 34, 35, 36, 37, 39, 40, 42, 44, 46]
3+
# branches ['34->exit', '34->35', '36->37', '36->39', '39->40', '39->42']
4+
5+
import pytest
6+
from coverup.utils import format_ranges
7+
8+
def test_format_ranges_with_negative_ranges():
9+
# Define the sets of lines and negative lines to pass to the function
10+
lines = {1, 2, 4, 5}
11+
negative = {3}
12+
13+
# Call the function with the test data
14+
result = format_ranges(lines, negative)
15+
16+
# Verify the result is as expected
17+
assert result == "1-2, 4-5", "The format_ranges function did not return the expected string"

0 commit comments

Comments
 (0)