Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code coverage #141

Merged
merged 42 commits into from
Aug 2, 2024
Merged

Code coverage #141

merged 42 commits into from
Aug 2, 2024

Conversation

bandophahita
Copy link
Contributor

Added tests where coverage was lacking and added configuration to skip portions of files that do not need to be covered.

@bandophahita bandophahita requested a review from a team April 5, 2024 18:24
@bandophahita
Copy link
Contributor Author

I just realized we don't have any coverage for gravitas argument in beat. I'll add that.

Copy link
Member

@perrygoy perrygoy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Phew i actually had a lot to say on this one!

Comment on lines 30 to 31
"""
Matches a number which is in the given range.
Copy link
Member

@perrygoy perrygoy Apr 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This first line should still be level with the """. Also i don't think we can have the . at the end of the URL like that.

(Well by jove, we can, but it breaks the link-to-the-heading.)

    """Matches a number which is in the given range.

    Only supports proper intervals.
    https://en.wikipedia.org/wiki/Interval_%28mathematics%29#Notations_for_intervals
    """

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that was done automatically by the pydocstyle rules. I would never have done that myself.
Interestingly enough, when I run the rules now it doesn't seem to add the period. I'm guessing that got fixed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry i'm coming back to this so late, but if you move the sentence back up to the """s, does linting move it back down again?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Latest version of ruff isn't trying to reformat the first line anymore.

Comment on lines +22 to +25
@property
def length_to_log(self) -> str:
"""Represent the length in a log-friendly way."""
return represent_prop(self.length)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure to add this method to the exclude-members list fo HasLength in docs/api/resolutions.rst!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be clear, should we be doing that with all the others as well? None of the resolutions are currently excluding the x_to_log properties. I would imagine we want to be consistent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the published docs, I don't see any of the x_to_log properties being displayed for the other resolutions.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, it's because none of the Resolutions have :members: directive, which is obvious to me now because we don't actually have any methods on resolutions (yet).

I see you added those directives, but now i'm wondering—should we add the directives to exclude those members just in case we someday do add the :members: directive, or should we just assume Resolutions will never have methods on them?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had similar thought, but I wasn't sure. Is that pattern going to fit every Resolution?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we can remove the :exclude-members: directives that you added. I didn't look before i asked for this; having just done a bunch of editing Actions documentation i just assumed we needed it.

I'd rather be consistent for now and deal with that when we need to.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are removed.

Comment on lines -22 to +38
def test__parse_pyproject_toml_file_exists(self) -> None:
MockedPath = mock.MagicMock(spec=Path)
@mock.patch("screenpy.configuration.Path", autospec=True)
def test__parse_pyproject_toml_file_exists(self, MockedPath: mock.Mock) -> None:
MockedPath.cwd.return_value.__truediv__.return_value = MockedPath
MockedPath.is_file.return_value = True
test_data = (
b"[tool.screenpy]\nTIMEOUT = 500"
b"\n\n[tool.screenpy.stdoutadapter]\nINDENT_SIZE = 500"
)
mock_open = mock.mock_open(read_data=test_data)
MockedPath.open.side_effect = mock_open.side_effect
MockedPath.open.return_value = mock_open.return_value

with mock.patch("pathlib.Path.open", mock_open):
pyproject_config = PyprojectTomlConfig(ScreenPySettings)
pyproject_config._parse_pyproject_toml()
pyproject_config = PyprojectTomlConfig(ScreenPySettings)
pyproject_config._parse_pyproject_toml()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these changes to limit the scope of the Path that was mocked?

Copy link
Contributor Author

@bandophahita bandophahita May 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It limits what methods can be called on the mock object. If you recall a while back the conversation about using autospec to narrowly define what methods can be utilized on the mock objects. This would avoid any potential false positives due to a typo.

# mock has no issues with calling methods that don't actually exist 
# on the original object being mocked
obj = mock.Mock
obj.mispeeled_method()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous code was only and specifically mocking the Path.open method with the specially-crafted mock_open function from unittest.mock. I don't think we would have run into the "mispeeled method" problem here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a very low chance possibility, but wasn't zero. This makes it zero.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still not sure it's necessary:

Python 3.12.3 (main, Apr  9 2024, 08:09:14) [Clang 15.0.0 (clang-1500.3.9.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from unittest import mock
>>> mo = mock.mock_open(read_data="")
>>> mo.mispeeled_method()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/homebrew/Cellar/[email protected]/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/unittest/mock.py", line 658, in __getattr__
    raise AttributeError("Mock object has no attribute %r" % name)
AttributeError: Mock object has no attribute 'mispeeled_method'

I actually think mocking more of Path than we need to would make the test less valuable, honestly.

Copy link
Contributor

@MarcelWilson MarcelWilson Jun 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I roll back the mock changes, coverage in configuration.py drops to 98%.
The test__parse_pyproject_toml_file_does_not_exist never seems to hit the following line in PyprojectTomlConfig._parse_pyproject_toml

        if not pyproject_path.is_file():
            self.toml_config = {}

And that is due to the fact that we weren't patching Path in configuration.py before. With these changes, we get that coverage.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that missing that line doesn't point to us needing to mock more, i think it means something about our test just above is incorrect. I don't think mocking further is the right answer, we need to look at why the test just above this comment (test__parse_pyproject_toml_file_does_not_exist) was not hitting this line of code, when it really ought to be.

Copy link
Contributor Author

@bandophahita bandophahita Aug 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't consider this mocking more, but more along the lines of mocking differently.

In the old version we were creating a mock object but that object was never being utilized at the point in the code where we needed it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously we were only mocking the Path.open and the Path.is_file methods (well, trying to, on that second one). Now we're mocking the entire Path class.

Comment on lines 66 to 74
:exclude-members: length_to_log, item_plural

IsCloseTo
---------

**Aliases**: ``CloseTo``

.. autoclass:: IsCloseTo
:exclude-members: delta_to_log, num_to_log
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned in the comments below, you can remove these :exclude-members: directives because we don't have :members: on here to begin with.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha. Removing them. (I really ought to take some time to learn more about autodoc)

Copy link
Contributor

@MarcelWilson MarcelWilson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

Copy link
Member

@perrygoy perrygoy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At long last! Sorry for the long delay.

@bandophahita bandophahita merged commit b5be493 into ScreenPyHQ:trunk Aug 2, 2024
12 checks passed
@bandophahita bandophahita deleted the code_coverage branch August 2, 2024 15:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants