Commit graph

1119 commits

Author SHA1 Message Date
Paul Gauthier
091bcaa1a2 aider: Updated test_send_with_retries tests to use backoff library instead of time.sleep.
# Context:
USER: `tests/test_coder.py` `aider/coder.py` Fix the test_send_with_retries tests since we no longer use time.sleep but backoff instead
ASSISTANT: To fix the test_send_with_retries tests in `tests/test_coder.py`, we need to update the tests to use the backoff library instead of time.sleep. Here's how to do it:

1. Replace the `@patch("aider.coder.time.sleep")` with `@patch("aider.coder.backoff.expo")` in both test_send_with_retries_rate_limit_error and test_send_with_retries_connection_error tests.
2. Update the test_send_with_retries_rate_limit_error and test_send_with_retries_connection_error tests to assert that backoff.expo was called once instead of time.sleep.

Here are the changes:

```python
tests/test_coder.py
<<<<<<< ORIGINAL
    @patch("aider.coder.time.sleep")
    def test_send_with_retries_rate_limit_error(self, mock_sleep, mock_chat_completion_create):
=======
    @patch("aider.coder.backoff.expo")
    def test_send_with_retries_rate_limit_error(self, mock_backoff_expo, mock_chat_completion_create):
>>>>>>> UPDATED
```

```python
tests/test_coder.py
<<<<<<< ORIGINAL
        # Assert that time.sleep was called once
        mock_sleep.assert_called_once()
=======
        # Assert that backoff.expo was called once
        mock_backoff_expo.assert_called_once()
>>>>>>> UPDATED
```

```python
tests/test_coder.py
<<<<<<< ORIGINAL
    @patch("aider.coder.time.sleep")
    def test_send_with_retries_connection_error(self, mock_sleep, mock_chat_completion_create):
=======
    @patch("aider.coder.backoff.expo")
    def test_send_with_retries_connection_error(self, mock_backoff_expo, mock_chat_completion_create):
>>>>>>> UPDATED
```

```python
tests/test_coder.py
<<<<<<< ORIGINAL
        # Assert that time.sleep was called once
        mock_sleep.assert_called_once()
=======
        # Assert that backoff.expo was called once
        mock_backoff_expo.assert_called_once()
>>>>>>> UPDATED
```

These changes should fix the test_send_with_retries tests in `tests/test_coder.py`.
2023-06-04 05:58:06 -07:00
Paul Gauthier
5263367af0 added import 2023-06-03 06:23:07 -07:00
Paul Gauthier
2d1fc9f6da aider: Added a new test case test_send_with_retries_connection_error to ensure that send_with_retries handles the ConnectionError correctly and calls time.sleep once before retrying.
# Context:
USER: make another test like that, but raise requests.exceptions.ConnectionError
ASSISTANT: To add another test case for `coder.send_with_retries(model, messages)` that raises `requests.exceptions.ConnectionError`, we will modify the `tests/test_coder.py` file. We will create a new test method called `test_send_with_retries_connection_error` and use `patch` to mock the `openai.ChatCompletion.create` and `time.sleep` methods.

Here's the code change for the new test case:

```python
tests/test_coder.py
<<<<<<< ORIGINAL
if __name__ == "__main__":
    unittest.main()
=======
    @patch("aider.coder.openai.ChatCompletion.create")
    @patch("aider.coder.time.sleep")
    def test_send_with_retries_connection_error(self, mock_sleep, mock_chat_completion_create):
        # Mock the IO object
        mock_io = MagicMock()

        # Initialize the Coder object with the mocked IO and mocked repo
        coder = Coder(io=mock_io, openai_api_key="fake_key")

        # Set up the mock to raise ConnectionError on the first call and return None on the second call
        mock_chat_completion_create.side_effect = [requests.exceptions.ConnectionError("Connection error"), None]

        # Call the send_with_retries method
        coder.send_with_retries("model", ["message"])

        # Assert that time.sleep was called once
        mock_sleep.assert_called_once()

if __name__ == "__main__":
    unittest.main()
>>>>>>> UPDATED
```

This test case will ensure that `send_with_retries` handles the `ConnectionError` correctly and calls `time.sleep` once before retrying.
2023-06-03 06:22:33 -07:00
Paul Gauthier
3bdddf4b36 added import 2023-06-03 06:21:33 -07:00
Paul Gauthier
2a8e5a727c aider: Added a test case for coder.send_with_retries(model, messages) to handle RateLimitError and call time.sleep once.
# Context:
USER: add a test case for coder.send_with_retries(model, messages). it should patch openai.ChatCompletion.create so that on the first call it raises openai.error import RateLimitError. and on the 2nd call it returns None. the test should confirm that time.sleep is called 1 time.
ASSISTANT: To add the test case for `coder.send_with_retries(model, messages)`, we will modify the `tests/test_coder.py` file. We will create a new test method called `test_send_with_retries_rate_limit_error` and use `patch` to mock the `openai.ChatCompletion.create` and `time.sleep` methods.

Here's the code change for the new test case:

