From 015d2bd1c4cd6e364a3b50ea83bcaa0dcdf734c3 Mon Sep 17 00:00:00 2001 From: Jonathan Schneider Date: Tue, 20 Aug 2024 08:58:04 -0400 Subject: [PATCH] Add rewrite-test --- rewrite/rewrite-test/poetry.lock | 114 +++++++++ rewrite/rewrite-test/pyproject.toml | 20 ++ .../rewrite-test/src/rewrite/test/__init__.py | 0 .../src/rewrite/test/source_specs.py | 16 ++ rewrite/rewrite-test/src/rewrite/test/test.py | 5 + rewrite/rewrite-test/tests/java/.editorconfig | 5 + .../python/ChangeMethodNameTest.java | 51 ++++ .../cleanup/StartsWithEndsWithTest.java | 105 ++++++++ .../python/format/PythonSpacesTest.java | 204 +++++++++++++++ .../python/tree/AnnotationTest.java | 113 +++++++++ .../python/tree/ArrayAccessTest.java | 33 +++ .../openrewrite/python/tree/AssertTest.java | 40 +++ .../openrewrite/python/tree/AssignTest.java | 80 ++++++ .../openrewrite/python/tree/AwaitTest.java | 36 +++ .../openrewrite/python/tree/BinaryTest.java | 80 ++++++ .../openrewrite/python/tree/BlockTest.java | 233 ++++++++++++++++++ .../openrewrite/python/tree/BreakTest.java | 36 +++ .../python/tree/ClassDeclarationTest.java | 80 ++++++ .../python/tree/CollectionTest.java | 82 ++++++ .../python/tree/ComprehensionTest.java | 67 +++++ .../openrewrite/python/tree/ContinueTest.java | 36 +++ .../org/openrewrite/python/tree/DelTest.java | 40 +++ .../python/tree/DictLiteralTest.java | 36 +++ .../python/tree/FieldAccessTest.java | 37 +++ .../openrewrite/python/tree/ForEachTest.java | 70 ++++++ .../org/openrewrite/python/tree/IfTest.java | 100 ++++++++ .../openrewrite/python/tree/ImportTest.java | 153 ++++++++++++ .../openrewrite/python/tree/LambdaTest.java | 36 +++ .../openrewrite/python/tree/LiteralTest.java | 38 +++ .../python/tree/MethodDeclarationTest.java | 115 +++++++++ .../python/tree/MethodInvocationTest.java | 131 ++++++++++ .../openrewrite/python/tree/NewArrayTest.java | 100 ++++++++ .../python/tree/ParenthesesTest.java | 34 +++ .../python/tree/ParserAssertions.java | 92 +++++++ .../python/tree/ReindentationTest.java | 174 +++++++++++++ .../python/tree/RemotePythonParser.java | 176 +++++++++++++ .../openrewrite/python/tree/ReturnTest.java | 36 +++ .../openrewrite/python/tree/SliceTest.java | 40 +++ .../openrewrite/python/tree/SwitchTest.java | 208 ++++++++++++++++ .../openrewrite/python/tree/TernaryTest.java | 39 +++ .../openrewrite/python/tree/ThrowsTest.java | 64 +++++ .../org/openrewrite/python/tree/TryTest.java | 121 +++++++++ .../python/tree/TypeCommentTest.java | 112 +++++++++ .../openrewrite/python/tree/UnaryTest.java | 33 +++ .../python/tree/VariableScopeTest.java | 65 +++++ .../openrewrite/python/tree/WhileTest.java | 36 +++ .../python/tree/WhitespaceTest.java | 139 +++++++++++ .../org/openrewrite/python/tree/WithTest.java | 51 ++++ .../openrewrite/python/tree/YieldTest.java | 69 ++++++ .../openrewrite/python/tree/package-info.java | 5 + 50 files changed, 3786 insertions(+) create mode 100644 rewrite/rewrite-test/poetry.lock create mode 100644 rewrite/rewrite-test/pyproject.toml create mode 100644 rewrite/rewrite-test/src/rewrite/test/__init__.py create mode 100644 rewrite/rewrite-test/src/rewrite/test/source_specs.py create mode 100644 rewrite/rewrite-test/src/rewrite/test/test.py create mode 100644 rewrite/rewrite-test/tests/java/.editorconfig create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/ChangeMethodNameTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/cleanup/StartsWithEndsWithTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/format/PythonSpacesTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/AnnotationTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ArrayAccessTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/AssertTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/AssignTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/AwaitTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/BinaryTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/BlockTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/BreakTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ClassDeclarationTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/CollectionTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ComprehensionTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ContinueTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/DelTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/DictLiteralTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/FieldAccessTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ForEachTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/IfTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ImportTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/LambdaTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/LiteralTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/MethodDeclarationTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/MethodInvocationTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/NewArrayTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ParenthesesTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ParserAssertions.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ReindentationTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/RemotePythonParser.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ReturnTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/SliceTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/SwitchTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/TernaryTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ThrowsTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/TryTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/TypeCommentTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/UnaryTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/VariableScopeTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/WhileTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/WhitespaceTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/WithTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/YieldTest.java create mode 100644 rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/package-info.java diff --git a/rewrite/rewrite-test/poetry.lock b/rewrite/rewrite-test/poetry.lock new file mode 100644 index 00000000..98c40d11 --- /dev/null +++ b/rewrite/rewrite-test/poetry.lock @@ -0,0 +1,114 @@ +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "exceptiongroup" +version = "1.2.2" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, +] + +[package.extras] +test = ["pytest (>=6)"] + +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + +[[package]] +name = "packaging" +version = "24.1" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, +] + +[[package]] +name = "pluggy" +version = "1.5.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "pytest" +version = "8.3.2" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-8.3.2-py3-none-any.whl", hash = "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5"}, + {file = "pytest-8.3.2.tar.gz", hash = "sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=1.5,<2" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} + +[package.extras] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "rewrite-core" +version = "0.0.0" +description = "Core functionality for the OpenRewrite library" +optional = false +python-versions = "^3.8" +files = [] +develop = true + +[package.source] +type = "directory" +url = "../rewrite-core" + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] + +[metadata] +lock-version = "2.0" +python-versions = "^3.8" +content-hash = "456a37f55f8655cdec858e4e8d20090896a65f7993a5497b47f664e572b94d3f" diff --git a/rewrite/rewrite-test/pyproject.toml b/rewrite/rewrite-test/pyproject.toml new file mode 100644 index 00000000..713d929a --- /dev/null +++ b/rewrite/rewrite-test/pyproject.toml @@ -0,0 +1,20 @@ +[tool.poetry] +name = "rewrite-test" +version = "0.0.0" # This will be replaced by the GitHub Actions workflow +description = "Test functionality for the OpenRewrite library" +authors = ["Moderne Inc. "] +license = "Apache-2.0" +packages = [ + { include = "rewrite/test", from = "src" } +] + +[tool.poetry.dependencies] +python = "^3.8" +rewrite-core = { path = "../rewrite-core", develop = true } + +[tool.poetry.group.dev.dependencies] +pytest = "^8.3.2" + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" \ No newline at end of file diff --git a/rewrite/rewrite-test/src/rewrite/test/__init__.py b/rewrite/rewrite-test/src/rewrite/test/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/rewrite/rewrite-test/src/rewrite/test/source_specs.py b/rewrite/rewrite-test/src/rewrite/test/source_specs.py new file mode 100644 index 00000000..4751d1d2 --- /dev/null +++ b/rewrite/rewrite-test/src/rewrite/test/source_specs.py @@ -0,0 +1,16 @@ +from dataclasses import dataclass +from uuid import UUID + +@dataclass(frozen=True, eq=False) +class SourceSpec: + _id: UUID + + @property + def id(self) -> UUID: + return self._id + + _parser: ParserBuilder + + @property + def parser(self) -> ParserBuilder: + return self._parser \ No newline at end of file diff --git a/rewrite/rewrite-test/src/rewrite/test/test.py b/rewrite/rewrite-test/src/rewrite/test/test.py new file mode 100644 index 00000000..c53b547d --- /dev/null +++ b/rewrite/rewrite-test/src/rewrite/test/test.py @@ -0,0 +1,5 @@ +from abc import ABC + +class RewriteTest(ABC): + def rewrite_run(self): + pass diff --git a/rewrite/rewrite-test/tests/java/.editorconfig b/rewrite/rewrite-test/tests/java/.editorconfig new file mode 100644 index 00000000..a4824935 --- /dev/null +++ b/rewrite/rewrite-test/tests/java/.editorconfig @@ -0,0 +1,5 @@ +root = true + +[*.java] +indent_size = 4 +ij_continuation_indent_size = 2 diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/ChangeMethodNameTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/ChangeMethodNameTest.java new file mode 100644 index 00000000..f48a8086 --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/ChangeMethodNameTest.java @@ -0,0 +1,51 @@ +/* + * Copyright 2023 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python; + +import org.junit.jupiter.api.Test; +import org.openrewrite.DocumentExample; +import org.openrewrite.test.RecipeSpec; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.Assertions.python; + +class ChangeMethodNameTest implements RewriteTest { + + @Override + public void defaults(RecipeSpec spec) { + spec.recipe(new ChangeMethodName("print", "println", true)); + } + + @DocumentExample + @Test + void renameMethod() { + rewriteRun( + python( + """ + class Foo: + def foo() : + print("hello") + """, + """ + class Foo: + def foo() : + println("hello") + """ + ) + ); + } + +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/cleanup/StartsWithEndsWithTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/cleanup/StartsWithEndsWithTest.java new file mode 100644 index 00000000..3615ffa0 --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/cleanup/StartsWithEndsWithTest.java @@ -0,0 +1,105 @@ +/* + * Copyright 2024 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.cleanup; + +import org.junit.jupiter.api.Test; +import org.openrewrite.DocumentExample; +import org.openrewrite.test.RecipeSpec; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.Assertions.python; + +@SuppressWarnings({"PyInterpreter", "PyUnresolvedReferences"}) +class StartsWithEndsWithTest implements RewriteTest { + @Override + public void defaults(RecipeSpec spec) { + spec.recipe(new StartsWithEndsWith()); + } + + @Test + @DocumentExample + void startswithAndEndswith() { + rewriteRun( + python( + """ + a_string = "ababab" + + if a_string.startswith("ab") or a_string.startswith("aba"): + print("Starts with ab") + + if a_string.startswith("ab") or a_string.startswith("aba") or a_string.startswith("abab"): + print("Starts with ab") + + if a_string.endswith("ab") or a_string.endswith("bab"): + print("Ends with ab") + """, + """ + a_string = "ababab" + + if a_string.startswith(("ab", "aba")): + print("Starts with ab") + + if a_string.startswith(("ab", "aba", "abab")): + print("Starts with ab") + + if a_string.endswith(("ab", "bab")): + print("Ends with ab") + """ + ) + ); + } + + @Test + void morePositiveCases() { + rewriteRun( + python( + """ + a_string = "ababab" + + a_string.startswith("ab") or a_string.startswith("aba") or a_string.startswith("abab") or a_string.startswith("ababa") + a_string.startswith("ab") or a_string.startswith(("aba", "abab")) + a_string.startswith(("ab", "aba")) or a_string.startswith(("abab", "ababa")) + """, + """ + a_string = "ababab" + + a_string.startswith(("ab", "aba", "abab", "ababa")) + a_string.startswith(("ab", "aba", "abab")) + a_string.startswith(("ab", "aba", "abab", "ababa")) + """ + ) + ); + } + + @Test + void negativeCases() { + rewriteRun( + python( + """ + a_string = "ababab" + b_string = "babab" + + a_string.startswith("ab") + a_string.startswith(("ab", "aba")) + a_string.startswith("aba") and a_string.startswith("ab") + a_string.startswith("aba") and a_string.startswith("ab") or True + a_string.startswith("aba") or b_string.startswith("ba") + a_string.startswith("aba") or a_string.endswith("bab") + """ + ) + ); + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/format/PythonSpacesTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/format/PythonSpacesTest.java new file mode 100644 index 00000000..06db4090 --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/format/PythonSpacesTest.java @@ -0,0 +1,204 @@ +/* + * Copyright 2023 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.format; + +import org.junit.jupiter.api.Test; +import org.openrewrite.DocumentExample; +import org.openrewrite.test.RecipeSpec; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.Assertions.python; + +class PythonSpacesTest implements RewriteTest { + + @Override + public void defaults(RecipeSpec spec) { + spec.recipe(new PythonSpaces()); + } + + @Test + void emptyParameters() { + rewriteRun( + python( + """ + class Foo: + def foo() : + pass + """ + ) + ); + } + + @Test + void singleParameter() { + rewriteRun( + python( + """ + class Foo: + def foo(a): + pass + """ + ) + ); + } + + @Test + void multipleParameters() { + rewriteRun( + python( + """ + class Foo: + def foo(a, b, c): + pass + """ + ) + ); + } + + @Test + void newLines() { + rewriteRun( + python( + """ + class Foo: + def foo( + a, + b, + c + ): + pass + """ + ) + ); + } + + @DocumentExample + @Test + void formatAfterWithNewLines() { + rewriteRun( + python( + """ + class Foo: + def foo( + a , + b , + c + ): + pass + """, + """ + class Foo: + def foo( + a, + b, + c + ): + pass + """ + ) + ); + } + + @Test + void formatBeforeParameters() { + rewriteRun( + python( + """ + class Foo: + def foo (): + pass + """, + """ + class Foo: + def foo(): + pass + """ + ) + ); + } + + @Test + void formatEmptyParameters() { + rewriteRun( + python( + """ + class Foo: + def foo( ): + pass + """, + """ + class Foo: + def foo(): + pass + """ + ) + ); + } + + @Test + void formatSingleParameter() { + rewriteRun( + python( + """ + class Foo: + def foo( a ): + pass + """, + """ + class Foo: + def foo(a): + pass + """ + ) + ); + } + + @Test + void formatParameterPrefix() { + rewriteRun( + python( + """ + class Foo: + def foo( a,b,c): + pass + """, + """ + class Foo: + def foo(a, b, c): + pass + """ + ) + ); + } + + @Test + void formatParameterSuffix() { + rewriteRun( + python( + """ + class Foo: + def foo(a ,b ,c ): + pass + """, + """ + class Foo: + def foo(a, b, c): + pass + """ + ) + ); + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/AnnotationTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/AnnotationTest.java new file mode 100644 index 00000000..a608c7d1 --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/AnnotationTest.java @@ -0,0 +1,113 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class AnnotationTest implements RewriteTest { + + @Test + void decoratorOnFunction() { + rewriteRun(python( + """ + @dec + def f(): + pass + """ + )); + } + + @Test + void decoratorOnClass() { + rewriteRun(python( + """ + @dec + class C: + pass + """ + )); + } + + @Test + void staticMethodDecoratorOnFunction() { + rewriteRun(python( + """ + class C: + @staticmethod + def f(): + pass + """ + )); + } + + @ParameterizedTest + @ValueSource( + strings = { + "", "()", "( )", + "(42)", "(42 )", "( 42 )", + "(1, 2)", "(1,2)", "(1, 2 )", "( 1, 2 )", "( 1, 2)" + } + ) + void decoratorArguments(String args) { + rewriteRun(python( + """ + @dec%s + def f(): + pass + """.formatted(args) + )); + } + + @ParameterizedTest + @ValueSource( + strings = { + "class C", "def m()" + } + ) + void multipleDecorators(String args) { + rewriteRun(python( + """ + @decA + @decB() + @decC() + %s: + pass + """.formatted(args) + )); + } + + @ParameterizedTest + @ValueSource( + strings = { + "class C", "def m()" + } + ) + void qualifiedDecoratorName(String args) { + rewriteRun(python( + """ + @a.qualified.name + %s: + pass + """.formatted(args) + )); + } + +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ArrayAccessTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ArrayAccessTest.java new file mode 100644 index 00000000..8c945fdd --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ArrayAccessTest.java @@ -0,0 +1,33 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.intellij.lang.annotations.Language; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class ArrayAccessTest implements RewriteTest { + + @ParameterizedTest + //language=py + @ValueSource(strings = {"x[0]", "x [0]", "x[ 0]", "x[0 ]"}) + void arrayAccess(@Language("py") String access) { + rewriteRun(python(access)); + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/AssertTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/AssertTest.java new file mode 100644 index 00000000..6443fb92 --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/AssertTest.java @@ -0,0 +1,40 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.intellij.lang.annotations.Language; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class AssertTest implements RewriteTest { + + @ParameterizedTest + @ValueSource(strings = { + "assert x", + "assert x", + "assert x, y", + "assert x, y", + "assert x , y", + "assert x, y", + }) + void assert_(@Language("py") String arg) { + rewriteRun(python(arg)); + } + +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/AssignTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/AssignTest.java new file mode 100644 index 00000000..5ae7184a --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/AssignTest.java @@ -0,0 +1,80 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class AssignTest implements RewriteTest { + @Test + void assignment() { + rewriteRun( + python( + """ + j = 1 + k = 2 + """ + ) + ); + } + + @ParameterizedTest + @ValueSource(strings = { + "+", + "-", + "*", + "/", + "%", + "&", + "|", + "^", + "<<", + ">>", + "@", + "**", + "//", + }) + void assignmentOp(String op) { + rewriteRun( + python( + """ + a %s= 3 + """.formatted(op) + ) + ); + } + + @ParameterizedTest + @ValueSource(strings = { + "(a:=3)", + "(a :=3)", + "(a:= 3)", + "a[b:=1]", + }) + void assignmentExpression(String expr) { + rewriteRun( + python( + """ + %s + """.formatted(expr) + ) + ); + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/AwaitTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/AwaitTest.java new file mode 100644 index 00000000..c48f4ccd --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/AwaitTest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.intellij.lang.annotations.Language; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class AwaitTest implements RewriteTest { + + @ParameterizedTest + @ValueSource(strings = { + "await x", + "await x" + }) + void await(@Language("py") String arg) { + rewriteRun(python(arg)); + } + +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/BinaryTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/BinaryTest.java new file mode 100644 index 00000000..bd80e658 --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/BinaryTest.java @@ -0,0 +1,80 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.intellij.lang.annotations.Language; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class BinaryTest implements RewriteTest { + + @ParameterizedTest + //language=py + @ValueSource(strings = { + "1+2", + "1+ 2", + "1 +2", + }) + void binaryOperatorSpacing(@Language("py") String expr) { + rewriteRun(python(expr)); + } + + @ParameterizedTest + @ValueSource(strings = {"-", "+", "*", "/", "//", "**", "%", "@"}) + void arithmeticOperator(String op) { + rewriteRun(python("1 %s 2".formatted(op))); + } + + @ParameterizedTest + @ValueSource(strings = {"&", "|", "^", ">>", "<<"}) + void bitwiseOperator(String op) { + rewriteRun(python("1 %s 2".formatted(op))); + } + + @ParameterizedTest + @ValueSource(strings = {"==", "!=", "<", ">", "<=", ">="}) + void comparisonOperator(String op) { + rewriteRun(python("1 %s 2".formatted(op))); + } + + @ParameterizedTest + @ValueSource(strings = {"or", "and", "is", "is not", "in", "not in"}) + void booleanOperator(String op) { + rewriteRun(python("x %s y".formatted(op))); + } + + @ParameterizedTest + @ValueSource(strings = { + "in", " in", "in ", + "not in", " not in", "not in ", + "==", " ==", "== " + }) + void magicMethodOperatorSpacing(String op) { + rewriteRun(python("(x)%s(y)".formatted(op))); + } + + @ParameterizedTest + @ValueSource(strings = { + "not in", "not in", " not in", "not in ", + "is not", "is not", " is not", "is not " + }) + void operatorInternalSpacing(String op) { + rewriteRun(python("(x)%s(y)".formatted(op))); + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/BlockTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/BlockTest.java new file mode 100644 index 00000000..a3af55c2 --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/BlockTest.java @@ -0,0 +1,233 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.intellij.lang.annotations.Language; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class BlockTest implements RewriteTest { + + @Test + void singleStatement() { + rewriteRun(python( + """ + def f(): + pass + """ + )); + } + + @Test + void blockPrefix() { + rewriteRun(python( + """ + def f() : + pass + """ + )); + } + + @Test + void singleStatementWithDocstring() { + rewriteRun(python( + """ + def f(): + \"""a docstring\""" + pass + """ + )); + } + + @Test + void singleStatementWithTrailingComment() { + rewriteRun(python( + """ + def f(): + pass # a comment about the line + """ + )); + } + + @Test + void multiStatementWithBlankLines() { + rewriteRun(python( + """ + def f(): + pass + + pass + + pass + """ + )); + } + + @Test + void multiStatementWithTrailingComments() { + rewriteRun(python( + """ + def f(): + pass # a comment about the line + pass # a comment about the line + pass # a comment about the line + """ + )); + } + + @Test + void multiStatementWithBetweenComments() { + rewriteRun(python( + """ + def f(): + pass + # a comment on its own line + # another comment on its own line + pass + # a comment on its own line + # another comment on its own line + pass + """ + )); + } + + @ParameterizedTest + @ValueSource(strings = {"", "\n", "\n\n", "\n\n\n"}) + void deeplyNested(String eof) { + rewriteRun(python( + """ + def f1(): + def f2(): + pass + + def f3(): + + def f4(): + pass + + pass%s""".formatted(eof) + )); + } + + + @ParameterizedTest + @ValueSource(strings = {"", "\n", "\n\n", "\n\n\n"}) + void lineEndingLocations(String eof) { + rewriteRun( + python( + """ + print(1) # a comment + print(2) + print(3) + + print(4) # a comment + print(5)%s""".formatted(eof) + ) + ); + } + + @ParameterizedTest + @ValueSource(strings = { + "for x in mylist: print(x)", + "def f(x): x = x + 1; return x", + "def f(x): x = x + 1 ; return x", + "def f(x): x = x + 1; return x;", + "def f(x): x = x + 1; return x ;", + }) + void oneLineBlocks(@Language("py") String code) { + rewriteRun( + python(code) + ); + } + + @ParameterizedTest + @ValueSource(strings = { + """ + for x in xs: + pass + """, + """ + for x in xs: + pass + else: + pass + """, + """ + while True: + pass + """, + """ + with stuff() as x: + pass + """, + """ + if True: + pass + """, + """ + if True: + pass + else: + pass + """, + """ + if True: + pass + elif False: + pass + else: + pass + """, + """ + try: + pass + except: + pass + """, + """ + try: + pass + except: + pass + else: + pass + """, + """ + try: + pass + except: + pass + else: + pass + finally: + pass + """, + }) + void nested(String block) { + rewriteRun( + python( + """ + def f(): + %s + """.formatted(block.replace("\n", "\n ")) + ) + ); + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/BreakTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/BreakTest.java new file mode 100644 index 00000000..deb97354 --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/BreakTest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.junit.jupiter.api.Test; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class BreakTest implements RewriteTest { + + @Test + void forLoopBreak() { + rewriteRun( + python( + """ + for x in xs: + break + """ + ) + ); + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ClassDeclarationTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ClassDeclarationTest.java new file mode 100644 index 00000000..ced26564 --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ClassDeclarationTest.java @@ -0,0 +1,80 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; +class ClassDeclarationTest implements RewriteTest { + + @ParameterizedTest + @ValueSource(strings = { + "Foo:", + "Foo :", + "Foo(Bar):", + "Foo (Bar):", + "Foo(Bar) :", + "Foo( Bar):", + "Foo(Bar ):", + "Foo():", + "Foo( ):", + "Foo ():", + "Foo (Bar1, Bar2):", + }) + void classDeclaration(String decl) { + rewriteRun( + python( + """ + class %s + pass + """.formatted(decl) + ) + ); + } + + @Test + void spaceBetweenClasses() { + rewriteRun( + python( + """ + class Foo: + pass + + + class Bar: + pass + """ + ) + ); + } + + @Test + void nestedClasses() { + rewriteRun( + python( + """ + class A: + + class B: + pass + """ + ) + ); + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/CollectionTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/CollectionTest.java new file mode 100644 index 00000000..10edf70b --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/CollectionTest.java @@ -0,0 +1,82 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class CollectionTest implements RewriteTest { + + @Test + void listExpression() { + rewriteRun( + python("xs = [1, 2, 3]") + ); + } + + @Test + void listExpressionEmpty() { + rewriteRun( + python("xs = []") + ); + } + + @Test + void tupleExpression() { + rewriteRun( + python("xs = (1, 2, 3)") + ); + } + + @ParameterizedTest + @ValueSource(strings = { + "()", "( )" + }) + void tupleExpressionEmpty(String arg) { + rewriteRun( + python("xs = %s".formatted(arg)) + ); + } + + @Test + void tupleExpressionSingle() { + // () => tuple + // (1) => int + // (1,) => tuple <-- test this case + // (1, 2) => tuple + rewriteRun( + python("xs = (1,)") + ); + } + + @Test + void dictExpression() { + rewriteRun( + python("xs = {\"foo\": \"bar\", \"foo2\": \"bar2\"}") + ); + } + + @Test + void dictExpressionEmpty() { + rewriteRun( + python("xs = {}") + ); + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ComprehensionTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ComprehensionTest.java new file mode 100644 index 00000000..73c08d55 --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ComprehensionTest.java @@ -0,0 +1,67 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.intellij.lang.annotations.Language; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class ComprehensionTest implements RewriteTest { + + @ParameterizedTest + //language=py + @ValueSource(strings = { + "[x for x in xs if x]", + "[ x for x in xs if x]", + "[x for x in xs if x]", + "[x for x in xs if x]", + "[x for x in xs if x]", + "[x for x in xs if x]", + "[x for x in xs if x]", + "[x for x in xs if x]", + "[x for x in xs if x ]", + }) + void listComprehension(@Language("py") String arg) { + rewriteRun( + python(arg) + ); + } + + @Test + void setComprehension() { + rewriteRun( + python("{x for x in xs if x}") + ); + } + + @Test + void dictComprehension() { + rewriteRun( + python("{x:x for x in xs if x}") + ); + } + + @Test + void generatorComprehension() { + rewriteRun( + python("(x for x in xs if x)") + ); + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ContinueTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ContinueTest.java new file mode 100644 index 00000000..390cfa5f --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ContinueTest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.junit.jupiter.api.Test; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class ContinueTest implements RewriteTest { + + @Test + void forLoopContinue() { + rewriteRun( + python( + """ + for x in xs: + continue + """ + ) + ); + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/DelTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/DelTest.java new file mode 100644 index 00000000..2cbca196 --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/DelTest.java @@ -0,0 +1,40 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.intellij.lang.annotations.Language; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class DelTest implements RewriteTest { + + @ParameterizedTest + @ValueSource(strings = { + "del x", + "del x", + "del x, y", + "del x, y", + "del x , y", + "del x, y", + }) + void del(@Language("py") String arg) { + rewriteRun(python(arg)); + } + +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/DictLiteralTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/DictLiteralTest.java new file mode 100644 index 00000000..014226ba --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/DictLiteralTest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.junit.jupiter.api.Test; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class DictLiteralTest implements RewriteTest { + + @Test + void dictLiteral() { + rewriteRun( + python( + """ + class Test: + d = { 'a': 1, 'b': 2 } + """ + ) + ); + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/FieldAccessTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/FieldAccessTest.java new file mode 100644 index 00000000..aa5ea6ea --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/FieldAccessTest.java @@ -0,0 +1,37 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.intellij.lang.annotations.Language; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class FieldAccessTest implements RewriteTest { + + @ParameterizedTest + //language=py + @ValueSource(strings = { + "a.b", "a. b", "a .b", + "a.b.c", "a. b.c", "a .b.c" + }) + void simpleFieldAccess(@Language("py") String arg) { + rewriteRun(python(arg)); + } + +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ForEachTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ForEachTest.java new file mode 100644 index 00000000..aa9abd5f --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ForEachTest.java @@ -0,0 +1,70 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class ForEachTest implements RewriteTest { + + @Test + void forLoop() { + rewriteRun( + python( + """ + for x in xs: + pass + """ + ) + ); + } + + @ParameterizedTest + @ValueSource(strings = { + "x, y", + "x, (y, z)", + "(x, y)", + "(x, (y, z))" + }) + void forLoopDestructuring(String vars) { + rewriteRun( + python( + """ + for %s in xs: + pass + """.formatted(vars) + ) + ); + } + + @Test + void forLoopWithElse() { + rewriteRun( + python( + """ + for x in xs: + pass + else: + pass + """ + ) + ); + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/IfTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/IfTest.java new file mode 100644 index 00000000..837670a9 --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/IfTest.java @@ -0,0 +1,100 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.junit.jupiter.api.Test; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class IfTest implements RewriteTest { + + @Test + void ifStmt() { + rewriteRun( + python( + """ + if True: + pass + """ + ) + ); + } + + @Test + void ifElseStmt() { + rewriteRun( + python( + """ + if True: + pass + else: + pass + """ + ) + ); + } + + @Test + void ifElifElseStmt() { + rewriteRun( + python( + """ + if True: + pass + elif False: + pass + else: + pass + """ + ) + ); + } + + @Test + void multiElifElseStmt() { + rewriteRun( + python( + """ + if True: + pass + elif False: + pass + elif True: + pass + else: + pass + """ + ) + ); + } + + @Test + void multiElifStmt() { + rewriteRun( + python( + """ + if True: + pass + elif False: + pass + elif True: + pass + """ + ) + ); + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ImportTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ImportTest.java new file mode 100644 index 00000000..a77dfe67 --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ImportTest.java @@ -0,0 +1,153 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.intellij.lang.annotations.Language; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.Issue; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class ImportTest implements RewriteTest { + + @ParameterizedTest + //language=py + @ValueSource(strings = { + "import math", + "import math", + }) + void simpleImport(@Language("py") String arg) { + rewriteRun( + python(arg) + ); + } + + @ParameterizedTest + //language=py + @ValueSource(strings = { + "import math as math2", + "import math as math2", + "import math as math2", + "import math as math2", + }) + void simpleImportAlias(@Language("py") String arg) { + rewriteRun( + python(arg) + ); + } + + + @ParameterizedTest + //language=py + @ValueSource(strings = { + "from . import foo", + "from . import foo", + "from . import foo", + "from . import foo", + "from .mod import foo", + "from .mod import foo", + "from .mod import foo", + "from .mod import foo", + "from ...mod import foo", + "from ....mod import foo", + }) + void localImport(@Language("py") String arg) { + rewriteRun( + python(arg) + ); + } + + @ParameterizedTest + //language=py + @ValueSource(strings = { + "from math import ceil", + "from math import ceil", + "from math import ceil", + "from math import ceil", + }) + void qualifiedImport(@Language("py") String arg) { + rewriteRun( + python(arg) + ); + } + + @ParameterizedTest + //language=py + @ValueSource(strings = { + "from . import foo as foo2", + "from . import foo as foo2", + "from . import foo as foo2", + "from . import foo as foo2", + "from . import foo as foo2", + "from . import foo as foo2", + }) + void localImportAlias(@Language("py") String arg) { + rewriteRun( + python(arg) + ); + } + + @Issue("https://github.com/openrewrite/rewrite-python/issues/35") + @Test + void multipleImports() { + rewriteRun( + python( + """ + import sys + + import math + """) + ); + } + + @Issue("https://github.com/openrewrite/rewrite-python/issues/35") + @Test + void enclosedInParens() { + rewriteRun( + python( + """ + from math import ( + sin, + cos + ) + """) + ); + } + + @SuppressWarnings("TrailingWhitespacesInTextBlock") + @ParameterizedTest + //language=py + @ValueSource(strings = { + "from math import sin, cos # stuff\n\n", + "from math import sin as sin2, cos\n", + "from math import sin as sin2, cos as cos2\n", + """ + from math import ( + sin, + cos + ) + """, + }) + void multipleImport(@Language("py") String arg) { + rewriteRun( + python(arg) + ); + } + +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/LambdaTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/LambdaTest.java new file mode 100644 index 00000000..5ba99fe5 --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/LambdaTest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.junit.jupiter.api.Test; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class LambdaTest implements RewriteTest { + + @Test + void group() { + rewriteRun( + python( + """ + x = lambda a : a + 10 + """ + ) + ); + } + +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/LiteralTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/LiteralTest.java new file mode 100644 index 00000000..b888ba60 --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/LiteralTest.java @@ -0,0 +1,38 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.intellij.lang.annotations.Language; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class LiteralTest implements RewriteTest { + + @ParameterizedTest + //language=py + @ValueSource(strings = { + "None", "True", "False", "42.2", "42", "123456789.123456789E123456789", + "\"hello world\"", + "\"hello \\\"world\\\"\"", "'hello world'", + "'hello \\'world\\''" + }) + void literals(@Language("py") String lit) { + rewriteRun(python(lit)); + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/MethodDeclarationTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/MethodDeclarationTest.java new file mode 100644 index 00000000..0587e597 --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/MethodDeclarationTest.java @@ -0,0 +1,115 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.intellij.lang.annotations.Language; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class MethodDeclarationTest implements RewriteTest { + + @ParameterizedTest + @ValueSource(strings = { + "", + "a", + "a, b", + "a, b, c=1", + "a, b, *args", + "a, b, *args, **kwargs", + "a, b, *args, **kwargs", + "a, b, *, c=1" + }) + void functionDefinition(@Language("py") String args) { + rewriteRun( + python( + """ + def foo(%s): + pass + """.formatted(args) + ) + ); + } + + @Test + void methodDefinition() { + rewriteRun( + python( + """ + class Foo: + def foo(): + pass + """ + ) + ); + } + + @Test + void methodDefinitionWithDocstring() { + rewriteRun( + python( + """ + class Foo: + def foo(): + \"""sa docstring comment\""" + pass + """ + ) + ); + } + + + @Test + void decorator() { + rewriteRun( + python( + """ + @something + def foo(): + pass + """ + ) + ); + } + + @Test + void decoratorWithParams() { + rewriteRun( + python( + """ + @something(1, 2, 3) + def foo(): + pass + """ + ) + ); + } + + @Test + void typedParams() { + rewriteRun( + python( + """ + def foo(a: int = 0, b: str = ''): + pass + """ + ) + ); + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/MethodInvocationTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/MethodInvocationTest.java new file mode 100644 index 00000000..ddaf7978 --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/MethodInvocationTest.java @@ -0,0 +1,131 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.intellij.lang.annotations.Language; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.Issue; +import org.openrewrite.python.PythonParser; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.Assertions.python; + +class MethodInvocationTest implements RewriteTest { + + @ParameterizedTest + @ValueSource(strings = { + "print", "print ", + "print 42", "print 42 ", "print 1, 2, 3, 4", + "print 1, 2, 3, 4 ", "print 1 , 2 , 3 , 4", + "print 1, 2, 3, 4", + """ + for x in range(1,11): + print '{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x) + """, + }) + void python2Print(@Language("py") String print) { + rewriteRun(python(print, PythonParser.LanguageLevel.PYTHON_27)); + } + + @ParameterizedTest + //language=py + @ValueSource(strings = { + "print()", "print( )", + "print(42)", "print( 42 )", "print(1, 2, 3, 4)", + "print( 1, 2, 3, 4 )", "print(1 , 2 , 3 , 4)", + "print(1, 2, 3, 4, sep='+')", + "print(1, 2, a=1, b=2)", "print(1, 2, a =1, b =2)", "print(1, 2, a= 1, b= 2)", + }) + void print(@Language("py") String print) { + rewriteRun(python(print)); + } + + @ParameterizedTest + //language=py + @ValueSource(strings = { + "int.bit_length(42)", + "int .bit_length(42)", + "int. bit_length(42)", + "int.bit_length (42)", + "int.bit_length( 42)", + "int.bit_length(42 )", + }) + void qualifiedTarget(@Language("py") String arg) { + rewriteRun(python(arg)); + } + + @ParameterizedTest + //language=py + @ValueSource(strings = { + "list().copy()", + "list() .copy()", + "list(). copy()", + "list().copy ()", + "list().copy( )", + }) + void methodInvocationOnExpressionTarget(@Language("py") String arg) { + rewriteRun(python(arg)); + } + + @ParameterizedTest + //language=py + @ValueSource(strings = { + "(list().copy)()", + "(list().copy) ()", + "(list().copy)( )", + "(list().count)(1)", + "(list().count) (1)", + "(list().count)( 1)", + "(list().count)(1 )", + "(list().count)(1,2)", + "(list().count) (1,2)", + "(list().count)( 1,2)", + "(list().count)(1 ,2)", + "(list().count)(1, 2)", + "(list().count)(1,2 )", + }) + void methodInvocationOnCallable(@Language("py") String arg) { + rewriteRun(python(arg)); + } + + @ParameterizedTest + //language=py + @ValueSource(strings = { + "print(*x)", + "print(* x)", + "print(**x)", + "print(** x)", + }) + void specialArg(@Language("py") String arg) { + rewriteRun(python(arg)); + } + + @Issue("https://github.com/openrewrite/rewrite-python/issues/39") + @Test + void parameterPadding() { + rewriteRun( + python( + """ + class Foo: + def foo ( ) : + pass + """ + ) + ); + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/NewArrayTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/NewArrayTest.java new file mode 100644 index 00000000..ead926ee --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/NewArrayTest.java @@ -0,0 +1,100 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.junitpioneer.jupiter.ExpectedToFail; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class NewArrayTest implements RewriteTest { + + @ParameterizedTest + @ValueSource(strings = { + "[]", + "[ ]", + "[1,2,3]", + "[1, 2, 3]", + "[ 1, 2, 3 ]", + "[ 1 , 2 , 3 ]", + "[1, *xs]", + "[1, *xs ]", + }) + void list(String arg) { + rewriteRun( + python( + """ + n = %s + """.formatted(arg) + ) + ); + } + + @ParameterizedTest + @ValueSource(strings = { + "{}", + "{ }", + "{1,2,3}", + "{1, 2, 3}", + "{ 1, 2, 3 }", + "{ 1 , 2 , 3 }", + "{1, *xs}", + "{1, * xs}", + "{1, *xs }", + }) + void set(String arg) { + rewriteRun( + python( + """ + n = %s + """.formatted(arg) + ) + ); + } + + @ExpectedToFail("Requires revisions to mapExpressionsAsRightPadded") + @Test + void trailingComma() { + rewriteRun( + python( + """ + value = [ + "v1" , + "v2" , + ] + """ + ) + ); + } + + @ExpectedToFail("Requires revisions to mapExpressionsAsRightPadded") + @Test + void trailingComments() { + rewriteRun( + python( + """ + value = [ + "v1" , # comment 1 + "v2" , # comment 2 + ] + """ + ) + ); + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ParenthesesTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ParenthesesTest.java new file mode 100644 index 00000000..982fff80 --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ParenthesesTest.java @@ -0,0 +1,34 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class ParenthesesTest implements RewriteTest { + + @ParameterizedTest + //language=py + @ValueSource(strings = {"(42)", "( 42 )"}) + void parentheses(String expr) { + rewriteRun( + python("n = %s".formatted(expr)) + ); + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ParserAssertions.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ParserAssertions.java new file mode 100644 index 00000000..8d69e478 --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ParserAssertions.java @@ -0,0 +1,92 @@ +/* + * Copyright 2023 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + + +import org.intellij.lang.annotations.Language; +import org.openrewrite.internal.lang.Nullable; +import org.openrewrite.java.JavaVisitor; +import org.openrewrite.java.tree.Space; +import org.openrewrite.python.PythonParser; +import org.openrewrite.test.SourceSpec; +import org.openrewrite.test.SourceSpecs; + +import java.util.function.Consumer; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.openrewrite.python.PythonParser.LanguageLevel.PYTHON_312; + +public final class ParserAssertions { + private ParserAssertions() { + } + public static SourceSpecs python(@Language("py") @Nullable String before) { + return python(before, s -> { + }, PYTHON_312); + } + + public static SourceSpecs python(@Language("py") @Nullable String before, Consumer> spec) { + return python(before, spec, PYTHON_312); + } + + public static SourceSpecs python(@Language("py") @Nullable String before, @Language("py") String after) { + return python(before, after, s -> { + }, PYTHON_312); + } + + public static SourceSpecs python(@Language("py") @Nullable String before, @Language("py") String after, + Consumer> spec) { + return python(before, after, spec, PYTHON_312); + } + + public static SourceSpecs python(@Language("py") @Nullable String before, PythonParser.LanguageLevel languageLevel) { + return python(before, s -> { + }, languageLevel); + } + + public static SourceSpecs python(@Language("py") @Nullable String before, Consumer> spec, PythonParser.LanguageLevel languageLevel) { + SourceSpec python = new SourceSpec<>(Py.CompilationUnit.class, null, RemotePythonParser.builder().languageLevel(languageLevel), before, null); + acceptSpec(spec, python); + return python; + } + + public static SourceSpecs python(@Language("py") @Nullable String before, @Language("py") String after, PythonParser.LanguageLevel languageLevel) { + return python(before, after, s -> { + }, languageLevel); + } + + public static SourceSpecs python(@Language("py") @Nullable String before, @Language("py") String after, + Consumer> spec, PythonParser.LanguageLevel languageLevel) { + SourceSpec python = new SourceSpec<>(Py.CompilationUnit.class, null, RemotePythonParser.builder().languageLevel(languageLevel), before, s -> after); + acceptSpec(spec, python); + return python; + } + + public static void acceptSpec(Consumer> spec, SourceSpec python) { + Consumer userSuppliedAfterRecipe = python.getAfterRecipe(); + python.afterRecipe(userSuppliedAfterRecipe::accept); + spec.andThen(isFullyParsed()).accept(python); + } + + public static Consumer> isFullyParsed() { + return spec -> spec.afterRecipe(cu -> new JavaVisitor() { + @Override + public Space visitSpace(Space space, Space.Location loc, Integer integer) { + assertThat(space.getWhitespace()).isBlank(); + return super.visitSpace(space, loc, integer); + } + }.visit(cu, 0)); + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ReindentationTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ReindentationTest.java new file mode 100644 index 00000000..88d5da14 --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ReindentationTest.java @@ -0,0 +1,174 @@ +/* + * Copyright 2023 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.junit.jupiter.api.Test; +import org.openrewrite.DocumentExample; +import org.openrewrite.ExecutionContext; +import org.openrewrite.internal.ListUtils; +import org.openrewrite.java.tree.J; +import org.openrewrite.java.tree.Statement; +import org.openrewrite.python.PythonVisitor; +import org.openrewrite.test.RecipeSpec; +import org.openrewrite.test.RewriteTest; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static org.openrewrite.python.Assertions.python; +import static org.openrewrite.test.RewriteTest.toRecipe; + +class ReindentationTest implements RewriteTest { + + @Override + public void defaults(RecipeSpec spec) { + spec.recipe(toRecipe(() -> new PythonVisitor<>() { + @Override + public J visitBlock(J.Block block, ExecutionContext executionContext) { + List copied = new ArrayList<>(); + Set existing = new HashSet<>(); + for (Statement statement : block.getStatements()) { + if (statement instanceof J.MethodDeclaration) { + existing.add(((J.MethodDeclaration) statement).getSimpleName()); + } + } + for (Statement statement : block.getStatements()) { + if (statement instanceof J.ClassDeclaration) { + J.Block body = ((J.ClassDeclaration) statement).getBody(); + for (Statement classStatement : body.getStatements()) { + if (classStatement instanceof J.MethodDeclaration) { + if (existing.add(((J.MethodDeclaration) classStatement).getSimpleName())) { + copied.add(classStatement); + } + } + } + } + } + return block.withStatements(ListUtils.concatAll( + block.getStatements(), + copied + )); + } + })); + } + + @DocumentExample + @Test + void example1() { + rewriteRun(python( + """ + class A: + @decorator + @anotherdec + def f(): + # misaligned comment + # misaligned comment + # a loop + while True: + pass + + def g(): + pass + """, + """ + class A: + @decorator + @anotherdec + def f(): + # misaligned comment + # misaligned comment + # a loop + while True: + pass + + def g(): + pass + + @decorator + @anotherdec + def f(): + # misaligned comment + # misaligned comment + # a loop + while True: + pass + + def g(): + pass + """ + )); + } + + @Test + void example2() { + rewriteRun(python( + """ + class A: + + class B: + @dec + def f(): + pass + + @dec + @anotherdec + def g(): + pass + + @dec # trailing + @anotherdec + def h(): + pass + + @dec # trailing + # multiline + @anotherdec + def i(): + pass + + @dec # trailing + # multiline jagged + @anotherdec + def i(): + pass + + @dec + @anotherdec + # comment between + def k(): + pass + + # comment + def l(): + pass + + # multiline + # comment + def m(): + pass + + # very + # jagged + # comment + def n(): + pass + """ + )); + } + +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/RemotePythonParser.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/RemotePythonParser.java new file mode 100644 index 00000000..2018c33d --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/RemotePythonParser.java @@ -0,0 +1,176 @@ +/* + * Copyright 2023 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import lombok.AccessLevel; +import lombok.RequiredArgsConstructor; +import org.openrewrite.*; +import org.openrewrite.internal.EncodingDetectingInputStream; +import org.openrewrite.internal.lang.Nullable; +import org.openrewrite.java.internal.JavaTypeCache; +import org.openrewrite.python.PythonParser; +import org.openrewrite.remote.ReceiverContext; +import org.openrewrite.remote.java.RemotingClient; +import org.openrewrite.style.NamedStyles; +import org.openrewrite.tree.ParseError; +import org.openrewrite.tree.ParsingEventListener; +import org.openrewrite.tree.ParsingExecutionContextView; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; +import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.stream.Stream; + +@SuppressWarnings("unused") +@RequiredArgsConstructor(access = AccessLevel.PRIVATE) +public class RemotePythonParser implements Parser { + private final PythonParser.LanguageLevel languageLevel; + private final Collection styles; + private final boolean logCompilationWarningsAndErrors; + private final JavaTypeCache typeCache; + private @org.jspecify.annotations.Nullable RemotingClient client; + + @Override + public Stream parse(String... sources) { + List inputs = new ArrayList<>(sources.length); + for (int i = 0; i < sources.length; i++) { + Path path = Paths.get("p" + i + ".py"); + int j = i; + inputs.add(new Input( + path, null, + () -> new ByteArrayInputStream(sources[j].getBytes(StandardCharsets.UTF_8)), + true + )); + } + + return parseInputs( + inputs, + null, + new InMemoryExecutionContext() + ); + } + + @Override + public Stream parseInputs(Iterable inputs, @Nullable Path relativeTo, ExecutionContext ctx) { + ParsingExecutionContextView pctx = ParsingExecutionContextView.view(ctx); + ParsingEventListener parsingListener = pctx.getParsingListener(); + + if (client == null) { + client = RemotingClient.create(ctx, RemotePythonParser.class, () -> { + try { + return new Socket(InetAddress.getLoopbackAddress(), 54321); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + } + + return acceptedInputs(inputs).map(input -> { + Path path = input.getRelativePath(relativeTo); + parsingListener.startedParsing(input); + try (EncodingDetectingInputStream is = input.getSource(ctx)) { + SourceFile parsed = client.runUsingSocket((socket, messenger) -> messenger.sendRequest(generator -> { + generator.writeString("parse-python"); + generator.writeString(is.readFully()); + }, parser -> { + Tree tree = new ReceiverContext(client.getContext().newReceiver(parser), client.getContext()).receiveTree(null); + return (SourceFile) tree; + }, socket)); + + Py.CompilationUnit py = (Py.CompilationUnit) parsed; + parsingListener.parsed(input, py); + return requirePrintEqualsInput(py, input, relativeTo, ctx); + } catch (Throwable t) { + ctx.getOnError().accept(t); + return ParseError.build(this, input, relativeTo, ctx, t); + } + }); + } + + @Override + public boolean accept(Path path) { + return path.toString().endsWith(".py"); + } + + @Override + public RemotePythonParser reset() { + typeCache.clear(); + if (client != null) { + client.getContext().reset(); + } + return this; + } + + @Override + public Path sourcePathFromSourceText(Path prefix, String sourceCode) { + return prefix.resolve("file.py"); + } + + public static Builder builder() { + return new Builder(); + } + + @SuppressWarnings("unused") + public static class Builder extends Parser.Builder { + private PythonParser.LanguageLevel languageLevel = PythonParser.LanguageLevel.PYTHON_312; + private JavaTypeCache typeCache = new JavaTypeCache(); + private boolean logCompilationWarningsAndErrors; + private final Collection styles = new ArrayList<>(); + + public Builder() { + super(Py.CompilationUnit.class); + } + + public Builder logCompilationWarningsAndErrors(boolean logCompilationWarningsAndErrors) { + this.logCompilationWarningsAndErrors = logCompilationWarningsAndErrors; + return this; + } + + public Builder typeCache(JavaTypeCache typeCache) { + this.typeCache = typeCache; + return this; + } + + public Builder styles(Iterable styles) { + for (NamedStyles style : styles) { + this.styles.add(style); + } + return this; + } + + public Builder languageLevel(PythonParser.LanguageLevel languageLevel) { + this.languageLevel = languageLevel; + return this; + } + + @Override + public RemotePythonParser build() { + return new RemotePythonParser(languageLevel, styles, logCompilationWarningsAndErrors, typeCache); + } + + @Override + public String getDslName() { + return "python"; + } + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ReturnTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ReturnTest.java new file mode 100644 index 00000000..3b1b5cf6 --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ReturnTest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.junit.jupiter.api.Test; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class ReturnTest implements RewriteTest { + + @Test + void methodReturn() { + rewriteRun( + python( + """ + def foo(): + return 1 + """ + ) + ); + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/SliceTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/SliceTest.java new file mode 100644 index 00000000..ccdfe8c4 --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/SliceTest.java @@ -0,0 +1,40 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class SliceTest implements RewriteTest { + + @ParameterizedTest + @ValueSource(strings = { + ":", "::", " :", ": ", " : ", + "1:2", "1:2:3", + "1 :2", "1: 2", "1 : 2", + "1:2:3", + "None:None", "None:None:None", + " None : None ", " None : None : None ", + }) + void sliceOperator(String arg) { + rewriteRun( + python("x[%s]".formatted(arg)) + ); + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/SwitchTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/SwitchTest.java new file mode 100644 index 00000000..ffc50111 --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/SwitchTest.java @@ -0,0 +1,208 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class SwitchTest implements RewriteTest { + + @Test + void simple() { + rewriteRun( + python( + """ + match x: + case 1: + pass + case 2: + pass + """ + ) + ); + } + + @Test + void wildcard() { + rewriteRun( + python( + """ + match x: + case 1: + pass + case 2: + pass + case _: + pass + """ + ) + ); + } + + @Test + void sequence() { + rewriteRun( + python( + """ + match x: + case [1, 2]: + pass + """ + ) + ); + } + + @Test + void star() { + rewriteRun( + python( + """ + match x: + case [1, 2, *rest]: + pass + """ + ) + ); + } + + @Test + void guard() { + rewriteRun( + python( + """ + match x: + case [1, 2, *rest] if 42 in rest: + pass + """ + ) + ); + } + + @Test + void or() { + rewriteRun( + python( + """ + match x: + case 2 | 3: + pass + """ + ) + ); + } + + @ParameterizedTest + @ValueSource(strings = { + "", + "a", + "b, c", + "a, b=c", + "a, b=c, d=(e,f)", + }) + void className(String args) { + rewriteRun( + python( + """ + match x: + case ClassName(%s): + pass + """.formatted(args) + ) + ); + } + + @Test + void mapping() { + rewriteRun( + python( + """ + match x: + case {"x": x, "y": y, **z}: + pass + """ + ) + ); + } + + @Test + void value() { + rewriteRun( + python( + """ + match x: + case value.pattern: + pass + """ + ) + ); + } + + @Test + void nested() { + rewriteRun( + python( + """ + match x: + case [int(), str()]: + pass + """ + ) + ); + } + + @Test + void as() { + rewriteRun( + python( + """ + match x: + case [int(), str()] as y: + pass + """ + ) + ); + } + + @Test + void group() { + rewriteRun( + python( + """ + match x: + case (value.pattern): + pass + """ + ) + ); + } + + @Test + void sequenceTarget() { + rewriteRun( + python( + """ + match x, y: + case a, b: + pass + """ + ) + ); + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/TernaryTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/TernaryTest.java new file mode 100644 index 00000000..ba5a9a24 --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/TernaryTest.java @@ -0,0 +1,39 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.intellij.lang.annotations.Language; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class TernaryTest implements RewriteTest { + + @ParameterizedTest + @ValueSource(strings = { + "x = 3 if True else 1", + "x = 3 if True else 1", + "x = 3 if True else 1", + "x = 3 if True else 1", + "x = 3 if True else 1", + }) + void test(@Language("py") String expr) { + rewriteRun(python(expr)); + } + +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ThrowsTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ThrowsTest.java new file mode 100644 index 00000000..b5a8a03b --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/ThrowsTest.java @@ -0,0 +1,64 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; +class ThrowsTest implements RewriteTest { + + @Test + void raise() { + rewriteRun( + python("raise") + ); + } + + @ParameterizedTest + @ValueSource(strings = { + "x", " x" + }) + void raiseError(String expr) { + rewriteRun( + python( + """ + raise %s + """.formatted(expr) + ) + ); + } + + @ParameterizedTest + @ValueSource(strings = { + "x from None", + " x from None", + "x from None", + "x from None", + }) + void raiseErrorFrom(String expr) { + rewriteRun( + python( + """ + raise %s + """.formatted(expr) + ) + ); + } + +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/TryTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/TryTest.java new file mode 100644 index 00000000..47e5f30d --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/TryTest.java @@ -0,0 +1,121 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class TryTest implements RewriteTest { + + @ParameterizedTest + @CsvSource(textBlock = """ + "" , "" + " ", "" + "" , " " + "" , " TypeError" + "" , " TypeError " + "" , " TypeError as e" + "" , " TypeError as e" + "" , " TypeError as e" + "" , " TypeError as e " + "" , "* TypeError" + "" , " * TypeError" + "" , "* TypeError" + "" , "* TypeError as e" + "" , "* TypeError as e" + "" , "*TypeError" + "" , " *TypeError" + """, quoteCharacter = '"') + void tryExcept(String afterTry, String afterExcept) { + rewriteRun(python( + """ + try%s: + pass + except%s: + pass + """.formatted(afterTry, afterExcept) + )); + } + + @ParameterizedTest + @CsvSource(textBlock = """ + " TypeError" , " OSError" + " TypeError " , " OSError" + " TypeError" , " OSError " + """, quoteCharacter = '"') + void tryMultiExcept(String afterFirstExcept, String afterSecondExcept) { + rewriteRun(python( + """ + try: + pass + except%s: + pass + except%s: + pass + """.formatted(afterFirstExcept, afterSecondExcept) + )); + } + + @ParameterizedTest + @ValueSource(strings = {"", " "}) + void tryFinally(String afterFinally) { + rewriteRun(python( + """ + try: + pass + finally%s: + pass + """.formatted(afterFinally) + )); + } + + @ParameterizedTest + @ValueSource(strings = {"", " "}) + void tryExceptFinally(String afterFinally) { + rewriteRun(python( + """ + try: + pass + except: + pass + finally%s: + pass + """.formatted(afterFinally) + )); + } + + @ParameterizedTest + @ValueSource(strings = {"", " "}) + void testElse(String afterElse) { + rewriteRun(python( + """ + try: + pass + except: + pass + else%s: + pass + finally: + pass + """.formatted(afterElse) + )); + } + +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/TypeCommentTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/TypeCommentTest.java new file mode 100644 index 00000000..bdb4796a --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/TypeCommentTest.java @@ -0,0 +1,112 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.intellij.lang.annotations.Language; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class TypeCommentTest implements RewriteTest { + + @ParameterizedTest + @ValueSource(strings = { + "->str", + "-> str", + " -> str", + "-> str", + "-> str ", + }) + void functionReturnType(String type) { + rewriteRun( + python( + """ + def x()%s: + pass + """.formatted(type) + ) + ); + } + + @ParameterizedTest + @ValueSource(strings = { + ":str", + " :str", + ": str", + ":str ", + }) + void functionParamType(String type) { + rewriteRun( + python( + """ + def x(a%s): + pass + """.formatted(type) + ) + ); + } + + @ParameterizedTest + @ValueSource(strings = { + ":str", + " :str", + ": str", + ":str ", + }) + void functionArgsParamType(String type) { + rewriteRun( + python( + """ + def x(*a%s): + pass + """.formatted(type) + ) + ); + } + + @ParameterizedTest + @ValueSource(strings = { + "a: None = None", + "a = None", + "a: str = \"hello\"" + }) + void variables(@Language("py") String stmt) { + rewriteRun( + python(stmt) + ); + } + + @ParameterizedTest + @ValueSource(strings = { + ":str", + " :str", + ": str", + ":str ", + }) + void variablesWithoutAssignment(String type) { + rewriteRun( + python( + """ + x%s + """.formatted(type) + ) + ); + } + + +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/UnaryTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/UnaryTest.java new file mode 100644 index 00000000..77cb1c9e --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/UnaryTest.java @@ -0,0 +1,33 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class UnaryTest implements RewriteTest { + + @ParameterizedTest + @ValueSource(strings = {"not ", "+", "-", "~"}) + void unary(String op) { + rewriteRun( + python("%sy".formatted(op)) + ); + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/VariableScopeTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/VariableScopeTest.java new file mode 100644 index 00000000..b76bf57f --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/VariableScopeTest.java @@ -0,0 +1,65 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.Issue; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class VariableScopeTest implements RewriteTest { + @ParameterizedTest + @ValueSource(strings = {"nonlocal", "global"}) + void singleName(String kind) { + rewriteRun( + python( + """ + def foo(): + %s x + """.formatted(kind) + ) + ); + } + + @ParameterizedTest + @ValueSource(strings = {"nonlocal", "global"}) + void multipleNames(String kind) { + rewriteRun( + python( + """ + def foo(): + %s x, y, z + """.formatted(kind) + ) + ); + } + + @Issue("https://github.com/openrewrite/rewrite-python/issues/36") + @Test + void assignment() { + rewriteRun( + python( + """ + import pygenie + + pygenie.conf.DEFAULT_GENIE_URL = "http://genie:8080" + """) + ); + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/WhileTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/WhileTest.java new file mode 100644 index 00000000..23ec5c8d --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/WhileTest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.junit.jupiter.api.Test; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class WhileTest implements RewriteTest { + + @Test + void whileLoop() { + rewriteRun( + python( + """ + while x: + pass + """ + ) + ); + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/WhitespaceTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/WhitespaceTest.java new file mode 100644 index 00000000..aa75af3a --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/WhitespaceTest.java @@ -0,0 +1,139 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class WhitespaceTest implements RewriteTest { + + @Test + void hashbang() { + rewriteRun(python( + """ + #!/usr/bin/env python3.6 + + print(42) + """ + )); + } + + @ParameterizedTest + @ValueSource(strings = { + "", + " ", + ";", + " ;", + "; ", + "\n", + " \n", + "\n ", + "# comment", + " # comment", + "# comment ", + }) + void singleStatement(String ending) { + rewriteRun(python("print(42)%s".formatted(ending))); + } + + @ParameterizedTest + @ValueSource(strings = { + ";", + " ;", + "; ", + "\n", + " \n", + "# comment\n", + " # comment\n", + "# comment \n", + }) + void multiStatement(String ending) { + rewriteRun(python("print(42)%sprint(2)".formatted(ending))); + } + + @SuppressWarnings("TrailingWhitespacesInTextBlock") + @ParameterizedTest + @ValueSource(strings = { + "", + " ", + ";", + " ;", + "; ", + "\n", + " \n", + "\n ", + "# comment", + " # comment", + "# comment ", + "\n#comment\n", + "\n #comment\n", + }) + void singleLineMultiStatement(String firstLineEnding) { + rewriteRun(python( + """ + print(42); print(43) ;print(44)%s + print(42); print(43) ;print(44) ; + """.formatted(firstLineEnding) + )); + } + + @SuppressWarnings("TrailingWhitespacesInTextBlock") + @ParameterizedTest + @ValueSource(strings = { + "", + " ", + ";", + " ;", + "; ", + "\n", + " \n", + "\n ", + "# comment", + " # comment", + "# comment ", + "\n#comment\n", + "\n #comment\n", + "\n #comment\n", + "\n #comment\n", + "\n #comment\n", + }) + void singleLineMultiStatementInsideBlock(String firstLineEnding) { + rewriteRun(python( + """ + def foo(): + print(42); print(43) ;print(44)%s + print(42); print(43) ;print(44) ; + """.formatted(firstLineEnding) + )); + } + + @ParameterizedTest + @ValueSource(strings = { + "", "\n", "\n\n", "\n\n\n" + }) + void eOF(String eofSpace) { + rewriteRun(python( + """ + print(1) + print(2) + print(3)%s""".formatted(eofSpace) + )); + } +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/WithTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/WithTest.java new file mode 100644 index 00000000..9b95dc44 --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/WithTest.java @@ -0,0 +1,51 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class WithTest implements RewriteTest { + + @ParameterizedTest + @ValueSource(strings = { + "A()", + "A() as a", + "A() as a", + "A() as a", + "A() as a ", + "A() as a, B() as b", + "A() as a, B() as b", + "A() as a, B() as b", + "A() as a , B() as b", + "A() as a, B() as b", + "A() as a, B() as b", + "A() as a, B() as b", + "A() as a, B() as b ", + }) + void simple(String vars) { + rewriteRun(python( + """ + with %s: + pass + """.formatted(vars) + )); + } + +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/YieldTest.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/YieldTest.java new file mode 100644 index 00000000..38184274 --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/YieldTest.java @@ -0,0 +1,69 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.python.tree; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.python.tree.ParserAssertions.python; + +class YieldTest implements RewriteTest { + + @ParameterizedTest + @ValueSource(strings = { + "yield", + "yield x", + "yield x", + "yield x, y", + "yield x, y", + "yield x , y", + "yield x, y", + "yield from x", + "yield from x", + "yield from x", + }) + void yieldStatement(String arg) { + rewriteRun(python( + """ + def foo(): + %s + """.formatted(arg) + )); + } + + @ParameterizedTest + @ValueSource(strings = { + "yield x", + "yield x", + "yield x, y", + "yield x, y", + "yield x , y", + "yield x, y", + "yield from x", + "yield from x", + "yield from x", + }) + void yieldExpression(String arg) { + rewriteRun(python( + """ + def foo(): + it = (%s) + """.formatted(arg) + )); + } + +} diff --git a/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/package-info.java b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/package-info.java new file mode 100644 index 00000000..a2e3377f --- /dev/null +++ b/rewrite/rewrite-test/tests/java/org/openrewrite/python/tree/package-info.java @@ -0,0 +1,5 @@ +@NullMarked +package org.openrewrite.python.tree; + +import org.jspecify.annotations.NullMarked; +