Skip to content

Commit

Permalink
Add docs on Large style Act blocks (jamescooke#219)
Browse files Browse the repository at this point in the history
  • Loading branch information
jamescooke authored May 10, 2023
1 parent 8abe040 commit 29ed661
Show file tree
Hide file tree
Showing 9 changed files with 131 additions and 36 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ See also `latest documentation
provided to provide compatibility with Black versions ``23.*``. Fixes `issue
200 <https://github.com/jamescooke/flake8-aaa/issues/200>`_.

* 📕: New docs added for "large" Act block style. `Issue 200
<https://github.com/jamescooke/flake8-aaa/issues/200>`_.

* ⛏️ Moved Black formatted test examples to their own directory. This helps
when running Flake8 against Black formatted tests which need
``--aaa-act-block-style=large``. Also fix up associated Makefile recipes and
Expand Down
10 changes: 8 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ checks provided by plugins, of which Flake8-AAA is one.

Further reading:

* `Flake8's documentation <https://flake8.pycqa.org/en/latest/>`_
* `Flake8's documentation <https://flake8.pycqa.org/en/latest/>`_.

* `Awesome Flake8 Extensions
<https://github.com/DmytroLitvinov/awesome-flake8-extensions/>`_ - a curated
Expand Down Expand Up @@ -234,6 +234,9 @@ Flake8 with ``--select``:
Further reading:

* `Flake8-AAA options and configuration
<https://flake8-aaa.readthedocs.io/en/stable/options.html>`_.

* `Using Flake8 <https://flake8.pycqa.org/en/stable/user/index.html>`_.

Via command line
Expand Down Expand Up @@ -270,7 +273,8 @@ Further reading:

* `Full compatibility list
<https://flake8-aaa.readthedocs.io/en/stable/compatibility.html>`_ - includes
information on support for older versions of Python.
how to configure Flake8-AAA to work with Black and information on support for
older versions of Python.

📕 Resources
------------
Expand All @@ -284,3 +288,5 @@ Further reading:
* `Licensed on MIT <https://github.com/jamescooke/flake8-aaa/blob/master/LICENSE>`_

* `Changelog <https://github.com/jamescooke/flake8-aaa/blob/master/CHANGELOG.rst>`_

* `#flake8_aaa hashtag on Mastodon <https://fosstodon.org/tags/flake8_aaa>`_
29 changes: 12 additions & 17 deletions docs/compatibility.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,31 +46,26 @@ plugin.
Yapf
----

Yapf is used to format Flake8-AAA code and tests. It is the primary formatter
focused on for compatibility.
`Yapf <https://github.com/google/yapf>`_ is used to format Flake8-AAA code and
tests. It is the primary formatter focused on for compatibility.

Black
-----

Flake8-AAA is compatible with tests formatted with Black.
Flake8-AAA is compatible with tests formatted with `Black
<https://github.com/psf/black>`_.

The coding style used by Black can be viewed as a strict subset of PEP8.
Black version ``23.1.0`` changed how it managed blank lines by default. Set
:ref:`"large" Act block style option or configuration <large-act-block-style>`
when running via Flake8 for best compatibility with Black:

The AAA pattern is PEP8 compatible so it makes sense that Flake8-AAA should
work with PEP8 compatible formatters.

This compatibility is pinned by the test examples in the `examples/good/black
directory
<https://github.com/jamescooke/flake8-aaa/tree/master/examples/good/black>`_.
These tests are formatted with the latest version of Black in default mode.
They are then checked to pass Flake8-AAA's linting.
.. code-block:: shell
.. note::
flake8 --aaa-act-block-style=large
Black version ``23.1.0`` changed how it managed blank lines by default.
This change causes Flake8-AAA to raise ``AAA03`` errors on tests that
contain context managers and are formatted with Black. See `issue #200
<https://github.com/jamescooke/flake8-aaa/issues/200>`_.
See also `Black formatted example tests
<https://github.com/jamescooke/flake8-aaa/tree/master/examples/#black-formatted-examples>`_
in Flake8-AAA's test suite.

Pytest
------
Expand Down
3 changes: 3 additions & 0 deletions docs/discovery.rst
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ There are four recognised types of Act block:
Flake8-AAA searches each test function for lines that look like Act blocks. It
will raise an error when a function does not have exactly 1 Act block.

The "act block style" configuration allows for a "large" style of Act block to
be specified, which changes how Act blocks are built in relation to context managers. See ...

Build Arrange and Assert blocks
...............................

Expand Down
8 changes: 4 additions & 4 deletions docs/error_codes/AAA01-no-act-block-found-in-test.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ is raised. When Flake8-AAA raises ``AAA01`` it could not find an Act block in
the indicated test function.

Problematic code
................
----------------

.. code-block:: python
Expand All @@ -27,7 +27,7 @@ Problematic code
list()[0]
Correct code 1
..............
--------------

Use ``result =`` assignment to indicate the action in the test:

Expand Down Expand Up @@ -55,7 +55,7 @@ Ensure all Pytest context managers are in the ``pytest`` namespace - use
.. _aaa01-correct-code-2:

Correct code 2
..............
--------------

Alternatively, mark your Act block with the ``# act`` hint to indicate the
action in the test. This can be useful for scenarios where a result can not be
Expand All @@ -80,7 +80,7 @@ assigned, such as tests on functions that return ``None``.
list()[0] # act
Rationale
.........
---------

The Act block carries out a single action on an object so it's important that
Flake8-AAA can clearly distinguish which line or lines make up the Act block in
Expand Down
46 changes: 40 additions & 6 deletions docs/error_codes/AAA03-expected-1-blank-line-before-act-block.rst
Original file line number Diff line number Diff line change
@@ -1,17 +1,51 @@
AAA03: expected 1 blank line before Act block, found none
---------------------------------------------------------
=========================================================

For tests that have an Arrange block, there must be a blank line between the
Arrange and Act blocks, but Flake8-AAA could not find one.

This blank line creates separation between the arrangement and the action and
makes the Act block easy to spot.
Prerequisites
-------------

This rule works best with `pycodestyle
<https://pypi.org/project/pycodestyle/>`_'s ``E303`` rule enabled because it
ensures that there are not multiple blank lines between the blocks.

Resolution
..........
If test code is formatted with Black, then it's best to set :ref:`"large" Act
block style <large-act-block-style>`.

Add a blank line before the Act block.
Problematic code
----------------

.. code-block:: python
def test_simple(hello_world_path: pathlib.Path) -> None:
with open(hello_world_path) as f:
result = f.read()
assert result == 'Hello World!\n'
Correct code
------------

Since the ``open()`` context manager is part of the Arrange block, create space
between it and the ``result =`` Act block.

.. code-block:: python
def test_simple(hello_world_path: pathlib.Path) -> None:
with open(hello_world_path) as f:
result = f.read()
assert result == 'Hello World!\n'
Alternatively, if you want the context manager to be treated as part of the Act
block, the :ref:`"large" Act block style <large-act-block-style>` as mentioned
above.

Rationale
---------

This blank line creates separation between the test's Arrange and Act blocks
and makes the Act block easy to spot.
12 changes: 6 additions & 6 deletions docs/error_codes/AAA06-comment-in-act-block.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
AAA06: comment in Act block
---------------------------
===========================

Problematic code
................
----------------

.. code-block:: python
Expand All @@ -23,7 +23,7 @@ Problematic code
assert result == 2
Correct code
............
------------

Use docstrings instead of hash-comments:

Expand Down Expand Up @@ -61,7 +61,7 @@ Separate hash-comment line from Act block with a blank line:
assert result == 2
Rationale
.........
---------

The Act block carries out a single action on an object. It is the focus of each
test. Therefore any comments on this single action are really comments on the
Expand All @@ -77,9 +77,9 @@ By placing these important comments in the docstring we can:
are lifted to the top of the test.

Exceptions
..........
----------

Inline comments used to pass information to linters are OK:
Directives in the form of inline comments are OK, for example:

* Marking the Act block:

Expand Down
51 changes: 50 additions & 1 deletion docs/options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ Configuration option
The Act block style option adjusts how Flake8-AAA builds the Act block from the
Act node.

The allowed value is "default".
The allowed values are "default" and "large".

Default
.......

In default mode the Act block is the single Act node, best demonstrated by
example:
Expand Down Expand Up @@ -51,3 +54,49 @@ context managers other than pytest or unittest ones.
In the example above, Flake8-AAA considers the ``with freeze_time()`` context
manager to be in the Arrange block. It therefore expects a blank line between
it and the ``result =`` Act block.

.. _large-act-block-style:

Large
.....

Large style Act blocks have been provided to be compatible with Black.

In Large mode the Act block can grow to include context managers that wrap it.
For example, referring to the test above, this would be formatted as follows
with Large Act blocks:

.. code-block:: python
def test_with():
a_class = AClass()
with freeze_time("2021-02-02 12:00:02"):
result = a_class.action('test')
assert result == 'test'
The ``result =`` result assignment Act block expands to include the
``freeze_time()`` context manager. In this way, the blank line that divides the
Arrange block from the Act block can be *before* the context manager - a format
which is compatible with Black.

Note however, the context manager only joined the Act block because the Act
node was the **first** line in the context manager's body. If we moved the
``AClass()`` initialisation inside the context manager, something different
would happen:

.. code-block:: python
def test_with():
with freeze_time("2021-02-02 12:00:02"):
a_class = AClass()
result = a_class.action('test')
assert result == 'test'
This time the result assignment does *not* consume the context manager.
Instead, the ``freeze_time()`` context manager and the ``a_class``
initialisation make up the Arrange block, and there's a single blank line
between that and the simple result assignment Act block.
5 changes: 5 additions & 0 deletions examples/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ Layout
Black formatted examples
------------------------

The example tests in ``examples/black`` are copies of the ``examples/good``
tests which are then formatted with the latest version of Black in default
mode. They are then linted with Flake8-AAA using Large-style Act blocks so that
Black's formatting of context managers passes lint.

To update the examples formatted with Black in ``examples/black`` (run from
project root)::

Expand Down

0 comments on commit 29ed661

Please sign in to comment.