From: Jelle Zijlstra Date: Tue, 10 Oct 2023 01:43:47 +0000 (-0700) Subject: Use inline flags for test cases (#3931) X-Git-Url: https://git.madduck.net/etc/vim.git/commitdiff_plain/a69bda3b9bde208d5489eb2e37fc982b6bc1d8df Use inline flags for test cases (#3931) Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com> --- diff --git a/docs/contributing/the_basics.md b/docs/contributing/the_basics.md index 864894b..bc1680e 100644 --- a/docs/contributing/the_basics.md +++ b/docs/contributing/the_basics.md @@ -58,7 +58,26 @@ Further examples of invoking the tests (.venv)$ tox -e py -- --print-tree-diff=False ``` -`Black` has two pytest command-line options affecting test files in `tests/data/` that +### Testing + +All aspects of the _Black_ style should be tested. Normally, tests should be created as +files in the `tests/data/cases` directory. These files consist of up to three parts: + +- A line that starts with `# flags: ` followed by a set of command-line options. For + example, if the line is `# flags: --preview --skip-magic-trailing-comma`, the test + case will be run with preview mode on and the magic trailing comma off. The options + accepted are mostly a subset of those of _Black_ itself, except for the + `--minimum-version=` flag, which should be used when testing a grammar feature that + works only in newer versions of Python. This flag ensures that we don't try to + validate the AST on older versions and tests that we autodetect the Python version + correctly when the feature is used. For the exact flags accepted, see the function + `get_flags_parser` in `tests/util.py`. If this line is omitted, the default options + are used. +- A block of Python code used as input for the formatter. +- The line `# output`, followed by the output of _Black_ when run on the previous block. + If this is omitted, the test asserts that _Black_ will leave the input code unchanged. + +_Black_ has two pytest command-line options affecting test files in `tests/data/` that are split into an input part, and an output part, separated by a line with`# output`. These can be passed to `pytest` through `tox`, or directly into pytest if not using `tox`. diff --git a/tests/data/simple_cases/attribute_access_on_number_literals.py b/tests/data/cases/attribute_access_on_number_literals.py similarity index 100% rename from tests/data/simple_cases/attribute_access_on_number_literals.py rename to tests/data/cases/attribute_access_on_number_literals.py diff --git a/tests/data/simple_cases/beginning_backslash.py b/tests/data/cases/beginning_backslash.py similarity index 100% rename from tests/data/simple_cases/beginning_backslash.py rename to tests/data/cases/beginning_backslash.py diff --git a/tests/data/simple_cases/bracketmatch.py b/tests/data/cases/bracketmatch.py similarity index 100% rename from tests/data/simple_cases/bracketmatch.py rename to tests/data/cases/bracketmatch.py diff --git a/tests/data/simple_cases/class_blank_parentheses.py b/tests/data/cases/class_blank_parentheses.py similarity index 100% rename from tests/data/simple_cases/class_blank_parentheses.py rename to tests/data/cases/class_blank_parentheses.py diff --git a/tests/data/simple_cases/class_methods_new_line.py b/tests/data/cases/class_methods_new_line.py similarity index 100% rename from tests/data/simple_cases/class_methods_new_line.py rename to tests/data/cases/class_methods_new_line.py diff --git a/tests/data/simple_cases/collections.py b/tests/data/cases/collections.py similarity index 100% rename from tests/data/simple_cases/collections.py rename to tests/data/cases/collections.py diff --git a/tests/data/simple_cases/comment_after_escaped_newline.py b/tests/data/cases/comment_after_escaped_newline.py similarity index 100% rename from tests/data/simple_cases/comment_after_escaped_newline.py rename to tests/data/cases/comment_after_escaped_newline.py diff --git a/tests/data/simple_cases/comments.py b/tests/data/cases/comments.py similarity index 100% rename from tests/data/simple_cases/comments.py rename to tests/data/cases/comments.py diff --git a/tests/data/simple_cases/comments2.py b/tests/data/cases/comments2.py similarity index 100% rename from tests/data/simple_cases/comments2.py rename to tests/data/cases/comments2.py diff --git a/tests/data/simple_cases/comments3.py b/tests/data/cases/comments3.py similarity index 100% rename from tests/data/simple_cases/comments3.py rename to tests/data/cases/comments3.py diff --git a/tests/data/simple_cases/comments4.py b/tests/data/cases/comments4.py similarity index 100% rename from tests/data/simple_cases/comments4.py rename to tests/data/cases/comments4.py diff --git a/tests/data/simple_cases/comments5.py b/tests/data/cases/comments5.py similarity index 100% rename from tests/data/simple_cases/comments5.py rename to tests/data/cases/comments5.py diff --git a/tests/data/simple_cases/comments6.py b/tests/data/cases/comments6.py similarity index 100% rename from tests/data/simple_cases/comments6.py rename to tests/data/cases/comments6.py diff --git a/tests/data/simple_cases/comments8.py b/tests/data/cases/comments8.py similarity index 100% rename from tests/data/simple_cases/comments8.py rename to tests/data/cases/comments8.py diff --git a/tests/data/simple_cases/comments9.py b/tests/data/cases/comments9.py similarity index 100% rename from tests/data/simple_cases/comments9.py rename to tests/data/cases/comments9.py diff --git a/tests/data/simple_cases/comments_non_breaking_space.py b/tests/data/cases/comments_non_breaking_space.py similarity index 100% rename from tests/data/simple_cases/comments_non_breaking_space.py rename to tests/data/cases/comments_non_breaking_space.py diff --git a/tests/data/simple_cases/composition.py b/tests/data/cases/composition.py similarity index 100% rename from tests/data/simple_cases/composition.py rename to tests/data/cases/composition.py diff --git a/tests/data/simple_cases/composition_no_trailing_comma.py b/tests/data/cases/composition_no_trailing_comma.py similarity index 100% rename from tests/data/simple_cases/composition_no_trailing_comma.py rename to tests/data/cases/composition_no_trailing_comma.py diff --git a/tests/data/simple_cases/docstring.py b/tests/data/cases/docstring.py similarity index 100% rename from tests/data/simple_cases/docstring.py rename to tests/data/cases/docstring.py diff --git a/tests/data/simple_cases/docstring_no_extra_empty_line_before_eof.py b/tests/data/cases/docstring_no_extra_empty_line_before_eof.py similarity index 100% rename from tests/data/simple_cases/docstring_no_extra_empty_line_before_eof.py rename to tests/data/cases/docstring_no_extra_empty_line_before_eof.py diff --git a/tests/data/miscellaneous/docstring_no_string_normalization.py b/tests/data/cases/docstring_no_string_normalization.py similarity index 98% rename from tests/data/miscellaneous/docstring_no_string_normalization.py rename to tests/data/cases/docstring_no_string_normalization.py index a90b578..4ec6b8a 100644 --- a/tests/data/miscellaneous/docstring_no_string_normalization.py +++ b/tests/data/cases/docstring_no_string_normalization.py @@ -1,3 +1,4 @@ +# flags: --skip-string-normalization class ALonelyClass: ''' A multiline class docstring. diff --git a/tests/data/simple_cases/docstring_preview.py b/tests/data/cases/docstring_preview.py similarity index 100% rename from tests/data/simple_cases/docstring_preview.py rename to tests/data/cases/docstring_preview.py diff --git a/tests/data/miscellaneous/docstring_preview_no_string_normalization.py b/tests/data/cases/docstring_preview_no_string_normalization.py similarity index 88% rename from tests/data/miscellaneous/docstring_preview_no_string_normalization.py rename to tests/data/cases/docstring_preview_no_string_normalization.py index 338cc01..712c736 100644 --- a/tests/data/miscellaneous/docstring_preview_no_string_normalization.py +++ b/tests/data/cases/docstring_preview_no_string_normalization.py @@ -1,3 +1,4 @@ +# flags: --preview --skip-string-normalization def do_not_touch_this_prefix(): R"""There was a bug where docstring prefixes would be normalized even with -S.""" diff --git a/tests/data/simple_cases/empty_lines.py b/tests/data/cases/empty_lines.py similarity index 100% rename from tests/data/simple_cases/empty_lines.py rename to tests/data/cases/empty_lines.py diff --git a/tests/data/simple_cases/expression.diff b/tests/data/cases/expression.diff similarity index 100% rename from tests/data/simple_cases/expression.diff rename to tests/data/cases/expression.diff diff --git a/tests/data/simple_cases/expression.py b/tests/data/cases/expression.py similarity index 100% rename from tests/data/simple_cases/expression.py rename to tests/data/cases/expression.py diff --git a/tests/data/simple_cases/fmtonoff.py b/tests/data/cases/fmtonoff.py similarity index 100% rename from tests/data/simple_cases/fmtonoff.py rename to tests/data/cases/fmtonoff.py diff --git a/tests/data/simple_cases/fmtonoff2.py b/tests/data/cases/fmtonoff2.py similarity index 100% rename from tests/data/simple_cases/fmtonoff2.py rename to tests/data/cases/fmtonoff2.py diff --git a/tests/data/simple_cases/fmtonoff3.py b/tests/data/cases/fmtonoff3.py similarity index 100% rename from tests/data/simple_cases/fmtonoff3.py rename to tests/data/cases/fmtonoff3.py diff --git a/tests/data/simple_cases/fmtonoff4.py b/tests/data/cases/fmtonoff4.py similarity index 100% rename from tests/data/simple_cases/fmtonoff4.py rename to tests/data/cases/fmtonoff4.py diff --git a/tests/data/simple_cases/fmtonoff5.py b/tests/data/cases/fmtonoff5.py similarity index 100% rename from tests/data/simple_cases/fmtonoff5.py rename to tests/data/cases/fmtonoff5.py diff --git a/tests/data/simple_cases/fmtpass_imports.py b/tests/data/cases/fmtpass_imports.py similarity index 100% rename from tests/data/simple_cases/fmtpass_imports.py rename to tests/data/cases/fmtpass_imports.py diff --git a/tests/data/simple_cases/fmtskip.py b/tests/data/cases/fmtskip.py similarity index 100% rename from tests/data/simple_cases/fmtskip.py rename to tests/data/cases/fmtskip.py diff --git a/tests/data/simple_cases/fmtskip2.py b/tests/data/cases/fmtskip2.py similarity index 100% rename from tests/data/simple_cases/fmtskip2.py rename to tests/data/cases/fmtskip2.py diff --git a/tests/data/simple_cases/fmtskip3.py b/tests/data/cases/fmtskip3.py similarity index 100% rename from tests/data/simple_cases/fmtskip3.py rename to tests/data/cases/fmtskip3.py diff --git a/tests/data/simple_cases/fmtskip4.py b/tests/data/cases/fmtskip4.py similarity index 100% rename from tests/data/simple_cases/fmtskip4.py rename to tests/data/cases/fmtskip4.py diff --git a/tests/data/simple_cases/fmtskip5.py b/tests/data/cases/fmtskip5.py similarity index 100% rename from tests/data/simple_cases/fmtskip5.py rename to tests/data/cases/fmtskip5.py diff --git a/tests/data/simple_cases/fmtskip6.py b/tests/data/cases/fmtskip6.py similarity index 100% rename from tests/data/simple_cases/fmtskip6.py rename to tests/data/cases/fmtskip6.py diff --git a/tests/data/simple_cases/fmtskip7.py b/tests/data/cases/fmtskip7.py similarity index 100% rename from tests/data/simple_cases/fmtskip7.py rename to tests/data/cases/fmtskip7.py diff --git a/tests/data/simple_cases/fmtskip8.py b/tests/data/cases/fmtskip8.py similarity index 100% rename from tests/data/simple_cases/fmtskip8.py rename to tests/data/cases/fmtskip8.py diff --git a/tests/data/simple_cases/fstring.py b/tests/data/cases/fstring.py similarity index 100% rename from tests/data/simple_cases/fstring.py rename to tests/data/cases/fstring.py diff --git a/tests/data/preview_py_310/funcdef_return_type_trailing_comma.py b/tests/data/cases/funcdef_return_type_trailing_comma.py similarity index 99% rename from tests/data/preview_py_310/funcdef_return_type_trailing_comma.py rename to tests/data/cases/funcdef_return_type_trailing_comma.py index 15db772..9b9b9c6 100644 --- a/tests/data/preview_py_310/funcdef_return_type_trailing_comma.py +++ b/tests/data/cases/funcdef_return_type_trailing_comma.py @@ -1,3 +1,4 @@ +# flags: --preview --minimum-version=3.10 # normal, short, function definition def foo(a, b) -> tuple[int, float]: ... diff --git a/tests/data/simple_cases/function.py b/tests/data/cases/function.py similarity index 100% rename from tests/data/simple_cases/function.py rename to tests/data/cases/function.py diff --git a/tests/data/simple_cases/function2.py b/tests/data/cases/function2.py similarity index 100% rename from tests/data/simple_cases/function2.py rename to tests/data/cases/function2.py diff --git a/tests/data/simple_cases/function_trailing_comma.py b/tests/data/cases/function_trailing_comma.py similarity index 100% rename from tests/data/simple_cases/function_trailing_comma.py rename to tests/data/cases/function_trailing_comma.py diff --git a/tests/data/simple_cases/ignore_pyi.py b/tests/data/cases/ignore_pyi.py similarity index 97% rename from tests/data/simple_cases/ignore_pyi.py rename to tests/data/cases/ignore_pyi.py index 3ef6107..4fae753 100644 --- a/tests/data/simple_cases/ignore_pyi.py +++ b/tests/data/cases/ignore_pyi.py @@ -1,3 +1,4 @@ +# flags: --pyi def f(): # type: ignore ... diff --git a/tests/data/simple_cases/import_spacing.py b/tests/data/cases/import_spacing.py similarity index 100% rename from tests/data/simple_cases/import_spacing.py rename to tests/data/cases/import_spacing.py diff --git a/tests/data/miscellaneous/linelength6.py b/tests/data/cases/linelength6.py similarity index 80% rename from tests/data/miscellaneous/linelength6.py rename to tests/data/cases/linelength6.py index 4fb3427..158038b 100644 --- a/tests/data/miscellaneous/linelength6.py +++ b/tests/data/cases/linelength6.py @@ -1,3 +1,4 @@ +# flags: --line-length=6 # Regression test for #3427, which reproes only with line length <= 6 def f(): """ diff --git a/tests/data/miscellaneous/long_strings_flag_disabled.py b/tests/data/cases/long_strings_flag_disabled.py similarity index 100% rename from tests/data/miscellaneous/long_strings_flag_disabled.py rename to tests/data/cases/long_strings_flag_disabled.py diff --git a/tests/data/simple_cases/multiline_consecutive_open_parentheses_ignore.py b/tests/data/cases/multiline_consecutive_open_parentheses_ignore.py similarity index 100% rename from tests/data/simple_cases/multiline_consecutive_open_parentheses_ignore.py rename to tests/data/cases/multiline_consecutive_open_parentheses_ignore.py diff --git a/tests/data/miscellaneous/nested_stub.pyi b/tests/data/cases/nested_stub.py similarity index 94% rename from tests/data/miscellaneous/nested_stub.pyi rename to tests/data/cases/nested_stub.py index 15e69d8..b81549e 100644 --- a/tests/data/miscellaneous/nested_stub.pyi +++ b/tests/data/cases/nested_stub.py @@ -1,3 +1,4 @@ +# flags: --pyi --preview import sys class Outer: diff --git a/tests/data/py_36/numeric_literals.py b/tests/data/cases/numeric_literals.py similarity index 91% rename from tests/data/py_36/numeric_literals.py rename to tests/data/cases/numeric_literals.py index 254da68..9966932 100644 --- a/tests/data/py_36/numeric_literals.py +++ b/tests/data/cases/numeric_literals.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3.6 - x = 123456789 x = 123456 x = .1 @@ -21,9 +19,6 @@ x = 133333 # output - -#!/usr/bin/env python3.6 - x = 123456789 x = 123456 x = 0.1 diff --git a/tests/data/py_36/numeric_literals_skip_underscores.py b/tests/data/cases/numeric_literals_skip_underscores.py similarity index 77% rename from tests/data/py_36/numeric_literals_skip_underscores.py rename to tests/data/cases/numeric_literals_skip_underscores.py index e345bb9..6d60bdb 100644 --- a/tests/data/py_36/numeric_literals_skip_underscores.py +++ b/tests/data/cases/numeric_literals_skip_underscores.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3.6 - x = 123456789 x = 1_2_3_4_5_6_7 x = 1E+1 @@ -11,8 +9,6 @@ x = 1_2. # output -#!/usr/bin/env python3.6 - x = 123456789 x = 1_2_3_4_5_6_7 x = 1e1 diff --git a/tests/data/simple_cases/one_element_subscript.py b/tests/data/cases/one_element_subscript.py similarity index 100% rename from tests/data/simple_cases/one_element_subscript.py rename to tests/data/cases/one_element_subscript.py diff --git a/tests/data/py_310/parenthesized_context_managers.py b/tests/data/cases/parenthesized_context_managers.py similarity index 95% rename from tests/data/py_310/parenthesized_context_managers.py rename to tests/data/cases/parenthesized_context_managers.py index 1ef09a1..16645a1 100644 --- a/tests/data/py_310/parenthesized_context_managers.py +++ b/tests/data/cases/parenthesized_context_managers.py @@ -1,3 +1,4 @@ +# flags: --minimum-version=3.10 with (CtxManager() as example): ... diff --git a/tests/data/py_310/pattern_matching_complex.py b/tests/data/cases/pattern_matching_complex.py similarity index 98% rename from tests/data/py_310/pattern_matching_complex.py rename to tests/data/cases/pattern_matching_complex.py index 97ee194..b4355c7 100644 --- a/tests/data/py_310/pattern_matching_complex.py +++ b/tests/data/cases/pattern_matching_complex.py @@ -1,3 +1,4 @@ +# flags: --minimum-version=3.10 # Cases sampled from Lib/test/test_patma.py # case black_test_patma_098 diff --git a/tests/data/py_310/pattern_matching_extras.py b/tests/data/cases/pattern_matching_extras.py similarity index 98% rename from tests/data/py_310/pattern_matching_extras.py rename to tests/data/cases/pattern_matching_extras.py index 0242d26..1e1481d 100644 --- a/tests/data/py_310/pattern_matching_extras.py +++ b/tests/data/cases/pattern_matching_extras.py @@ -1,3 +1,4 @@ +# flags: --minimum-version=3.10 import match match something: diff --git a/tests/data/py_310/pattern_matching_generic.py b/tests/data/cases/pattern_matching_generic.py similarity index 98% rename from tests/data/py_310/pattern_matching_generic.py rename to tests/data/cases/pattern_matching_generic.py index 00a0e4a..4b4d45f 100644 --- a/tests/data/py_310/pattern_matching_generic.py +++ b/tests/data/cases/pattern_matching_generic.py @@ -1,3 +1,4 @@ +# flags: --minimum-version=3.10 re.match() match = a with match() as match: diff --git a/tests/data/py_310/pattern_matching_simple.py b/tests/data/cases/pattern_matching_simple.py similarity index 98% rename from tests/data/py_310/pattern_matching_simple.py rename to tests/data/cases/pattern_matching_simple.py index 5ed6241..6fa2000 100644 --- a/tests/data/py_310/pattern_matching_simple.py +++ b/tests/data/cases/pattern_matching_simple.py @@ -1,3 +1,4 @@ +# flags: --minimum-version=3.10 # Cases sampled from PEP 636 examples match command.split(): diff --git a/tests/data/py_310/pattern_matching_style.py b/tests/data/cases/pattern_matching_style.py similarity index 97% rename from tests/data/py_310/pattern_matching_style.py rename to tests/data/cases/pattern_matching_style.py index 8e18ce2..2ee6ea2 100644 --- a/tests/data/py_310/pattern_matching_style.py +++ b/tests/data/cases/pattern_matching_style.py @@ -1,3 +1,4 @@ +# flags: --minimum-version=3.10 match something: case b(): print(1+1) case c( diff --git a/tests/data/preview_py_310/pep604_union_types_line_breaks.py b/tests/data/cases/pep604_union_types_line_breaks.py similarity index 99% rename from tests/data/preview_py_310/pep604_union_types_line_breaks.py rename to tests/data/cases/pep604_union_types_line_breaks.py index 9c4ab87..fee2b84 100644 --- a/tests/data/preview_py_310/pep604_union_types_line_breaks.py +++ b/tests/data/cases/pep604_union_types_line_breaks.py @@ -1,3 +1,4 @@ +# flags: --preview --minimum-version=3.10 # This has always worked z= Loooooooooooooooooooooooong | Loooooooooooooooooooooooong | Loooooooooooooooooooooooong | Loooooooooooooooooooooooong diff --git a/tests/data/py_38/pep_570.py b/tests/data/cases/pep_570.py similarity index 95% rename from tests/data/py_38/pep_570.py rename to tests/data/cases/pep_570.py index ca8f7ab..2641c2b 100644 --- a/tests/data/py_38/pep_570.py +++ b/tests/data/cases/pep_570.py @@ -1,3 +1,4 @@ +# flags: --minimum-version=3.8 def positional_only_arg(a, /): pass diff --git a/tests/data/py_38/pep_572.py b/tests/data/cases/pep_572.py similarity index 96% rename from tests/data/py_38/pep_572.py rename to tests/data/cases/pep_572.py index d41805f..742b6d5 100644 --- a/tests/data/py_38/pep_572.py +++ b/tests/data/cases/pep_572.py @@ -1,3 +1,4 @@ +# flags: --minimum-version=3.8 (a := 1) (a := a) if (match := pattern.search(data)) is None: diff --git a/tests/data/fast/pep_572_do_not_remove_parens.py b/tests/data/cases/pep_572_do_not_remove_parens.py similarity index 96% rename from tests/data/fast/pep_572_do_not_remove_parens.py rename to tests/data/cases/pep_572_do_not_remove_parens.py index 05619dd..08dba3f 100644 --- a/tests/data/fast/pep_572_do_not_remove_parens.py +++ b/tests/data/cases/pep_572_do_not_remove_parens.py @@ -1,3 +1,4 @@ +# flags: --fast # Most of the following examples are really dumb, some of them aren't even accepted by Python, # we're fixing them only so fuzzers (which follow the grammar which actually allows these # examples matter of fact!) don't yell at us :p diff --git a/tests/data/py_310/pep_572_py310.py b/tests/data/cases/pep_572_py310.py similarity index 93% rename from tests/data/py_310/pep_572_py310.py rename to tests/data/cases/pep_572_py310.py index cb82b2d..9f999de 100644 --- a/tests/data/py_310/pep_572_py310.py +++ b/tests/data/cases/pep_572_py310.py @@ -1,3 +1,4 @@ +# flags: --minimum-version=3.10 # Unparenthesized walruses are now allowed in indices since Python 3.10. x[a:=0] x[a:=0, b:=1] diff --git a/tests/data/py_39/pep_572_py39.py b/tests/data/cases/pep_572_py39.py similarity index 89% rename from tests/data/py_39/pep_572_py39.py rename to tests/data/cases/pep_572_py39.py index b8b081b..d161462 100644 --- a/tests/data/py_39/pep_572_py39.py +++ b/tests/data/cases/pep_572_py39.py @@ -1,3 +1,4 @@ +# flags: --minimum-version=3.9 # Unparenthesized walruses are now allowed in set literals & set comprehensions # since Python 3.9 {x := 1, 2, 3} diff --git a/tests/data/py_38/pep_572_remove_parens.py b/tests/data/cases/pep_572_remove_parens.py similarity index 98% rename from tests/data/py_38/pep_572_remove_parens.py rename to tests/data/cases/pep_572_remove_parens.py index b952b29..24f1ac2 100644 --- a/tests/data/py_38/pep_572_remove_parens.py +++ b/tests/data/cases/pep_572_remove_parens.py @@ -1,3 +1,4 @@ +# flags: --minimum-version=3.8 if (foo := 0): pass diff --git a/tests/data/simple_cases/pep_604.py b/tests/data/cases/pep_604.py similarity index 100% rename from tests/data/simple_cases/pep_604.py rename to tests/data/cases/pep_604.py diff --git a/tests/data/py_311/pep_646.py b/tests/data/cases/pep_646.py similarity index 98% rename from tests/data/py_311/pep_646.py rename to tests/data/cases/pep_646.py index e843ecf..92b568a 100644 --- a/tests/data/py_311/pep_646.py +++ b/tests/data/cases/pep_646.py @@ -1,3 +1,4 @@ +# flags: --minimum-version=3.11 A[*b] A[*b] = 1 A diff --git a/tests/data/py_311/pep_654.py b/tests/data/cases/pep_654.py similarity index 96% rename from tests/data/py_311/pep_654.py rename to tests/data/cases/pep_654.py index 387c081..12e4918 100644 --- a/tests/data/py_311/pep_654.py +++ b/tests/data/cases/pep_654.py @@ -1,3 +1,4 @@ +# flags: --minimum-version=3.11 try: raise OSError("blah") except* ExceptionGroup as e: diff --git a/tests/data/py_311/pep_654_style.py b/tests/data/cases/pep_654_style.py similarity index 98% rename from tests/data/py_311/pep_654_style.py rename to tests/data/cases/pep_654_style.py index 9fc7c0c..0d34650 100644 --- a/tests/data/py_311/pep_654_style.py +++ b/tests/data/cases/pep_654_style.py @@ -1,3 +1,4 @@ +# flags: --minimum-version=3.11 try: raise OSError("blah") except * ExceptionGroup as e: diff --git a/tests/data/miscellaneous/power_op_newline.py b/tests/data/cases/power_op_newline.py similarity index 73% rename from tests/data/miscellaneous/power_op_newline.py rename to tests/data/cases/power_op_newline.py index 85d434d..d9b3140 100644 --- a/tests/data/miscellaneous/power_op_newline.py +++ b/tests/data/cases/power_op_newline.py @@ -1,3 +1,4 @@ +# flags: --line-length=0 importA;()<<0**0# # output diff --git a/tests/data/simple_cases/power_op_spacing.py b/tests/data/cases/power_op_spacing.py similarity index 100% rename from tests/data/simple_cases/power_op_spacing.py rename to tests/data/cases/power_op_spacing.py diff --git a/tests/data/simple_cases/prefer_rhs_split_reformatted.py b/tests/data/cases/prefer_rhs_split_reformatted.py similarity index 100% rename from tests/data/simple_cases/prefer_rhs_split_reformatted.py rename to tests/data/cases/prefer_rhs_split_reformatted.py diff --git a/tests/data/preview/async_stmts.py b/tests/data/cases/preview_async_stmts.py similarity index 93% rename from tests/data/preview/async_stmts.py rename to tests/data/cases/preview_async_stmts.py index fe9594b..0a7671b 100644 --- a/tests/data/preview/async_stmts.py +++ b/tests/data/cases/preview_async_stmts.py @@ -1,3 +1,4 @@ +# flags: --preview async def func() -> (int): return 0 diff --git a/tests/data/preview/cantfit.py b/tests/data/cases/preview_cantfit.py similarity index 99% rename from tests/data/preview/cantfit.py rename to tests/data/cases/preview_cantfit.py index 0849374..d5da665 100644 --- a/tests/data/preview/cantfit.py +++ b/tests/data/cases/preview_cantfit.py @@ -1,3 +1,4 @@ +# flags: --preview # long variable name this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = 0 this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it = 1 # with a comment diff --git a/tests/data/preview/comments7.py b/tests/data/cases/preview_comments7.py similarity index 99% rename from tests/data/preview/comments7.py rename to tests/data/cases/preview_comments7.py index 0655de9..006d4f7 100644 --- a/tests/data/preview/comments7.py +++ b/tests/data/cases/preview_comments7.py @@ -1,3 +1,4 @@ +# flags: --preview from .config import ( Any, Bool, diff --git a/tests/data/preview_context_managers/targeting_py38.py b/tests/data/cases/preview_context_managers_38.py similarity index 96% rename from tests/data/preview_context_managers/targeting_py38.py rename to tests/data/cases/preview_context_managers_38.py index f125cdf..719d94f 100644 --- a/tests/data/preview_context_managers/targeting_py38.py +++ b/tests/data/cases/preview_context_managers_38.py @@ -1,3 +1,4 @@ +# flags: --preview --minimum-version=3.8 with \ make_context_manager1() as cm1, \ make_context_manager2() as cm2, \ diff --git a/tests/data/preview_context_managers/targeting_py39.py b/tests/data/cases/preview_context_managers_39.py similarity index 98% rename from tests/data/preview_context_managers/targeting_py39.py rename to tests/data/cases/preview_context_managers_39.py index c9fcf9c..589e00a 100644 --- a/tests/data/preview_context_managers/targeting_py39.py +++ b/tests/data/cases/preview_context_managers_39.py @@ -1,3 +1,4 @@ +# flags: --preview --minimum-version=3.9 with \ make_context_manager1() as cm1, \ make_context_manager2() as cm2, \ diff --git a/tests/data/preview_context_managers/auto_detect/features_3_10.py b/tests/data/cases/preview_context_managers_autodetect_310.py similarity index 93% rename from tests/data/preview_context_managers/auto_detect/features_3_10.py rename to tests/data/cases/preview_context_managers_autodetect_310.py index 1458df1..a9e3107 100644 --- a/tests/data/preview_context_managers/auto_detect/features_3_10.py +++ b/tests/data/cases/preview_context_managers_autodetect_310.py @@ -1,3 +1,4 @@ +# flags: --preview --minimum-version=3.10 # This file uses pattern matching introduced in Python 3.10. diff --git a/tests/data/preview_context_managers/auto_detect/features_3_11.py b/tests/data/cases/preview_context_managers_autodetect_311.py similarity index 92% rename from tests/data/preview_context_managers/auto_detect/features_3_11.py rename to tests/data/cases/preview_context_managers_autodetect_311.py index f83c533..af1e83f 100644 --- a/tests/data/preview_context_managers/auto_detect/features_3_11.py +++ b/tests/data/cases/preview_context_managers_autodetect_311.py @@ -1,3 +1,4 @@ +# flags: --preview --minimum-version=3.11 # This file uses except* clause in Python 3.11. diff --git a/tests/data/preview_context_managers/auto_detect/features_3_8.py b/tests/data/cases/preview_context_managers_autodetect_38.py similarity index 98% rename from tests/data/preview_context_managers/auto_detect/features_3_8.py rename to tests/data/cases/preview_context_managers_autodetect_38.py index 79e438b..25217a4 100644 --- a/tests/data/preview_context_managers/auto_detect/features_3_8.py +++ b/tests/data/cases/preview_context_managers_autodetect_38.py @@ -1,3 +1,4 @@ +# flags: --preview # This file doesn't use any Python 3.9+ only grammars. diff --git a/tests/data/preview_context_managers/auto_detect/features_3_9.py b/tests/data/cases/preview_context_managers_autodetect_39.py similarity index 93% rename from tests/data/preview_context_managers/auto_detect/features_3_9.py rename to tests/data/cases/preview_context_managers_autodetect_39.py index 0d28f99..3f72e48 100644 --- a/tests/data/preview_context_managers/auto_detect/features_3_9.py +++ b/tests/data/cases/preview_context_managers_autodetect_39.py @@ -1,3 +1,4 @@ +# flags: --preview --minimum-version=3.9 # This file uses parenthesized context managers introduced in Python 3.9. diff --git a/tests/data/preview/dummy_implementations.py b/tests/data/cases/preview_dummy_implementations.py similarity index 98% rename from tests/data/preview/dummy_implementations.py rename to tests/data/cases/preview_dummy_implementations.py index e07c25e..98b69bf 100644 --- a/tests/data/preview/dummy_implementations.py +++ b/tests/data/cases/preview_dummy_implementations.py @@ -1,3 +1,4 @@ +# flags: --preview from typing import NoReturn, Protocol, Union, overload diff --git a/tests/data/preview/format_unicode_escape_seq.py b/tests/data/cases/preview_format_unicode_escape_seq.py similarity index 96% rename from tests/data/preview/format_unicode_escape_seq.py rename to tests/data/cases/preview_format_unicode_escape_seq.py index 3440696..65c3d8d 100644 --- a/tests/data/preview/format_unicode_escape_seq.py +++ b/tests/data/cases/preview_format_unicode_escape_seq.py @@ -1,3 +1,4 @@ +# flags: --preview x = "\x1F" x = "\\x1B" x = "\\\x1B" diff --git a/tests/data/preview/long_dict_values.py b/tests/data/cases/preview_long_dict_values.py similarity index 99% rename from tests/data/preview/long_dict_values.py rename to tests/data/cases/preview_long_dict_values.py index 4c51518..fbbacd1 100644 --- a/tests/data/preview/long_dict_values.py +++ b/tests/data/cases/preview_long_dict_values.py @@ -1,3 +1,4 @@ +# flags: --preview my_dict = { "something_something": r"Lorem ipsum dolor sit amet, an sed convenire eloquentiam \t" diff --git a/tests/data/preview/long_strings.py b/tests/data/cases/preview_long_strings.py similarity index 99% rename from tests/data/preview/long_strings.py rename to tests/data/cases/preview_long_strings.py index 0591487..5519f09 100644 --- a/tests/data/preview/long_strings.py +++ b/tests/data/cases/preview_long_strings.py @@ -1,3 +1,4 @@ +# flags: --preview x = "This is a really long string that can't possibly be expected to fit all together on one line. In fact it may even take up three or more lines... like four or five... but probably just three." x += "This is a really long string that can't possibly be expected to fit all together on one line. In fact it may even take up three or more lines... like four or five... but probably just three." diff --git a/tests/data/preview/long_strings__east_asian_width.py b/tests/data/cases/preview_long_strings__east_asian_width.py similarity index 96% rename from tests/data/preview/long_strings__east_asian_width.py rename to tests/data/cases/preview_long_strings__east_asian_width.py index fb66a78..d190f42 100644 --- a/tests/data/preview/long_strings__east_asian_width.py +++ b/tests/data/cases/preview_long_strings__east_asian_width.py @@ -1,3 +1,4 @@ +# flags: --preview # The following strings do not have not-so-many chars, but are long enough # when these are rendered in a monospace font (if the renderer respects # Unicode East Asian Width properties). diff --git a/tests/data/preview/long_strings__edge_case.py b/tests/data/cases/preview_long_strings__edge_case.py similarity index 99% rename from tests/data/preview/long_strings__edge_case.py rename to tests/data/cases/preview_long_strings__edge_case.py index 2bc0b6e..a8e8971 100644 --- a/tests/data/preview/long_strings__edge_case.py +++ b/tests/data/cases/preview_long_strings__edge_case.py @@ -1,3 +1,4 @@ +# flags: --preview some_variable = "This string is long but not so long that it needs to be split just yet" some_variable = 'This string is long but not so long that it needs to be split just yet' some_variable = "This string is long, just long enough that it needs to be split, u get?" diff --git a/tests/data/preview/long_strings__regression.py b/tests/data/cases/preview_long_strings__regression.py similarity index 99% rename from tests/data/preview/long_strings__regression.py rename to tests/data/cases/preview_long_strings__regression.py index 5f0646e..40d5e74 100644 --- a/tests/data/preview/long_strings__regression.py +++ b/tests/data/cases/preview_long_strings__regression.py @@ -1,3 +1,4 @@ +# flags: --preview class A: def foo(): result = type(message)("") diff --git a/tests/data/preview/long_strings__type_annotations.py b/tests/data/cases/preview_long_strings__type_annotations.py similarity index 98% rename from tests/data/preview/long_strings__type_annotations.py rename to tests/data/cases/preview_long_strings__type_annotations.py index 45de882..8beb877 100644 --- a/tests/data/preview/long_strings__type_annotations.py +++ b/tests/data/cases/preview_long_strings__type_annotations.py @@ -1,3 +1,4 @@ +# flags: --preview def func( arg1, arg2, diff --git a/tests/data/preview/multiline_strings.py b/tests/data/cases/preview_multiline_strings.py similarity index 99% rename from tests/data/preview/multiline_strings.py rename to tests/data/cases/preview_multiline_strings.py index bb517d1..dec4ef2 100644 --- a/tests/data/preview/multiline_strings.py +++ b/tests/data/cases/preview_multiline_strings.py @@ -1,3 +1,4 @@ +# flags: --preview """cow say""", call(3, "dogsay", textwrap.dedent("""dove diff --git a/tests/data/preview/no_blank_line_before_docstring.py b/tests/data/cases/preview_no_blank_line_before_docstring.py similarity index 97% rename from tests/data/preview/no_blank_line_before_docstring.py rename to tests/data/cases/preview_no_blank_line_before_docstring.py index a37362d..303035a 100644 --- a/tests/data/preview/no_blank_line_before_docstring.py +++ b/tests/data/cases/preview_no_blank_line_before_docstring.py @@ -1,3 +1,4 @@ +# flags: --preview def line_before_docstring(): """Please move me up""" diff --git a/tests/data/preview/pep_572.py b/tests/data/cases/preview_pep_572.py similarity index 75% rename from tests/data/preview/pep_572.py rename to tests/data/cases/preview_pep_572.py index a50e130..8e801ff 100644 --- a/tests/data/preview/pep_572.py +++ b/tests/data/cases/preview_pep_572.py @@ -1,3 +1,4 @@ +# flags: --preview x[(a:=0):] x[:(a:=0)] diff --git a/tests/data/preview/percent_precedence.py b/tests/data/cases/preview_percent_precedence.py similarity index 96% rename from tests/data/preview/percent_precedence.py rename to tests/data/cases/preview_percent_precedence.py index b895443..aeaf450 100644 --- a/tests/data/preview/percent_precedence.py +++ b/tests/data/cases/preview_percent_precedence.py @@ -1,3 +1,4 @@ +# flags: --preview ("" % a) ** 2 ("" % a)[0] ("" % a)() diff --git a/tests/data/preview/prefer_rhs_split.py b/tests/data/cases/preview_prefer_rhs_split.py similarity index 99% rename from tests/data/preview/prefer_rhs_split.py rename to tests/data/cases/preview_prefer_rhs_split.py index a809eac..c732c33 100644 --- a/tests/data/preview/prefer_rhs_split.py +++ b/tests/data/cases/preview_prefer_rhs_split.py @@ -1,3 +1,4 @@ +# flags: --preview first_item, second_item = ( some_looooooooong_module.some_looooooooooooooong_function_name( first_argument, second_argument, third_argument diff --git a/tests/data/preview/return_annotation_brackets_string.py b/tests/data/cases/preview_return_annotation_brackets_string.py similarity index 97% rename from tests/data/preview/return_annotation_brackets_string.py rename to tests/data/cases/preview_return_annotation_brackets_string.py index 9148bd0..fea0ea6 100644 --- a/tests/data/preview/return_annotation_brackets_string.py +++ b/tests/data/cases/preview_return_annotation_brackets_string.py @@ -1,3 +1,4 @@ +# flags: --preview # Long string example def frobnicate() -> "ThisIsTrulyUnreasonablyExtremelyLongClassName | list[ThisIsTrulyUnreasonablyExtremelyLongClassName]": pass diff --git a/tests/data/preview/trailing_comma.py b/tests/data/cases/preview_trailing_comma.py similarity index 97% rename from tests/data/preview/trailing_comma.py rename to tests/data/cases/preview_trailing_comma.py index 5b09c66..bba7e7a 100644 --- a/tests/data/preview/trailing_comma.py +++ b/tests/data/cases/preview_trailing_comma.py @@ -1,3 +1,4 @@ +# flags: --preview e = { "a": fun(msg, "ts"), "longggggggggggggggid": ..., diff --git a/tests/data/preview_py_310/pep_572.py b/tests/data/cases/py310_pep572.py similarity index 77% rename from tests/data/preview_py_310/pep_572.py rename to tests/data/cases/py310_pep572.py index 78d4e9e..172be38 100644 --- a/tests/data/preview_py_310/pep_572.py +++ b/tests/data/cases/py310_pep572.py @@ -1,3 +1,4 @@ +# flags: --preview --minimum-version=3.10 x[a:=0] x[a := 0] x[a := 0, b := 1] diff --git a/tests/data/py_37/python37.py b/tests/data/cases/python37.py similarity index 95% rename from tests/data/py_37/python37.py rename to tests/data/cases/python37.py index dab8b40..3f61106 100644 --- a/tests/data/py_37/python37.py +++ b/tests/data/cases/python37.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3.7 +# flags: --minimum-version=3.7 def f(): @@ -33,9 +33,6 @@ def make_arange(n): # output -#!/usr/bin/env python3.7 - - def f(): return (i * 2 async for i in arange(42)) diff --git a/tests/data/py_38/python38.py b/tests/data/cases/python38.py similarity index 93% rename from tests/data/py_38/python38.py rename to tests/data/cases/python38.py index 63b0588..919ea6a 100644 --- a/tests/data/py_38/python38.py +++ b/tests/data/cases/python38.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3.8 +# flags: --minimum-version=3.8 def starred_return(): @@ -22,9 +22,6 @@ def t(): # output -#!/usr/bin/env python3.8 - - def starred_return(): my_list = ["value2", "value3"] return "value1", *my_list diff --git a/tests/data/py_39/python39.py b/tests/data/cases/python39.py similarity index 91% rename from tests/data/py_39/python39.py rename to tests/data/cases/python39.py index ae67c22..1b9536c 100644 --- a/tests/data/py_39/python39.py +++ b/tests/data/cases/python39.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3.9 +# flags: --minimum-version=3.9 @relaxed_decorator[0] def f(): @@ -14,10 +14,6 @@ def f(): # output - -#!/usr/bin/env python3.9 - - @relaxed_decorator[0] def f(): ... diff --git a/tests/data/simple_cases/remove_await_parens.py b/tests/data/cases/remove_await_parens.py similarity index 100% rename from tests/data/simple_cases/remove_await_parens.py rename to tests/data/cases/remove_await_parens.py diff --git a/tests/data/simple_cases/remove_except_parens.py b/tests/data/cases/remove_except_parens.py similarity index 100% rename from tests/data/simple_cases/remove_except_parens.py rename to tests/data/cases/remove_except_parens.py diff --git a/tests/data/simple_cases/remove_for_brackets.py b/tests/data/cases/remove_for_brackets.py similarity index 100% rename from tests/data/simple_cases/remove_for_brackets.py rename to tests/data/cases/remove_for_brackets.py diff --git a/tests/data/simple_cases/remove_newline_after_code_block_open.py b/tests/data/cases/remove_newline_after_code_block_open.py similarity index 100% rename from tests/data/simple_cases/remove_newline_after_code_block_open.py rename to tests/data/cases/remove_newline_after_code_block_open.py diff --git a/tests/data/py_310/remove_newline_after_match.py b/tests/data/cases/remove_newline_after_match.py similarity index 88% rename from tests/data/py_310/remove_newline_after_match.py rename to tests/data/cases/remove_newline_after_match.py index f7bcfbf..fe6592b 100644 --- a/tests/data/py_310/remove_newline_after_match.py +++ b/tests/data/cases/remove_newline_after_match.py @@ -1,3 +1,4 @@ +# flags: --minimum-version=3.10 def http_status(status): match status: diff --git a/tests/data/simple_cases/remove_parens.py b/tests/data/cases/remove_parens.py similarity index 100% rename from tests/data/simple_cases/remove_parens.py rename to tests/data/cases/remove_parens.py diff --git a/tests/data/py_39/remove_with_brackets.py b/tests/data/cases/remove_with_brackets.py similarity index 98% rename from tests/data/py_39/remove_with_brackets.py rename to tests/data/cases/remove_with_brackets.py index ea58ab9..3ee6490 100644 --- a/tests/data/py_39/remove_with_brackets.py +++ b/tests/data/cases/remove_with_brackets.py @@ -1,3 +1,4 @@ +# flags: --minimum-version=3.9 with (open("bla.txt")): pass diff --git a/tests/data/simple_cases/return_annotation_brackets.py b/tests/data/cases/return_annotation_brackets.py similarity index 100% rename from tests/data/simple_cases/return_annotation_brackets.py rename to tests/data/cases/return_annotation_brackets.py diff --git a/tests/data/simple_cases/skip_magic_trailing_comma.py b/tests/data/cases/skip_magic_trailing_comma.py similarity index 97% rename from tests/data/simple_cases/skip_magic_trailing_comma.py rename to tests/data/cases/skip_magic_trailing_comma.py index c020db7..4dda5df 100644 --- a/tests/data/simple_cases/skip_magic_trailing_comma.py +++ b/tests/data/cases/skip_magic_trailing_comma.py @@ -1,3 +1,4 @@ +# flags: --skip-magic-trailing-comma # We should not remove the trailing comma in a single-element subscript. a: tuple[int,] b = tuple[int,] diff --git a/tests/data/simple_cases/slices.py b/tests/data/cases/slices.py similarity index 100% rename from tests/data/simple_cases/slices.py rename to tests/data/cases/slices.py diff --git a/tests/data/py_310/starred_for_target.py b/tests/data/cases/starred_for_target.py similarity index 92% rename from tests/data/py_310/starred_for_target.py rename to tests/data/cases/starred_for_target.py index 8fc8e05..13e5178 100644 --- a/tests/data/py_310/starred_for_target.py +++ b/tests/data/cases/starred_for_target.py @@ -1,3 +1,4 @@ +# flags: --minimum-version=3.10 for x in *a, *b: print(x) diff --git a/tests/data/simple_cases/string_prefixes.py b/tests/data/cases/string_prefixes.py similarity index 100% rename from tests/data/simple_cases/string_prefixes.py rename to tests/data/cases/string_prefixes.py diff --git a/tests/data/miscellaneous/stub.pyi b/tests/data/cases/stub.py similarity index 99% rename from tests/data/miscellaneous/stub.pyi rename to tests/data/cases/stub.py index af2cd2c..f3828d5 100644 --- a/tests/data/miscellaneous/stub.pyi +++ b/tests/data/cases/stub.py @@ -1,3 +1,4 @@ +# flags: --pyi X: int def f(): ... diff --git a/tests/data/simple_cases/torture.py b/tests/data/cases/torture.py similarity index 100% rename from tests/data/simple_cases/torture.py rename to tests/data/cases/torture.py diff --git a/tests/data/simple_cases/trailing_comma_optional_parens1.py b/tests/data/cases/trailing_comma_optional_parens1.py similarity index 100% rename from tests/data/simple_cases/trailing_comma_optional_parens1.py rename to tests/data/cases/trailing_comma_optional_parens1.py diff --git a/tests/data/simple_cases/trailing_comma_optional_parens2.py b/tests/data/cases/trailing_comma_optional_parens2.py similarity index 100% rename from tests/data/simple_cases/trailing_comma_optional_parens2.py rename to tests/data/cases/trailing_comma_optional_parens2.py diff --git a/tests/data/simple_cases/trailing_comma_optional_parens3.py b/tests/data/cases/trailing_comma_optional_parens3.py similarity index 100% rename from tests/data/simple_cases/trailing_comma_optional_parens3.py rename to tests/data/cases/trailing_comma_optional_parens3.py diff --git a/tests/data/simple_cases/trailing_commas_in_leading_parts.py b/tests/data/cases/trailing_commas_in_leading_parts.py similarity index 100% rename from tests/data/simple_cases/trailing_commas_in_leading_parts.py rename to tests/data/cases/trailing_commas_in_leading_parts.py diff --git a/tests/data/simple_cases/tricky_unicode_symbols.py b/tests/data/cases/tricky_unicode_symbols.py similarity index 100% rename from tests/data/simple_cases/tricky_unicode_symbols.py rename to tests/data/cases/tricky_unicode_symbols.py diff --git a/tests/data/simple_cases/tupleassign.py b/tests/data/cases/tupleassign.py similarity index 100% rename from tests/data/simple_cases/tupleassign.py rename to tests/data/cases/tupleassign.py diff --git a/tests/data/py_312/type_aliases.py b/tests/data/cases/type_aliases.py similarity index 81% rename from tests/data/py_312/type_aliases.py rename to tests/data/cases/type_aliases.py index 84e07e5..a3c1931 100644 --- a/tests/data/py_312/type_aliases.py +++ b/tests/data/cases/type_aliases.py @@ -1,3 +1,4 @@ +# flags: --minimum-version=3.12 type A=int type Gen[T]=list[T] diff --git a/tests/data/type_comments/type_comment_syntax_error.py b/tests/data/cases/type_comment_syntax_error.py similarity index 100% rename from tests/data/type_comments/type_comment_syntax_error.py rename to tests/data/cases/type_comment_syntax_error.py diff --git a/tests/data/py_312/type_params.py b/tests/data/cases/type_params.py similarity index 97% rename from tests/data/py_312/type_params.py rename to tests/data/cases/type_params.py index 5f8ec43..720a775 100644 --- a/tests/data/py_312/type_params.py +++ b/tests/data/cases/type_params.py @@ -1,3 +1,4 @@ +# flags: --minimum-version=3.12 def func [T ](): pass async def func [ T ] (): pass class C[ T ] : pass diff --git a/tests/data/simple_cases/whitespace.py b/tests/data/cases/whitespace.py similarity index 100% rename from tests/data/simple_cases/whitespace.py rename to tests/data/cases/whitespace.py diff --git a/tests/data/miscellaneous/force_pyi.py b/tests/data/miscellaneous/force_pyi.py index 07ed93c..40caf30 100644 --- a/tests/data/miscellaneous/force_pyi.py +++ b/tests/data/miscellaneous/force_pyi.py @@ -1,3 +1,4 @@ +# flags: --pyi from typing import Union @bird diff --git a/tests/test_black.py b/tests/test_black.py index c665eee..bb5cc1e 100644 --- a/tests/test_black.py +++ b/tests/test_black.py @@ -187,7 +187,9 @@ class BlackTestCase(BlackBaseTestCase): ) def test_piping(self) -> None: - source, expected = read_data_from_file(PROJECT_ROOT / "src/black/__init__.py") + _, source, expected = read_data_from_file( + PROJECT_ROOT / "src/black/__init__.py" + ) result = BlackRunner().invoke( black.main, [ @@ -209,8 +211,8 @@ class BlackTestCase(BlackBaseTestCase): r"(STDIN|STDOUT)\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d\.\d\d\d\d\d\d" r"\+\d\d:\d\d" ) - source, _ = read_data("simple_cases", "expression.py") - expected, _ = read_data("simple_cases", "expression.diff") + source, _ = read_data("cases", "expression.py") + expected, _ = read_data("cases", "expression.diff") args = [ "-", "--fast", @@ -227,7 +229,7 @@ class BlackTestCase(BlackBaseTestCase): self.assertEqual(expected, actual) def test_piping_diff_with_color(self) -> None: - source, _ = read_data("simple_cases", "expression.py") + source, _ = read_data("cases", "expression.py") args = [ "-", "--fast", @@ -263,7 +265,7 @@ class BlackTestCase(BlackBaseTestCase): black.assert_stable(source, actual, black.FileMode()) def test_pep_572_version_detection(self) -> None: - source, _ = read_data("py_38", "pep_572") + source, _ = read_data("cases", "pep_572") root = black.lib2to3_parse(source) features = black.get_features_used(root) self.assertIn(black.Feature.ASSIGNMENT_EXPRESSIONS, features) @@ -272,7 +274,7 @@ class BlackTestCase(BlackBaseTestCase): def test_pep_695_version_detection(self) -> None: for file in ("type_aliases", "type_params"): - source, _ = read_data("py_312", file) + source, _ = read_data("cases", file) root = black.lib2to3_parse(source) features = black.get_features_used(root) self.assertIn(black.Feature.TYPE_PARAMS, features) @@ -280,7 +282,7 @@ class BlackTestCase(BlackBaseTestCase): self.assertIn(black.TargetVersion.PY312, versions) def test_expression_ff(self) -> None: - source, expected = read_data("simple_cases", "expression.py") + source, expected = read_data("cases", "expression.py") tmp_file = Path(black.dump_to_file(source)) try: self.assertTrue(ff(tmp_file, write_back=black.WriteBack.YES)) @@ -293,8 +295,8 @@ class BlackTestCase(BlackBaseTestCase): black.assert_stable(source, actual, DEFAULT_MODE) def test_expression_diff(self) -> None: - source, _ = read_data("simple_cases", "expression.py") - expected, _ = read_data("simple_cases", "expression.diff") + source, _ = read_data("cases", "expression.py") + expected, _ = read_data("cases", "expression.diff") tmp_file = Path(black.dump_to_file(source)) diff_header = re.compile( rf"{re.escape(str(tmp_file))}\t\d\d\d\d-\d\d-\d\d " @@ -319,8 +321,8 @@ class BlackTestCase(BlackBaseTestCase): self.assertEqual(expected, actual, msg) def test_expression_diff_with_color(self) -> None: - source, _ = read_data("simple_cases", "expression.py") - expected, _ = read_data("simple_cases", "expression.diff") + source, _ = read_data("cases", "expression.py") + expected, _ = read_data("cases", "expression.diff") tmp_file = Path(black.dump_to_file(source)) try: result = BlackRunner().invoke( @@ -339,7 +341,7 @@ class BlackTestCase(BlackBaseTestCase): self.assertIn("\033[0m", actual) def test_detect_pos_only_arguments(self) -> None: - source, _ = read_data("py_38", "pep_570") + source, _ = read_data("cases", "pep_570") root = black.lib2to3_parse(source) features = black.get_features_used(root) self.assertIn(black.Feature.POS_ONLY_ARGUMENTS, features) @@ -401,7 +403,7 @@ class BlackTestCase(BlackBaseTestCase): self.assertEqual(test_file.read_bytes(), expected) def test_skip_magic_trailing_comma(self) -> None: - source, _ = read_data("simple_cases", "expression") + source, _ = read_data("cases", "expression") expected, _ = read_data( "miscellaneous", "expression_skip_magic_trailing_comma.diff" ) @@ -433,7 +435,7 @@ class BlackTestCase(BlackBaseTestCase): @patch("black.dump_to_file", dump_to_stderr) def test_async_as_identifier(self) -> None: source_path = get_case_path("miscellaneous", "async_as_identifier") - source, expected = read_data_from_file(source_path) + _, source, expected = read_data_from_file(source_path) actual = fs(source) self.assertFormatEqual(expected, actual) major, minor = sys.version_info[:2] @@ -447,8 +449,8 @@ class BlackTestCase(BlackBaseTestCase): @patch("black.dump_to_file", dump_to_stderr) def test_python37(self) -> None: - source_path = get_case_path("py_37", "python37") - source, expected = read_data_from_file(source_path) + source_path = get_case_path("cases", "python37") + _, source, expected = read_data_from_file(source_path) actual = fs(source) self.assertFormatEqual(expected, actual) major, minor = sys.version_info[:2] @@ -884,7 +886,7 @@ class BlackTestCase(BlackBaseTestCase): self.assertEqual(black.get_features_used(node), {Feature.NUMERIC_UNDERSCORES}) node = black.lib2to3_parse("123456\n") self.assertEqual(black.get_features_used(node), set()) - source, expected = read_data("simple_cases", "function") + source, expected = read_data("cases", "function") node = black.lib2to3_parse(source) expected_features = { Feature.TRAILING_COMMA_IN_CALL, @@ -894,7 +896,7 @@ class BlackTestCase(BlackBaseTestCase): self.assertEqual(black.get_features_used(node), expected_features) node = black.lib2to3_parse(expected) self.assertEqual(black.get_features_used(node), expected_features) - source, expected = read_data("simple_cases", "expression") + source, expected = read_data("cases", "expression") node = black.lib2to3_parse(source) self.assertEqual(black.get_features_used(node), set()) node = black.lib2to3_parse(expected) @@ -1109,7 +1111,7 @@ class BlackTestCase(BlackBaseTestCase): src1 = get_case_path("miscellaneous", "string_quotes") self.invokeBlack([str(src1), "--diff", "--check"], exit_code=1) # Files which will not be reformatted. - src2 = get_case_path("simple_cases", "composition") + src2 = get_case_path("cases", "composition") self.invokeBlack([str(src2), "--diff", "--check"]) # Multi file command. self.invokeBlack([str(src1), str(src2), "--diff", "--check"], exit_code=1) @@ -1330,7 +1332,7 @@ class BlackTestCase(BlackBaseTestCase): report = MagicMock() # Even with an existing file, since we are forcing stdin, black # should output to stdout and not modify the file inplace - p = THIS_DIR / "data" / "simple_cases" / "collections.py" + p = THIS_DIR / "data" / "cases" / "collections.py" # Make sure is_file actually returns True self.assertTrue(p.is_file()) path = Path(f"__BLACK_STDIN_FILENAME__{p}") diff --git a/tests/test_blackd.py b/tests/test_blackd.py index dd2126e..c0152de 100644 --- a/tests/test_blackd.py +++ b/tests/test_blackd.py @@ -104,7 +104,7 @@ class BlackDTestCase(AioHTTPTestCase): # type: ignore[misc] @unittest_run_loop async def test_blackd_pyi(self) -> None: - source, expected = read_data("miscellaneous", "stub.pyi") + source, expected = read_data("cases", "stub.py") response = await self.client.post( "/", data=source, headers={blackd.PYTHON_VARIANT_HEADER: "pyi"} ) diff --git a/tests/test_format.py b/tests/test_format.py index ff358d5..4e863c6 100644 --- a/tests/test_format.py +++ b/tests/test_format.py @@ -1,4 +1,3 @@ -import re from dataclasses import replace from typing import Any, Iterator from unittest.mock import patch @@ -6,13 +5,13 @@ from unittest.mock import patch import pytest import black +from black.mode import TargetVersion from tests.util import ( - DEFAULT_MODE, - PY36_VERSIONS, all_data_cases, assert_format, dump_to_stderr, read_data, + read_data_with_mode, ) @@ -22,61 +21,33 @@ def patch_dump_to_file(request: Any) -> Iterator[None]: yield -def check_file( - subdir: str, filename: str, mode: black.Mode, *, data: bool = True -) -> None: - source, expected = read_data(subdir, filename, data=data) - assert_format(source, expected, mode, fast=False) +def check_file(subdir: str, filename: str, *, data: bool = True) -> None: + args, source, expected = read_data_with_mode(subdir, filename, data=data) + assert_format( + source, + expected, + args.mode, + fast=args.fast, + minimum_version=args.minimum_version, + ) + if args.minimum_version is not None: + major, minor = args.minimum_version + target_version = TargetVersion[f"PY{major}{minor}"] + mode = replace(args.mode, target_versions={target_version}) + assert_format( + source, expected, mode, fast=args.fast, minimum_version=args.minimum_version + ) @pytest.mark.filterwarnings("ignore:invalid escape sequence.*:DeprecationWarning") -@pytest.mark.parametrize("filename", all_data_cases("simple_cases")) +@pytest.mark.parametrize("filename", all_data_cases("cases")) def test_simple_format(filename: str) -> None: - magic_trailing_comma = filename != "skip_magic_trailing_comma" - mode = black.Mode( - magic_trailing_comma=magic_trailing_comma, is_pyi=filename.endswith("_pyi") - ) - check_file("simple_cases", filename, mode) - - -@pytest.mark.parametrize("filename", all_data_cases("preview")) -def test_preview_format(filename: str) -> None: - check_file("preview", filename, black.Mode(preview=True)) - - -def test_preview_context_managers_targeting_py38() -> None: - source, expected = read_data("preview_context_managers", "targeting_py38.py") - mode = black.Mode(preview=True, target_versions={black.TargetVersion.PY38}) - assert_format(source, expected, mode, minimum_version=(3, 8)) - - -def test_preview_context_managers_targeting_py39() -> None: - source, expected = read_data("preview_context_managers", "targeting_py39.py") - mode = black.Mode(preview=True, target_versions={black.TargetVersion.PY39}) - assert_format(source, expected, mode, minimum_version=(3, 9)) - - -@pytest.mark.parametrize("filename", all_data_cases("preview_py_310")) -def test_preview_python_310(filename: str) -> None: - source, expected = read_data("preview_py_310", filename) - mode = black.Mode(target_versions={black.TargetVersion.PY310}, preview=True) - assert_format(source, expected, mode, minimum_version=(3, 10)) - - -@pytest.mark.parametrize( - "filename", all_data_cases("preview_context_managers/auto_detect") -) -def test_preview_context_managers_auto_detect(filename: str) -> None: - match = re.match(r"features_3_(\d+)", filename) - assert match is not None, "Unexpected filename format: %s" % filename - source, expected = read_data("preview_context_managers/auto_detect", filename) - mode = black.Mode(preview=True) - assert_format(source, expected, mode, minimum_version=(3, int(match.group(1)))) + check_file("cases", filename) # =============== # -# Complex cases -# ============= # +# Unusual cases +# =============== # def test_empty() -> None: @@ -84,48 +55,6 @@ def test_empty() -> None: assert_format(source, expected) -@pytest.mark.parametrize("filename", all_data_cases("py_36")) -def test_python_36(filename: str) -> None: - source, expected = read_data("py_36", filename) - mode = black.Mode(target_versions=PY36_VERSIONS) - assert_format(source, expected, mode, minimum_version=(3, 6)) - - -@pytest.mark.parametrize("filename", all_data_cases("py_37")) -def test_python_37(filename: str) -> None: - source, expected = read_data("py_37", filename) - mode = black.Mode(target_versions={black.TargetVersion.PY37}) - assert_format(source, expected, mode, minimum_version=(3, 7)) - - -@pytest.mark.parametrize("filename", all_data_cases("py_38")) -def test_python_38(filename: str) -> None: - source, expected = read_data("py_38", filename) - mode = black.Mode(target_versions={black.TargetVersion.PY38}) - assert_format(source, expected, mode, minimum_version=(3, 8)) - - -@pytest.mark.parametrize("filename", all_data_cases("py_39")) -def test_python_39(filename: str) -> None: - source, expected = read_data("py_39", filename) - mode = black.Mode(target_versions={black.TargetVersion.PY39}) - assert_format(source, expected, mode, minimum_version=(3, 9)) - - -@pytest.mark.parametrize("filename", all_data_cases("py_310")) -def test_python_310(filename: str) -> None: - source, expected = read_data("py_310", filename) - mode = black.Mode(target_versions={black.TargetVersion.PY310}) - assert_format(source, expected, mode, minimum_version=(3, 10)) - - -@pytest.mark.parametrize("filename", all_data_cases("py_310")) -def test_python_310_without_target_version(filename: str) -> None: - source, expected = read_data("py_310", filename) - mode = black.Mode() - assert_format(source, expected, mode, minimum_version=(3, 10)) - - def test_patma_invalid() -> None: source, expected = read_data("miscellaneous", "pattern_matching_invalid") mode = black.Mode(target_versions={black.TargetVersion.PY310}) @@ -133,82 +62,3 @@ def test_patma_invalid() -> None: assert_format(source, expected, mode, minimum_version=(3, 10)) exc_info.match("Cannot parse: 10:11") - - -@pytest.mark.parametrize("filename", all_data_cases("py_311")) -def test_python_311(filename: str) -> None: - source, expected = read_data("py_311", filename) - mode = black.Mode(target_versions={black.TargetVersion.PY311}) - assert_format(source, expected, mode, minimum_version=(3, 11)) - - -@pytest.mark.parametrize("filename", all_data_cases("py_312")) -def test_python_312(filename: str) -> None: - source, expected = read_data("py_312", filename) - mode = black.Mode(target_versions={black.TargetVersion.PY312}) - assert_format(source, expected, mode, minimum_version=(3, 12)) - - -@pytest.mark.parametrize("filename", all_data_cases("fast")) -def test_fast_cases(filename: str) -> None: - source, expected = read_data("fast", filename) - assert_format(source, expected, fast=True) - - -@pytest.mark.filterwarnings("ignore:invalid escape sequence.*:DeprecationWarning") -def test_docstring_no_string_normalization() -> None: - """Like test_docstring but with string normalization off.""" - source, expected = read_data("miscellaneous", "docstring_no_string_normalization") - mode = replace(DEFAULT_MODE, string_normalization=False) - assert_format(source, expected, mode) - - -def test_docstring_line_length_6() -> None: - """Like test_docstring but with line length set to 6.""" - source, expected = read_data("miscellaneous", "linelength6") - mode = black.Mode(line_length=6) - assert_format(source, expected, mode) - - -def test_preview_docstring_no_string_normalization() -> None: - """ - Like test_docstring but with string normalization off *and* the preview style - enabled. - """ - source, expected = read_data( - "miscellaneous", "docstring_preview_no_string_normalization" - ) - mode = replace(DEFAULT_MODE, string_normalization=False, preview=True) - assert_format(source, expected, mode) - - -def test_long_strings_flag_disabled() -> None: - """Tests for turning off the string processing logic.""" - source, expected = read_data("miscellaneous", "long_strings_flag_disabled") - mode = replace(DEFAULT_MODE, experimental_string_processing=False) - assert_format(source, expected, mode) - - -def test_stub() -> None: - mode = replace(DEFAULT_MODE, is_pyi=True) - source, expected = read_data("miscellaneous", "stub.pyi") - assert_format(source, expected, mode) - - -def test_nested_stub() -> None: - mode = replace(DEFAULT_MODE, is_pyi=True, preview=True) - source, expected = read_data("miscellaneous", "nested_stub.pyi") - assert_format(source, expected, mode) - - -def test_power_op_newline() -> None: - # requires line_length=0 - source, expected = read_data("miscellaneous", "power_op_newline") - assert_format(source, expected, mode=black.Mode(line_length=0)) - - -def test_type_comment_syntax_error() -> None: - """Test that black is able to format python code with type comment syntax errors.""" - source, expected = read_data("type_comments", "type_comment_syntax_error") - assert_format(source, expected) - black.assert_equivalent(source, expected) diff --git a/tests/util.py b/tests/util.py index 541d21d..a31ae09 100644 --- a/tests/util.py +++ b/tests/util.py @@ -1,13 +1,17 @@ +import argparse +import functools import os +import shlex import sys import unittest from contextlib import contextmanager -from dataclasses import replace +from dataclasses import dataclass, field, replace from functools import partial from pathlib import Path from typing import Any, Iterator, List, Optional, Tuple import black +from black.const import DEFAULT_LINE_LENGTH from black.debug import DebugVisitor from black.mode import TargetVersion from black.output import diff, err, out @@ -35,6 +39,13 @@ ff = partial(black.format_file_in_place, mode=DEFAULT_MODE, fast=True) fs = partial(black.format_str, mode=DEFAULT_MODE) +@dataclass +class TestCaseArgs: + mode: black.Mode = field(default_factory=black.Mode) + fast: bool = False + minimum_version: Optional[Tuple[int, int]] = None + + def _assert_format_equal(expected: str, actual: str) -> None: if actual != expected and (conftest.PRINT_FULL_TREE or conftest.PRINT_TREE_DIFF): bdv: DebugVisitor[Any] @@ -178,18 +189,85 @@ def get_case_path( return case_path +def read_data_with_mode( + subdir_name: str, name: str, data: bool = True +) -> Tuple[TestCaseArgs, str, str]: + """read_data_with_mode('test_name') -> Mode(), 'input', 'output'""" + return read_data_from_file(get_case_path(subdir_name, name, data)) + + def read_data(subdir_name: str, name: str, data: bool = True) -> Tuple[str, str]: """read_data('test_name') -> 'input', 'output'""" - return read_data_from_file(get_case_path(subdir_name, name, data)) + _, input, output = read_data_with_mode(subdir_name, name, data) + return input, output + + +def _parse_minimum_version(version: str) -> Tuple[int, int]: + major, minor = version.split(".") + return int(major), int(minor) -def read_data_from_file(file_name: Path) -> Tuple[str, str]: +@functools.lru_cache() +def get_flags_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser() + parser.add_argument( + "--target-version", + action="append", + type=lambda val: TargetVersion[val.upper()], + default=(), + ) + parser.add_argument("--line-length", default=DEFAULT_LINE_LENGTH, type=int) + parser.add_argument( + "--skip-string-normalization", default=False, action="store_true" + ) + parser.add_argument("--pyi", default=False, action="store_true") + parser.add_argument("--ipynb", default=False, action="store_true") + parser.add_argument( + "--skip-magic-trailing-comma", default=False, action="store_true" + ) + parser.add_argument("--preview", default=False, action="store_true") + parser.add_argument("--fast", default=False, action="store_true") + parser.add_argument( + "--minimum-version", + type=_parse_minimum_version, + default=None, + help=( + "Minimum version of Python where this test case is parseable. If this is" + " set, the test case will be run twice: once with the specified" + " --target-version, and once with --target-version set to exactly the" + " specified version. This ensures that Black's autodetection of the target" + " version works correctly." + ), + ) + return parser + + +def parse_mode(flags_line: str) -> TestCaseArgs: + parser = get_flags_parser() + args = parser.parse_args(shlex.split(flags_line)) + mode = black.Mode( + target_versions=set(args.target_version), + line_length=args.line_length, + string_normalization=not args.skip_string_normalization, + is_pyi=args.pyi, + is_ipynb=args.ipynb, + magic_trailing_comma=not args.skip_magic_trailing_comma, + preview=args.preview, + ) + return TestCaseArgs(mode=mode, fast=args.fast, minimum_version=args.minimum_version) + + +def read_data_from_file(file_name: Path) -> Tuple[TestCaseArgs, str, str]: with open(file_name, "r", encoding="utf8") as test: lines = test.readlines() _input: List[str] = [] _output: List[str] = [] result = _input + mode = TestCaseArgs() for line in lines: + if not _input and line.startswith("# flags: "): + mode = parse_mode(line[len("# flags: ") :]) + continue line = line.replace(EMPTY_LINE, "") if line.rstrip() == "# output": result = _output @@ -199,7 +277,7 @@ def read_data_from_file(file_name: Path) -> Tuple[str, str]: if _input and not _output: # If there's no output marker, treat the entire file as already pre-formatted. _output = _input[:] - return "".join(_input).strip() + "\n", "".join(_output).strip() + "\n" + return mode, "".join(_input).strip() + "\n", "".join(_output).strip() + "\n" def read_jupyter_notebook(subdir_name: str, name: str, data: bool = True) -> str: