Skip to content

Commit

Permalink
Updated, more coverage via running on different model and reiterating.
Browse files Browse the repository at this point in the history
  • Loading branch information
emeryberger committed Mar 24, 2024
1 parent 753c352 commit f7e5b88
Show file tree
Hide file tree
Showing 37 changed files with 435 additions and 0 deletions.
39 changes: 39 additions & 0 deletions tests/disabled_test_delta.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import pytest
from hypothesis import given, strategies as st
from pathlib import Path
from coverup.delta import DeltaDebugger


class NumbersFinder(DeltaDebugger):
def __init__(self, numbers: set):
super().__init__(trace=print)
self._numbers = numbers

def test(self, testset: set, **kwargs) -> bool:
return self._numbers.issubset(testset)


@given(st.integers(0, 50))
def test_single(culprit):
nf = NumbersFinder({culprit})
assert {culprit} == nf.debug(set(range(51)))


@given(st.lists(st.integers(0, 50), min_size=2).filter(lambda n: len(set(n)) == len(n)))
def test_multiple(nums):
nf = NumbersFinder({*nums})
assert {*nums} == nf.debug(set(range(51)))


@given(st.lists(st.integers(0, 50), min_size=2).filter(lambda n: len(set(n)) == len(n)))
def test_kwargs_passed_through(nums):
class DD(NumbersFinder):
def __init__(self, numbers: set):
super().__init__({*nums})

def test(self, testset: set, **kwargs) -> bool:
assert 'foo' in kwargs
return super().test(testset)

dd = DD({*nums})
assert {*nums} == dd.debug(set(range(51)), foo=True)
57 changes: 57 additions & 0 deletions tests/disabled_test_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import pytest
from hypothesis import given, strategies as st
from pathlib import Path
from coverup import utils
import subprocess

def test_format_ranges():
assert "" == utils.format_ranges(set(), set())
assert "1-5" == utils.format_ranges({1,2,3,5}, set())
assert "1-3, 5" == utils.format_ranges({1,2,3,5}, {4})
assert "1-6, 10-11, 30" == utils.format_ranges({1,2,4,5,6,10,11,30}, {8,14,15,16,17})


@given(st.integers(0, 10000), st.integers(1, 10000))
def test_format_ranges_is_sorted(a, b):
b = a+b
assert f"{a}-{b}" == utils.format_ranges({i for i in range(a,b+1)}, set())


def test_lines_branches_do():
assert "line 123 does" == utils.lines_branches_do({123}, set(), set())
assert "lines 123-125, 199 do" == utils.lines_branches_do({123,124,125,199}, {128}, set())
assert "branch 1->5 does" == utils.lines_branches_do(set(), set(), {(1,5)})
assert "branches 1->2, 1->5 do" == utils.lines_branches_do(set(), set(), {(1,5),(1,2)})
assert "line 123 and branches 1->exit, 1->2 do" == utils.lines_branches_do({123}, set(), {(1,2),(1,0)})
assert "lines 123-124 and branch 1->exit do" == utils.lines_branches_do({123, 124}, set(), {(1,0)})
assert "lines 123-125 and branches 1->exit, 1->2 do" == utils.lines_branches_do({123,124,125}, set(), {(1,2),(1,0)})

# if a line doesn't execute, neither do the branches that touch it...
assert "lines 123-125 do" == utils.lines_branches_do({123,124,125}, set(), {(123,124), (10,125)})


@pytest.mark.parametrize('check', [False, True])
@pytest.mark.asyncio
async def test_subprocess_run(check):
p = await utils.subprocess_run(['/bin/echo', 'hi!'], check=check)
assert p.stdout == b"hi!\n"


@pytest.mark.asyncio
async def test_subprocess_run_fails_checked():
with pytest.raises(subprocess.CalledProcessError) as e:
await utils.subprocess_run(['/usr/bin/false'], check=True)

assert e.value.stdout == b""


@pytest.mark.asyncio
async def test_subprocess_run_fails_not_checked():
p = await utils.subprocess_run(['/usr/bin/false'])
assert p.returncode != 0


@pytest.mark.asyncio
async def test_subprocess_run_timeout():
with pytest.raises(subprocess.TimeoutExpired) as e:
await utils.subprocess_run(['/bin/sleep', '2'], timeout=1)
20 changes: 20 additions & 0 deletions tests/test_claude_coverup_1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# file src/coverup/llm.py:47-51
# lines [48, 49, 51]
# branches ['48->49', '48->51']

import pytest
from unittest.mock import patch
from coverup.llm import token_rate_limit_for_model

@pytest.fixture
def mock_model_rate_limits():
with patch('coverup.llm.MODEL_RATE_LIMITS', {'model_a': {'token': (10, 20)}, 'model_b': {'token': (30, 40)}}):
yield

def test_token_rate_limit_for_model(mock_model_rate_limits):
# Test case when model_name is in MODEL_RATE_LIMITS
assert token_rate_limit_for_model('model_a') == (10, 20)
assert token_rate_limit_for_model('model_b') == (30, 40)

# Test case when model_name is not in MODEL_RATE_LIMITS
assert token_rate_limit_for_model('unknown_model') is None
14 changes: 14 additions & 0 deletions tests/test_claude_coverup_2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# file src/coverup/utils.py:49-51
# lines [50, 51]
# branches ['50->exit', '50->51']

import pytest
from coverup.utils import format_branches

@pytest.fixture
def mock_branches():
return [(1, 2), (3, 0), (5, 6)]

def test_format_branches(mock_branches):
formatted_branches = list(format_branches(mock_branches))
assert formatted_branches == ['1->2', '3->exit', '5->6']
32 changes: 32 additions & 0 deletions tests/test_claude_coverup_3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# file src/coverup/utils.py:6-23
# lines [9, 10, 11, 14, 15, 17, 18, 21, 22, 23]
# branches ['14->15', '14->17', '22->exit', '22->23']

import pytest
from pathlib import Path
from tempfile import TemporaryDirectory
from coverup.utils import TemporaryOverwrite

@pytest.fixture
def temp_dir():
with TemporaryDirectory() as tmp_dir:
yield Path(tmp_dir)

def test_temporary_overwrite(temp_dir, monkeypatch):
# Create a temporary file
file_path = temp_dir / "test_file.txt"
file_path.write_text("Initial content")

# Mock the Path.exists method
monkeypatch.setattr(Path, "exists", lambda self: True)

# Test the TemporaryOverwrite context manager
new_content = "New content"
with TemporaryOverwrite(file_path, new_content):
# Verify that the file content was overwritten
assert file_path.read_text() == new_content

# Verify that the file was restored to its original content
assert file_path.read_text() == "Initial content"

# Clean up the
28 changes: 28 additions & 0 deletions tests/test_claude_coverup_4.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# file src/coverup/coverup.py:203-222
# lines [204, 206, 207, 208, 209, 211, 213, 214, 215, 216, 217, 219, 220, 222]
# branches ['213->214', '213->222', '214->215', '214->219', '215->213', '215->216', '216->215', '216->217', '219->213', '219->220']

import ast
import pytest
from coverup.coverup import find_imports

@pytest.fixture
def python_code_with_syntax_error():
return "invalid python code"

@pytest.fixture
def python_code_with_imports():
return """
import os
import sys
from pathlib import Path
import re
"""

def test_find_imports_with_syntax_error(python_code_with_syntax_error):
result = find_imports(python_code_with_syntax_error)
assert result == []

def test_find_imports_with_valid_code(python_code_with_imports):
result = find_imports(python_code_with_imports)
assert set(result) == {"os", "sys", "pathlib", "re"}
27 changes: 27 additions & 0 deletions tests/test_claude_coverup_5.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# file src/coverup/coverup.py:333-338
# lines [335, 336, 337, 338]
# branches ['336->exit', '336->337']

import pytest
from unittest.mock import Mock
from coverup.coverup import State, Progress

@pytest.fixture
def state():
return State(initial_coverage=0.0)

def test_set_progress_bar_with_bar(state):
mock_bar = Mock(spec=Progress)
state.usage = 'some_usage'
state.counters = {'key': 'value'}

state.set_progress_bar(mock_bar)

assert state.bar == mock_bar
mock_bar.update_usage.assert_called_once_with('some_usage')
mock_bar.update_counters.assert_called_once_with({'key': 'value'})

def test_set_progress_bar_without_bar(state):
state.set_progress_bar(None)

assert state.bar is None
23 changes: 23 additions & 0 deletions tests/test_claude_coverup_6.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# file src/coverup/coverup.py:590-594
# lines [591, 592, 593, 594]
# branches []

import sys
from pathlib import Path
from unittest.mock import patch
import os
from coverup import coverup

def test_add_to_pythonpath(tmp_path):
source_dir = tmp_path / "source"
source_dir.mkdir()

with patch.dict('os.environ', {'PYTHONPATH': '/existing/path'}):
coverup.add_to_pythonpath(source_dir)
assert str(source_dir.parent) in sys.path[0]
assert os.environ['PYTHONPATH'] == f"{str(source_dir.parent)}:/existing/path"

with patch.dict('os.environ', clear=True):
coverup.add_to_pythonpath(source_dir)
assert str(source_dir.parent) in sys.path[0]
assert os.environ['PYTHONPATH'] == str(source_dir.parent)
17 changes: 17 additions & 0 deletions tests/test_claude_coverup_7.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# file src/coverup/coverup.py:323-325
# lines [325]
# branches []

import pytest
from unittest.mock import Mock
from coverup.coverup import State

@pytest.fixture
def state():
initial_coverage = {"line1": True, "line2": False}
state = State(initial_coverage)
return state

def test_get_initial_coverage(state):
expected_coverage = {"line1": True, "line2": False}
assert state.get_initial_coverage() == expected_coverage
17 changes: 17 additions & 0 deletions tests/test_claude_coverup_8.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# file src/coverup/coverup.py:328-330
# lines [330]
# branches []

import pytest
from unittest.mock import Mock
from coverup.coverup import State

@pytest.fixture
def state():
initial_coverage = Mock()
return State(initial_coverage)

def test_set_final_coverage(state):
expected_coverage = {'file1.py': 80, 'file2.py': 90}
state.set_final_coverage(expected_coverage)
assert state.final_coverage == expected_coverage
23 changes: 23 additions & 0 deletions tests/test_claude_coverup_9.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# file src/coverup/coverup.py:254-256
# lines [256]
# branches []

import pytest
import typing as T
from unittest.mock import patch, MagicMock
from coverup.coverup import get_required_modules

@pytest.fixture
def mock_module_available():
return {
'module1': 1,
'module2': 0,
'module3': 1,
'module4': 0
}

def test_get_required_modules(mock_module_available):
with patch('coverup.coverup.module_available', new=mock_module_available):
result = get_required_modules()
expected = ['module2', 'module4']
assert sorted(result) == sorted(expected)
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
24 changes: 24 additions & 0 deletions tests/test_openai_second_coverup_1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# file src/coverup/coverup.py:27-109
# lines []
# branches ['37->37', '103->103']

import pytest
from pathlib import Path
from unittest.mock import patch
from coverup.coverup import parse_args

def test_parse_args_with_invalid_dir_and_negative_int(tmp_path):
invalid_dir = tmp_path / "invalid_dir"
invalid_dir_file = tmp_path / "invalid_file.txt"
invalid_dir_file.touch()

with pytest.raises(SystemExit):
parse_args(['--tests-dir', str(invalid_dir), '--source-dir', str(tmp_path)])

with pytest.raises(SystemExit):
parse_args(['--tests-dir', str(tmp_path), '--source-dir', str(invalid_dir_file)])

with pytest.raises(SystemExit):
parse_args(['--max-concurrency', '-1'])

# Cleanup is not necessary as tmp_path is a fixture that automatically handles isolation
24 changes: 24 additions & 0 deletions tests/test_openai_second_coverup_2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# file src/coverup/utils.py:26-46
# lines [40]
# branches ['39->40']

import pytest
from coverup.utils import format_ranges

def test_format_ranges_single_line():
lines = {1, 2, 4}
negative = {3}
expected = "1-2, 4"
assert format_ranges(lines, negative) == expected

def test_format_ranges_with_negative_gap():
lines = {1, 2, 4, 5}
negative = {3}
expected = "1-2, 4-5"
assert format_ranges(lines, negative) == expected

def test_format_ranges_with_negative_gap_yielding_single_line():
lines = {1, 3, 5}
negative = {2, 4}
expected = "1, 3, 5"
assert format_ranges(lines, negative) == expected
31 changes: 31 additions & 0 deletions tests/test_openai_second_coverup_3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# file src/coverup/utils.py:6-23
# lines []
# branches ['14->17', '22->exit']

import pytest
from pathlib import Path
from coverup.utils import TemporaryOverwrite

@pytest.fixture
def temp_file(tmp_path):
file = tmp_path / "test.txt"
file.write_text("original content")
return file

@pytest.fixture
def non_existing_file(tmp_path):
return tmp_path / "non_existing.txt"

def test_temporary_overwrite_with_existing_file(temp_file):
new_content = "new content"
with TemporaryOverwrite(temp_file, new_content) as overwrite:
assert temp_file.read_text() == new_content
assert temp_file.read_text() == "original content"
assert not (temp_file.parent / (temp_file.name + ".bak")).exists()

def test_temporary_overwrite_with_non_existing_file(non_existing_file):
new_content = "new content"
with TemporaryOverwrite(non_existing_file, new_content) as overwrite:
assert non_existing_file.read_text() == new_content
assert not non_existing_file.exists()
assert not (non_existing_file.parent / (non_existing_file.name + ".bak")).exists()
Loading

0 comments on commit f7e5b88

Please sign in to comment.