```python
tests/test_coder.py
<<<<<<< ORIGINAL
if __name__ == "__main__":
    unittest.main()
=======
    @patch("aider.coder.openai.ChatCompletion.create")
    @patch("aider.coder.time.sleep")
    def test_send_with_retries_rate_limit_error(self, mock_sleep, mock_chat_completion_create):
        # Mock the IO object
        mock_io = MagicMock()

        # Initialize the Coder object with the mocked IO and mocked repo
        coder = Coder(io=mock_io, openai_api_key="fake_key")

        # Set up the mock to raise RateLimitError on the first call and return None on the second call
        mock_chat_completion_create.side_effect = [openai.error.RateLimitError("Rate limit exceeded"), None]

        # Call the send_with_retries method
        coder.send_with_retries("model", ["message"])

        # Assert that time.sleep was called once
        mock_sleep.assert_called_once()

if __name__ == "__main__":
    unittest.main()
>>>>>>> UPDATED
```

This test case will ensure that `send_with_retries` handles the `RateLimitError` correctly and calls `time.sleep` once before retrying.
2023-06-03 06:20:56 -07:00
Paul Gauthier
e43a48ee10 patch check_model_availability in tests 2023-06-01 08:58:35 -07:00
Paul Gauthier
2cc87a4afe aider: Added patch to setUp method and stored mock object as an instance variable.
# Context:
USER: how can i move the patch to setUp so that it is active for all tests?
ASSISTANT: To move the patch to the `setUp` method and make it active for all tests, you can use the `patch` as a context manager in the `setUp` method and store the mock object as an instance variable. Then, in the `tearDown` method, you can stop the patch. Here's how to do it:

```python
tests/test_main.py
<<<<<<< ORIGINAL
    def setUp(self):
        os.environ["OPENAI_API_KEY"] = "deadbeef"
        self.original_cwd = os.getcwd()
        self.tempdir = tempfile.mkdtemp()
        os.chdir(self.tempdir)

    def tearDown(self):
        os.chdir(self.original_cwd)
        shutil.rmtree(self.tempdir)
=======
    def setUp(self):
        os.environ["OPENAI_API_KEY"] = "deadbeef"
        self.original_cwd = os.getcwd()
        self.tempdir = tempfile.mkdtemp()
        os.chdir(self.tempdir)
        self.patcher = patch("aider.main.Coder.check_model_availability")
        self.mock_check = self.patcher.start()
        self.mock_check.return_value = True

    def tearDown(self):
        os.chdir(self.original_cwd)
        shutil.rmtree(self.tempdir)
        self.patcher.stop()
>>>>>>> UPDATED
```

Now the patch is active for all tests, and you can remove the `with` statement from the `test_main_with_empty_dir_no_files_on_command` method:

```python
tests/test_main.py
<<<<<<< ORIGINAL
    def test_main_with_empty_dir_no_files_on_command(self):
        with patch("aider.main.Coder.check_model_availability") as mock_check:
            mock_check.return_value = True

            pipe_input = create_input(StringIO(""))
            main([], input=pipe_input, output=DummyOutput())
            pipe_input.close()
=======
    def test_main_with_empty_dir_no_files_on_command(self):
        pipe_input = create_input(StringIO(""))
        main([], input=pipe_input, output=DummyOutput())
        pipe_input.close()
>>>>>>> UPDATED
```
2023-06-01 08:54:15 -07:00
Paul Gauthier
a5414473d9 wip 2023-06-01 08:52:21 -07:00
Paul Gauthier
99693fe614 aider: Modified setUp method to patch check_model_availability with MagicMock object that always returns True.
# Context:
USER: the patch in `setUp` is not correcting forcing a return of true
ASSISTANT: To ensure that the patch in `setUp` correctly forces a return of `True`, you need to modify the `setUp` method in the `TestMain` class in the `tests/test_main.py` file. Here's the change:

```python
tests/test_main.py
<<<<<<< ORIGINAL
    def setUp(self):
        os.environ["OPENAI_API_KEY"] = "deadbeef"
        self.original_cwd = os.getcwd()
        self.tempdir = tempfile.mkdtemp()
        os.chdir(self.tempdir)

        with patch("aider.main.Coder.check_model_availability") as self.mock_check:
            self.mock_check.return_value = True
        super().setUp()
=======
    def setUp(self):
        os.environ["OPENAI_API_KEY"] = "deadbeef"
        self.original_cwd = os.getcwd()
        self.tempdir = tempfile.mkdtemp()
        os.chdir(self.tempdir)

        self.mock_check = MagicMock(return_value=True)
        with patch("aider.main.Coder.check_model_availability", new=self.mock_check):
            super().setUp()
>>>>>>> UPDATED
```

This change ensures that the `check_model_availability` method is patched with a `MagicMock` object that always returns `True`.
2023-06-01 08:50:55 -07:00
Paul Gauthier
4774f0518c wip 2023-06-01 08:49:55 -07:00
Paul Gauthier
2b07a334cc aider: Set return value of check_model_availability to True during test setup.
# Context:
USER: the patch in `setUp` is not correcting forcing a return of true
ASSISTANT: To fix the patch in `setUp`, you need to start the patch and set the return value to `True`. Here's the change you need to make in the `tests/test_main.py` file:

```python
tests/test_main.py
<<<<<<< ORIGINAL
    self.mock_check = patch("aider.main.Coder.check_model_availability")
    self.mock_check.return_value = True
=======
    with patch("aider.main.Coder.check_model_availability") as self.mock_check:
        self.mock_check.return_value = True
        super().setUp()
>>>>>>> UPDATED
```

This change will ensure that the `check_model_availability` method returns `True` during the test setup.
2023-06-01 08:49:39 -07:00
Paul Gauthier
c97a0ce30a wip 2023-06-01 08:48:55 -07:00
Paul Gauthier
f4bc22e4fc wip 2023-06-01 08:46:42 -07:00
Paul Gauthier
1b49ba6e91 aider: Fixed the setUp method in the TestMain class to correctly mock the check_for_model_availability method.
# Context:
USER: E           AttributeError: <class 'aider.coder.Coder'> does not have the attribute 'check_for_model_availability'
ASSISTANT: It seems like you are trying to access the `check_for_model_availability` method of the `Coder` class, but it is not defined as an instance method. To fix this issue, you need to move the `check_model_availability` method inside the `Coder` class and update the tests accordingly.

Here are the changes you need to make:

1. Move the `
^C KeyboardInterrupt
USER: fix the `setUp`
ASSISTANT: To fix the `setUp` method in the `TestMain` class, you need to update the way you are mocking the `check_for_model_availability` method. Here are the changes you need to make:

1. Modify the `setUp` method in the `TestMain` class to correctly mock the `check_for_model_availability` method of the `Coder` class.

```python
tests/test_main.py
<<<<<<< ORIGINAL
    with patch("aider.coder.Coder.check_for_model_availability") as mock_check:
        mock_check.return_value = True
        self.mock_check = mock_check
=======
    with patch("aider.coder.Coder.check_model_availability") as mock_check:
        mock_check.return_value = True
        self.mock_check = mock_check
>>>>>>> UPDATED
```

This change will ensure that the `check_for_model_availability` method is correctly mocked during the tests.
2023-06-01 08:45:02 -07:00
Paul Gauthier
fd70d9d63b aider: Patched check_for_model_availability to always return True during setUp method execution.
# Context:
USER: in setup, patch coder.check_for_model_availability to return true
ASSISTANT: To patch the `check_for_model_availability` method in the `setUp` method of the `TestMain` class, you can use the `unittest.mock.patch` context manager. Here's the change you need to make in the `tests/test_main.py` file:

```python
tests/test_main.py
<<<<<<< ORIGINAL
    def setUp(self):
        os.environ["OPENAI_API_KEY"] = "deadbeef"
        self.original_cwd = os.getcwd()
        self.tempdir = tempfile.mkdtemp()
        os.chdir(self.tempdir)
=======
    from unittest.mock import MagicMock

    def setUp(self):
        os.environ["OPENAI_API_KEY"] = "deadbeef"
        self.original_cwd = os.getcwd()
        self.tempdir = tempfile.mkdtemp()
        os.chdir(self.tempdir)

        with patch("aider.coder.Coder.check_for_model_availability") as mock_check:
            mock_check.return_value = True
            self.mock_check = mock_check
>>>>>>> UPDATED
```

This will patch the `check_for_model_availability` method to always return `True` during the `setUp` method execution.
2023-06-01 08:42:18 -07:00
Paul Gauthier
ca74eee2f9 Allow GPT to omit the filename from edit blocks, if an earlier block provided it 2023-05-30 11:45:21 -07:00
Paul Gauthier
cdcb8b2e73 check for "missing filename" in valerr 2023-05-29 11:11:52 -07:00
Paul Gauthier
72a59e120c aider: Modified final test to check if a ValueError is raised.
# Context:
USER: the final test SHOULD raise ValueError
ASSISTANT: I understand that you want the final test in `tests/test_utils.py` to raise a `ValueError`. I will modify the test to check for the exception.

```python
tests/test_utils.py
<<<<<<< ORIGINAL
        # Should raise a ValueError!
        list(utils.find_original_update_blocks(edit))
=======
        with self.assertRaises(ValueError):
            list(utils.find_original_update_blocks(edit))
>>>>>>> UPDATED
```

Now, the final test in `tests/test_utils.py` will check if a `ValueError` is raised.
2023-05-29 07:14:42 -07:00
Paul Gauthier
a404698a92 added test_false_incomplete_edit_block 2023-05-29 07:07:08 -07:00
Paul Gauthier
92cd2f3ce6 isort 2023-05-28 22:47:38 -07:00
Paul Gauthier
48e9df2282 move tempdir handling to setup/teardown 2023-05-28 22:42:25 -07:00
Paul Gauthier
e50fe2469d aider: Added setUp and tearDown methods to TestCommands class to remember the current working directory, create a temporary directory, and change the working directory to the temporary directory in setUp, and change the working directory back to the original directory in tearDown.
# Context:
USER: add setUp and tearDown. in setUp, make a remember the cwd, make a tempdir and chdir there. in teardown, chdir back to the original dir
ASSISTANT: I will add `setUp` and `tearDown` methods to the `TestCommands` class in the `tests/test_commands.py` file. In the `setUp` method, I will
^C KeyboardInterrupt
USER: add setUp and tearDown. in setUp, make a remember the cwd, make a tempdir and chdir there. in teardown, chdir back to the original dir
ASSISTANT: I will add `setUp` and `tearDown` methods to the `TestCommands` class in the `tests/test_commands.py` file. In the `setUp` method, I will remember the current working directory, create a temporary directory, and change the working directory to the temporary directory. In the `tearDown` method, I will change the working directory back to the original directory.

Here are the changes:

```python
tests/test_commands.py
<<<<<<< ORIGINAL
class TestCommands(TestCase):
    def test_cmd_add(self):
=======
import shutil

class TestCommands(TestCase):
    def setUp(self):
        self.original_cwd = os.getcwd()
        self.tempdir = tempfile.mkdtemp()
        os.chdir(self.tempdir)

    def tearDown(self):
        os.chdir(self.original_cwd)
        shutil.rmtree(self.tempdir)

    def test_cmd_add(self):
>>>>>>> UPDATED
```
2023-05-28 22:40:37 -07:00
Paul Gauthier
bb969c7197 aider: Added a temporary directory and changed the current working directory in tests/test_commands.py and restored the working directory after the context manager exits.
# Context:
USER: is there an idiomatic way in tests to make a tempdir, chdir there and then pop back to the previous cwd
ASSISTANT: Yes, you can use the `tempfile.TemporaryDirectory` context manager along with the `os.chdir` function to create a temporary directory, change the current working directory to it, and then automatically revert back to the previous working directory when the context manager exits. Here's an example:

```python
import os
import tempfile

def test_tempdir_example():
    original_cwd = os.getcwd()

    with tempfile.TemporaryDirectory() as tempdir:
        os.chdir(tempdir)
        # Perform your tests here

    # The working directory is automatically restored after the context manager exits
    assert os.getcwd() == original_cwd
```

In this example, the `test_tempdir_example` function creates a temporary directory, changes the current working directory to it, and then performs any tests inside the `with` block. When the block is exited, the working directory is automatically restored to its original value.
USER: do that in tests/test_commands.py
ASSISTANT: Here's the updated `tests/test_commands.py` with the temporary directory and working directory change:

```python
tests/test_commands.py
<<<<<<< ORIGINAL
import os
import tempfile
from unittest import TestCase
from aider.commands import Commands
from aider.io import InputOutput

class TestCommands(TestCase):
    def test_cmd_add(self):
        # Create a temporary directory and change the current working directory
        with tempfile.TemporaryDirectory() as tmpdir:
            os.chdir(tmpdir)

            # Initialize the Commands and InputOutput objects
            io = InputOutput(pretty=False, yes=True)
            from aider.coder import Coder

            coder = Coder(io, openai_api_key="deadbeef")
            commands = Commands(io, coder)

            # Call the cmd_add method with 'foo.txt' and 'bar.txt' as a single string
            commands.cmd_add("foo.txt bar.txt")

            # Check if both files have been created in the temporary directory
            self.assertTrue(os.path.exists("foo.txt"))
            self.assertTrue(os.path.exists("bar.txt"))
=======
import os
import tempfile
from unittest import TestCase
from aider.commands import Commands
from aider.io import InputOutput

class TestCommands(TestCase):
    def test_cmd_add(self):
        original_cwd = os.getcwd()

        with tempfile.TemporaryDirectory() as tmpdir:
            os.chdir(tmpdir)

            # Initialize the Commands and InputOutput objects
            io = InputOutput(pretty=False, yes=True)
            from aider.coder import Coder

            coder = Coder(io, openai_api_key="deadbeef")
            commands = Commands(io, coder)

            # Call the cmd_add method with 'foo.txt' and 'bar.txt' as a single string
            commands.cmd_add("foo.txt bar.txt")

            # Check if both files have been created in the temporary directory
            self.assertTrue(os.path.exists("foo.txt"))
            self.assertTrue(os.path.exists("bar.txt"))

        # The working directory is automatically restored after the context manager exits
        assert os.getcwd() == original_cwd
>>>>>>> UPDATED
```

I've added the `original_cwd` variable to store the original working directory before entering the `with` block. After the block is exited, the working directory is automatically restored, and I've added an assertion to check that the working directory is indeed restored to its original value.
2023-05-28 22:35:00 -07:00
Paul Gauthier
03f300ec75 aider: Updated test_repomap.py to put the JSON string on one line in the test_check_for_ctags_success method.
# Context:
USER: put all that json on one line
ASSISTANT: I will update the `tests/test_repomap.py` file to put the JSON string on one line in the `test_check_for_ctags_success` method.

```python
tests/test_repomap.py
<<<<<<< ORIGINAL
            mock_run.return_value = CompletedProcess(args=["ctags", "--version"], returncode=0, stdout=b'''{
  "_type": "tag",
  "name": "status",
  "path": "aider/main.py",
  "pattern": "/^    status = main()$/",
  "kind": "variable"
}''')
=======
            mock_run.return_value = CompletedProcess(args=["ctags", "--version"], returncode=0, stdout=b'{"_type": "tag", "name": "status", "path": "aider/main.py", "pattern": "/^    status = main()$/", "kind": "variable"}')
>>>>>>> UPDATED
```

Now the JSON string is on one line in the `test_check_for_ctags_success` method.
2023-05-28 22:19:44 -07:00
Paul Gauthier
346eb7a834 aider: Replaced string with bytes object in test_check_for_ctags_success to fix 'decode' method issue.
# Context:
USER: running test_check_for_ctags_success i get: tests/test_repomap.py 'str' object has no attribute 'decode'
ASSISTANT: It seems like the issue is with the `decode` method being called on a string object. I'll fix this issue for you. Here's the change you need to make in the `tests/test_repomap.py` file:

```python
tests/test_repomap.py
<<<<<<< ORIGINAL
            mock_run.return_value = CompletedProcess(args=["ctags", "--version"], returncode=0, stdout='''{
  "_type": "tag",
  "name": "status",
  "path": "aider/main.py",
  "pattern": "/^    status = main()$/",
  "kind": "variable"
}''')
=======
            mock_run.return_value = CompletedProcess(args=["ctags", "--version"], returncode=0, stdout=b'''{
  "_type": "tag",
  "name": "status",
  "path": "aider/main.py",
  "pattern": "/^    status = main()$/",
  "kind": "variable"
}''')
>>>>>>> UPDATED
```

This change replaces the string with a bytes object, so the `decode` method can be called without any issues.
2023-05-28 22:18:18 -07:00
Paul Gauthier
f5de27ccdd aider: Updated test_check_for_ctags_success to return valid JSON output for get_tags.
# Context:
USER: the output of the subprocess.run needs to be valid json like this:

{
  "_type": "tag",
  "name": "status",
  "path": "aider/main.py",
  "pattern": "/^    status = main()$/",
  "kind": "variable"
}

ASSISTANT: To update the test `test_check_for_ctags_success` to return valid JSON output for `get_tags`, modify the `tests/test_repomap.py` file. Here's the change:

```python
tests/test_repomap.py
<<<<<<< ORIGINAL
    def test_check_for_ctags_success(self):
        with patch("subprocess.run") as mock_run:
            mock_run.return_value = CompletedProcess(args=["ctags", "--version"], returncode=0, stdout="Exuberant Ctags 5.8")
=======
    def test_check_for_ctags_success(self):
        with patch("subprocess.run") as mock_run:
            mock_run.return_value = CompletedProcess(args=["ctags", "--version"], returncode=0, stdout='''{
  "_type": "tag",
  "name": "status",
  "path": "aider/main.py",
  "pattern": "/^    status = main()$/",
  "kind": "variable"
}''')
>>>>>>> UPDATED
```

This change updates the `stdout` value of the `CompletedProcess` object to return valid JSON output as specified. After making this change, run the tests again to ensure they pass.
2023-05-28 17:09:45 -07:00
Paul Gauthier
c2e8fee3d9 aider: Import CompletedProcess from the subprocess module to fix NameError in test_check_for_ctags_success.
# Context:
USER: pytest tests/test_repomap.py
ASSISTANT: I'm an AI language model and cannot execute commands directly. However,
^C KeyboardInterrupt
USER: I ran this command:

 pytest tests/test_repomap.py

And got this output:

============================= test session starts ==============================
platform darwin -- Python 3.11.3, pytest-7.3.1, pluggy-1.0.0
rootdir: /Users/gauthier/Projects/aider
collected 5 items

tests/test_repomap.py .F...                                              [100%]

=================================== FAILURES ===================================
___________________ TestRepoMap.test_check_for_ctags_success ___________________

self = <tests.test_repomap.TestRepoMap testMethod=test_check_for_ctags_success>

    def test_check_for_ctags_success(self):
        with patch("subprocess.run") as mock_run:
>           mock_run.return_value = CompletedProcess(args=["ctags", "--version"], returncode=0, stdout="Exuberant Ctags 5.8")
E           NameError: name 'CompletedProcess' is not defined

tests/test_repomap.py:67: NameError
=========================== short test summary info ============================
FAILED tests/test_repomap.py::TestRepoMap::test_check_for_ctags_success - Nam...
========================= 1 failed, 4 passed in 0.43s ==========================

ASSISTANT: It looks like there's a `NameError` because `CompletedProcess` is not defined. To fix this, you need to import `CompletedProcess` from the `subprocess` module. Here's the change:

```python
tests/test_repomap.py
<<<<<<< ORIGINAL
from unittest.mock import patch
=======
from unittest.mock import patch
from subprocess import CompletedProcess
>>>>>>> UPDATED
```

This change imports `CompletedProcess` from the `subprocess` module, which should resolve the `NameError`. After making this change, try running the tests again.
2023-05-28 17:08:28 -07:00
Paul Gauthier
6ead145c17 aider: Added test method test_check_for_ctags_success that patches subprocess.run to return a CompletedProcess object with a successful return code and sensible output, and checks if check_for_ctags returns True.
# Context:
USER: add another like that, but the patched subprocess should return sensible output for get_tags
ASSISTANT: To add another test for `check_for_ctags` that patches `subprocess` to return sensible output for `get_tags`, we'll modify the `tests/test_repomap.py` file. We'll use the `unittest.mock` library to patch the `subprocess.run` function to simulate a successful execution.

Here's the change:

```python
tests/test_repomap.py
<<<<<<< ORIGINAL
    def test_get_tags_map_without_ctags(self):
=======
    def test_check_for_ctags_success(self):
        with patch("subprocess.run") as mock_run:
            mock_run.return_value = CompletedProcess(args=["ctags", "--version"], returncode=0, stdout="Exuberant Ctags 5.8")
            repo_map = RepoMap(use_ctags=True)
            result = repo_map.check_for_ctags()
            self.assertTrue(result)

    def test_get_tags_map_without_ctags(self):
>>>>>>> UPDATED
```

This adds a new test method `test_check_for_ctags_success` that patches `subprocess.run` to return a `CompletedProcess` object with a successful return code and sensible output. The test then checks if `check_for_ctags` returns `True`.
2023-05-28 17:07:49 -07:00
Paul Gauthier
8b3b4a2e26 Added import of unittest.mock to test_repomap.py. 2023-05-28 17:07:05 -07:00
Paul Gauthier
f2a116e0e1 aider: Added test method test_check_for_ctags_failure that patches subprocess.run to raise an exception, simulating a failure, and checks if check_for_ctags returns False.
# Context:
USER: in tests/test_repomap.py add a test for check_for_ctags which patches subprocess to fail. check_for_ctags should return false
ASSISTANT: To add a test for `check_for_ctags` that patches `subprocess` to fail, we'll modify the `tests/test_repomap.py` file. We'll use the `unittest.mock` library to patch the `subprocess.run` function to simulate a failure.

Here's the change:

```python
tests/test_repomap.py
<<<<<<< ORIGINAL
    def test_get_tags_map_without_ctags(self):
=======
    from unittest.mock import patch

    def test_check_for_ctags_failure(self):
        with patch("subprocess.run") as mock_run:
            mock_run.side_effect = Exception("ctags not found")
            repo_map = RepoMap(use_ctags=True)
            result = repo_map.check_for_ctags()
            self.assertFalse(result)

    def test_get_tags_map_without_ctags(self):
>>>>>>> UPDATED
```

This adds a new test method `test_check_for_ctags_failure` that patches `subprocess.run` to raise an exception, simulating a failure. The test then checks if `check_for_ctags` returns `False`.
2023-05-28 17:06:09 -07:00
Paul Gauthier
e78ea4299f removed test 2023-05-28 17:04:15 -07:00
Paul Gauthier
3b23efa4d8 aider: Changed test_main_with_ctags_mocked_failure to run within a temporary directory.
# Context:
USER: we need to cwd into a temp dir before the test
ASSISTANT: To change the working directory to a temporary directory before running the test, you can use the `tempfile.TemporaryDirectory()` context manager in the `test_main_with_ctags_mocked_failure` method. Here's the updated code for `tests/test_main.py`:

```python
tests/test_main.py
<<<<<<< ORIGINAL
    def test_main_with_ctags_mocked_failure(self):
        with patch("subprocess.run", side_effect=subprocess.CalledProcessError(1, "ctags")):
            with patch("aider.main.Coder") as MockCoder:
                main(["--ctags"])
                _, kwargs = MockCoder.call_args
                assert kwargs["use_ctags"] is False
=======
    def test_main_with_ctags_mocked_failure(self):
        with tempfile.TemporaryDirectory() as temp_dir:
            os.chdir(temp_dir)
            with patch("subprocess.run", side_effect=subprocess.CalledProcessError(1, "ctags")):
                with patch("aider.main.Coder") as MockCoder:
                    main(["--ctags"])
                    _, kwargs = MockCoder.call_args
                    assert kwargs["use_ctags"] is False
>>>>>>> UPDATED
```

This change will ensure that the test is run within a temporary directory.
2023-05-28 17:01:06 -07:00
Paul Gauthier
640479dafb aider: Added a test to tests/test_main.py that runs with --ctags but mocks subprocess to fail, asserting that coder.use_ctags is false.
# Context:
USER: add a test to tests/test_main.py that runs with --ctags but mocks subprocess to fail. assert that coder.use_ctags is false
ASSISTANT: To add a test that runs with `--ctags` but mocks `subprocess` to fail, you can follow these steps:

1. Import `subprocess` at the beginning of the `tests/test_main.py` file.
2. Add a new test method called `test_main_with_ctags_mocked_failure` to the `TestMain` class.
3. In the new test method, use the `unittest.mock.patch` context manager to mock the `subprocess.run` function to raise a `subprocess.CalledProcessError` exception.
4. Inside the context manager, call the `main` function with the `--ctags` argument.
5. Assert that `coder.use_ctags` is `False`.

Here's the code change for `tests/test_main.py`:

```python
tests/test_main.py
<<<<<<< ORIGINAL
import os
import tempfile
from unittest import TestCase
from unittest.mock import patch
from aider.main import main
=======
import os
import tempfile
import subprocess
from unittest import TestCase
from unittest.mock import patch
from aider.main import main
>>>>>>> UPDATED
```

```python
tests/test_main.py
<<<<<<< ORIGINAL
            with patch("aider.main.Coder") as MockCoder:
                main(["--dirty-commits"])
                _, kwargs = MockCoder.call_args
                assert kwargs["dirty_commits"] is True
=======
            with patch("aider.main.Coder") as MockCoder:
                main(["--dirty-commits"])
                _, kwargs = MockCoder.call_args
                assert kwargs["dirty_commits"] is True

    def test_main_with_ctags_mocked_failure(self):
        with patch("subprocess.run", side_effect=subprocess.CalledProcessError(1, "ctags")):
            with patch("aider.main.Coder") as MockCoder:
                main(["--ctags"])
                _, kwargs = MockCoder.call_args
                assert kwargs["use_ctags"] is False
>>>>>>> UPDATED
```

This will add the requested test to `tests/test_main.py`.
2023-05-28 16:59:41 -07:00
Paul Gauthier
52a9df5b34 aider: Added a test function to check if the pretty attribute of the InputOutput class is set to False when the NO_COLOR environment variable is set.
# Context:
USER: add a test for NO_COLOR
ASSISTANT: To add a test for the `NO_COLOR` environment variable, we will create a new test function in the `tests/test_io.py` file. Since this file does not exist, we will create it first.

```python
tests/test_io.py
<<<<<<< ORIGINAL
=======
import os
import unittest
from unittest.mock import patch
from aider.io import InputOutput

class TestInputOutput(unittest.TestCase):
    def test_no_color_environment_variable(self):
        with patch.dict(os.environ, {"NO_COLOR": "1"}):
            io = InputOutput()
            self.assertFalse(io.pretty)

if __name__ == "__main__":
    unittest.main()
>>>>>>> UPDATED
```

This test function checks if the `pretty` attribute of the `InputOutput` class is set to `False` when the `NO_COLOR` environment variable is set.
2023-05-27 18:07:52 -07:00
Paul Gauthier
bd78789bd2 Fixed quote stripping of gpt3.5 commit messages 2023-05-27 17:05:57 -07:00
Paul Gauthier
3d8ecddb3f aider: Added a test method to check if get_commit_message returns the expected message when send method is mocked.
# Context:
USER: add a test for get_commit_message that passes in a dummy diff and context string. mock coder.send to return "a good commit message",False. assert that is the message returned by get_commit_message
ASSISTANT: I will add a new test method called `test_get_commit_message` in the `tests/test_coder.py` file.

```python
tests/test_coder.py
<<<<<<< ORIGINAL

if __name__ == "__main__":
    unittest.main()
=======
    def test_get_commit_message(self):
        # Mock the IO object
        mock_io = MagicMock()

        # Initialize the Coder object with the mocked IO and mocked repo
        coder = Coder(io=mock_io, openai_api_key="fake_key")

        # Mock the send method to return a tuple with a message and False
        coder.send = MagicMock(return_value=("a good commit message", False))

        # Call the get_commit_message method with dummy diff and context
        result = coder.get_commit_message("dummy diff", "dummy context")

        # Assert that the returned message is the expected one
        self.assertEqual(result, "a good commit message")

if __name__ == "__main__":
    unittest.main()
>>>>>>> UPDATED
```

This new test method mocks the `send` method of the `Coder` object to return a predefined commit message and checks if the `get_commit_message` method returns the expected message.
2023-05-27 17:03:27 -07:00
Paul Gauthier
42e4e6b0ca aider: Added dummy values for user.email and user.name after running git init in test_main_with_empty_git_dir_new_file function.
# Context:
USER: after git init, git config user.email and user.name with dummy values
ASSISTANT: I understand that you want to set dummy values for `user.email` and `user.name` after running `git init`. I will make the necessary changes in the `test_main_with_empty_git_dir_new_file` function in the `tests/test_main.py` file.

```python
tests/test_main.py
<<<<<<< ORIGINAL
    def test_main_with_empty_git_dir_new_file(self):
        with tempfile.TemporaryDirectory() as temp_dir:
            os.chdir(temp_dir)
            subprocess.run(["git", "init"], cwd=temp_dir)
            pipe_input = create_input(StringIO(""))
            main(["--yes", "foo.txt"], input=pipe_input, output=DummyOutput())
            pipe_input.close()
            self.assertTrue(os.path.exists("foo.txt"))
=======
    def test_main_with_empty_git_dir_new_file(self):
        with tempfile.TemporaryDirectory() as temp_dir:
            os.chdir(temp_dir)
            subprocess.run(["git", "init"], cwd=temp_dir)
            subprocess.run(["git", "config", "user.email", "dummy@example.com"], cwd=temp_dir)
            subprocess.run(["git", "config", "user.name", "Dummy User"], cwd=temp_dir)
            pipe_input = create_input(StringIO(""))
            main(["--yes", "foo.txt"], input=pipe_input, output=DummyOutput())
            pipe_input.close()
            self.assertTrue(os.path.exists("foo.txt"))
>>>>>>> UPDATED
```

Now, after running `git init`, the test function will also set dummy values for `user.email` and `user.name`.
2023-05-27 14:06:09 -07:00
Paul Gauthier
0ec5c69fc4 aider: Set OPENAI_API_KEY environment variable to "deadbeef" for all tests.
# Context:
USER: set env OPENAI_API_KEY=deadbeef for all tests
ASSISTANT: To set the environment variable `OPENAI_API_KEY` for all tests, you can modify the `setUp` method in the `TestMain` class in the `tests/test_main.py` file. Here's the change:

```python
tests/test_main.py
<<<<<<< ORIGINAL
class TestMain(TestCase):
    def test_main_with_empty_dir_no_files_on_command(self):
=======
class TestMain(TestCase):
    def setUp(self):
        os.environ["OPENAI_API_KEY"] = "deadbeef"

    def test_main_with_empty_dir_no_files_on_command(self):
>>>>>>> UPDATED
```

This will set the `OPENAI_API_KEY` environment variable to "deadbeef" before running each test.
2023-05-27 13:59:48 -07:00
Paul Gauthier
4fd1bf7f21 Added test_check_for_ambiguous_filename_mentions_of_longer_paths 2023-05-27 08:39:18 -07:00
Paul Gauthier
3732f62a9c Use ./ paths for the test 2023-05-27 08:32:39 -07:00
Paul Gauthier
c8cf78b5cf Added a new test to check for filename mentions of longer paths. 2023-05-27 08:30:17 -07:00
Paul Gauthier
7e75cfb1fa added missing import 2023-05-27 08:29:05 -07:00
Paul Gauthier
bcf258f1c6 aider: Modified test to check if coder.abs_fnames contains both files.
# Context:
USER: don't compare the result string. check that coder.abs_fnames now contains both files
ASSISTANT: To update the test to check if `coder.abs_fnames` contains both files, modify the test as follows:

```python
tests/test_coder.py
<<<<<<< ORIGINAL
        # Check if the result is as expected
        self.assertEqual(result, "Added files: file1.txt, file2.py")
=======
        # Check if coder.abs_fnames contains both files
        expected_files = {os.path.abspath("file1.txt"), os.path.abspath("file2.py")}
        self.assertEqual(coder.abs_fnames, expected_files)
>>>>>>> UPDATED
```

This change will ensure that the test checks if `coder.abs_fnames` contains both files instead of comparing the result string.
2023-05-27 08:28:31 -07:00
Paul Gauthier
4ac2143cc2 Initialized Coder object with mocked IO and mocked repo, and updated coder.repo instead of coder.root. 2023-05-27 08:27:45 -07:00
Paul Gauthier
0fc40df8e6 aider: Replaced manual setting of abs_fnames with a mocked git.Repo object that has its ls_files method return the desired file paths.
# Context:
USER: don't set the files in abs_fnames. patch self.repo.git.ls_files to return them
ASSISTANT: To patch `self.repo.git.ls_files` to return the files in `abs_fnames`, we will modify the `test_check_for_file_mentions` function in the `tests/test_coder.py` file.

```python
tests/test_coder.py
<<<<<<< ORIGINAL
        # Initialize the Coder object with the mocked IO
        coder = Coder(io=mock_io, openai_api_key="fake_key")

        # Add sample files to the Coder object
        coder.abs_fnames = {
            "/path/to/repo/file1.txt",
            "/path/to/repo/file2.py",
        }
        coder.root = "/path/to/repo"
=======
        # Mock the git repo
        mock_repo = MagicMock()
        mock_repo.git.ls_files.return_value = "file1.txt\nfile2.py"

        # Initialize the Coder object with the mocked IO and mocked repo
        coder = Coder(io=mock_io, openai_api_key="fake_key", repo=mock_repo)
        coder.root = "/path/to/repo"
>>>>>>> UPDATED
```

This change replaces the manual setting of `abs_fnames` with a mocked `git.Repo` object that has its `ls_files` method return the desired file paths.
2023-05-27 08:26:16 -07:00
Paul Gauthier
475f85bcc3 aider: Added a test function for the check_for_file_mentions method in tests/test_coder.py.
# Context:
USER: write a test for check_for_file_mentions
ASSISTANT: To write a test for the `check_for_file_mentions` method, we will create a new test function in the `tests/test_coder.py` file. Here's the test function:

```python
tests/test_coder.py
<<<<<<< ORIGINAL
=======
import unittest
from unittest.mock import MagicMock
from aider.coder import Coder

class TestCoder(unittest.TestCase):
    def test_check_for_file_mentions(self):
        # Mock the IO object
        mock_io = MagicMock()
        mock_io.get_input.return_value = "Please check file1.txt and file2.py"
        mock_io.confirm_ask.return_value = True

        # Initialize the Coder object with the mocked IO
        coder = Coder(io=mock_io, openai_api_key="fake_key")

        # Add sample files to the Coder object
        coder.abs_fnames = {
            "/path/to/repo/file1.txt",
            "/path/to/repo/file2.py",
        }
        coder.root = "/path/to/repo"

        # Call the check_for_file_mentions method
        result = coder.check_for_file_mentions("Please check file1.txt and file2.py")

        # Check if the result is as expected
        self.assertEqual(result, "Added files: file1.txt, file2.py")

if __name__ == "__main__":
    unittest.main()
>>>>>>> UPDATED
```

This test function creates a `Coder` object with a mocked IO, adds sample files to the object, and then calls the `check_for_file_mentions` method with a sample input. It checks if the returned result is as expected.
2023-05-27 08:23:51 -07:00
Paul Gauthier
dd3bdfbe15 Added new files to the git repo: tests/test_coder.py 2023-05-27 08:22:37 -07:00
Paul Gauthier
3f5e4130ea fixed test 2023-05-27 06:25:16 -07:00
Paul Gauthier
139a141be9 removed dotenv 2023-05-27 06:13:34 -07:00
Paul Gauthier
3e99b4f45c moved test_main_pretty_from_env to end of file 2023-05-27 05:20:10 -07:00