├── .dockerignore
├── .flake8
├── .github
├── dependabot.yml
├── pull_request_template.md
└── workflows
│ ├── build.yml
│ ├── build_base_image.yml
│ ├── build_image.yml
│ ├── publish.yml
│ └── sort_whitespaces.yml
├── .gitignore
├── .intellij_inspector
└── .idea
│ ├── vcs.xml
│ └── workspace.xml
├── .python-version
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE
├── README.md
├── base.Dockerfile
├── hyperstyle
├── __init__.py
└── src
│ ├── __init__.py
│ └── python
│ ├── __init__.py
│ ├── common
│ ├── __init__.py
│ └── tool_arguments.py
│ └── review
│ ├── __init__.py
│ ├── application_config.py
│ ├── common
│ ├── __init__.py
│ ├── file_system.py
│ ├── java_compiler.py
│ ├── language.py
│ ├── language_version.py
│ ├── parallel_runner.py
│ └── subprocess_runner.py
│ ├── inspectors
│ ├── __init__.py
│ ├── checkstyle
│ │ ├── __init__.py
│ │ ├── checkstyle.py
│ │ ├── files
│ │ │ └── config.xml
│ │ ├── issue_configs.py
│ │ └── issue_types.py
│ ├── common
│ │ ├── __init__.py
│ │ ├── inspector
│ │ │ ├── __init__.py
│ │ │ ├── base_inspector.py
│ │ │ ├── ij_client.py
│ │ │ ├── inspector_type.py
│ │ │ └── proto
│ │ │ │ ├── __init__.py
│ │ │ │ └── model.proto
│ │ ├── issue
│ │ │ ├── __init__.py
│ │ │ ├── base_issue_converter.py
│ │ │ ├── issue.py
│ │ │ ├── issue_configs.py
│ │ │ └── tips.py
│ │ ├── utils.py
│ │ └── xml_parser.py
│ ├── detekt
│ │ ├── __init__.py
│ │ ├── detekt.py
│ │ ├── files
│ │ │ └── detekt-config.yml
│ │ ├── issue_configs.py
│ │ └── issue_types.py
│ ├── eslint
│ │ ├── .eslintrc
│ │ ├── __init__.py
│ │ ├── eslint.py
│ │ ├── issue_configs.py
│ │ └── issue_types.py
│ ├── flake8
│ │ ├── .flake8
│ │ ├── __init__.py
│ │ ├── flake8.py
│ │ ├── issue_configs.py
│ │ ├── issue_types.py
│ │ └── whitelist.txt
│ ├── golang_lint
│ │ ├── __init__.py
│ │ ├── config.yml
│ │ ├── golang_lint.py
│ │ ├── issue_configs.py
│ │ └── issue_types.py
│ ├── ij_java
│ │ ├── __init__.py
│ │ ├── ij_java.py
│ │ ├── issue_configs.py
│ │ └── issue_types.py
│ ├── ij_kotlin
│ │ ├── __init__.py
│ │ ├── ij_kotlin.py
│ │ ├── issue_configs.py
│ │ └── issue_types.py
│ ├── ij_python
│ │ ├── __init__.py
│ │ ├── ij_python.py
│ │ ├── issue_configs.py
│ │ └── issue_types.py
│ ├── pmd
│ │ ├── __init__.py
│ │ ├── files
│ │ │ └── config.xml
│ │ ├── issue_configs.py
│ │ ├── issue_types.py
│ │ └── pmd.py
│ ├── pyast
│ │ ├── __init__.py
│ │ └── python_ast.py
│ ├── pylint
│ │ ├── __init__.py
│ │ ├── issue_configs.py
│ │ ├── issue_types.py
│ │ ├── pylint.py
│ │ └── pylintrc
│ └── radon
│ │ ├── __init__.py
│ │ └── radon.py
│ ├── logging_config.py
│ ├── quality
│ ├── __init__.py
│ ├── evaluate_quality.py
│ ├── model.py
│ ├── penalty.py
│ └── rules
│ │ ├── __init__.py
│ │ ├── best_practices_scoring.py
│ │ ├── boolean_length_scoring.py
│ │ ├── class_response_scoring.py
│ │ ├── code_style_scoring.py
│ │ ├── cohesion_scoring.py
│ │ ├── complexity_scoring.py
│ │ ├── coupling_scoring.py
│ │ ├── cyclomatic_complexity_scoring.py
│ │ ├── error_prone_scoring.py
│ │ ├── function_length_scoring.py
│ │ ├── inheritance_depth_scoring.py
│ │ ├── line_len_scoring.py
│ │ ├── maintainability_scoring.py
│ │ ├── method_number_scoring.py
│ │ └── weighted_methods_scoring.py
│ ├── reviewers
│ ├── __init__.py
│ ├── common.py
│ ├── exceptions.py
│ ├── go.py
│ ├── perform_review.py
│ ├── python.py
│ ├── review_result.py
│ └── utils
│ │ ├── __init__.py
│ │ ├── code_statistics.py
│ │ ├── issues_filter.py
│ │ ├── metadata_exploration.py
│ │ └── print_review.py
│ └── run_tool.py
├── package.json
├── poetry.lock
├── pyproject.toml
├── setup_environment.sh
├── test
├── __init__.py
├── python
│ ├── __init__.py
│ ├── functional_tests
│ │ ├── __init__.py
│ │ ├── conftest.py
│ │ ├── test_different_languages.py
│ │ ├── test_difficulty_levels.py
│ │ ├── test_disable.py
│ │ ├── test_duplicates.py
│ │ ├── test_exit_code.py
│ │ ├── test_file_or_project.py
│ │ ├── test_json_format.py
│ │ ├── test_range_of_lines.py
│ │ └── test_verbosity.py
│ ├── inspectors
│ │ ├── __init__.py
│ │ ├── conftest.py
│ │ ├── test_checkstyle_inspector.py
│ │ ├── test_common.py
│ │ ├── test_detekt_inspector.py
│ │ ├── test_eslint_inspector.py
│ │ ├── test_filter_duplicate_issues.py
│ │ ├── test_flake8_inspector.py
│ │ ├── test_golang_lint_inspector.py
│ │ ├── test_issue_configs.py
│ │ ├── test_local_review.py
│ │ ├── test_out_of_range_issues.py
│ │ ├── test_pmd_inspector.py
│ │ ├── test_pylint_inspector.py
│ │ ├── test_python_ast.py
│ │ └── test_radon_inspector.py
│ └── quality
│ │ ├── __init__.py
│ │ └── test_penalty.py
└── resources
│ ├── functional_tests
│ ├── different_languages
│ │ ├── go
│ │ │ ├── a.go
│ │ │ ├── b.go
│ │ │ └── go.mod
│ │ ├── java
│ │ │ └── src
│ │ │ │ ├── First.java
│ │ │ │ └── Second.java
│ │ ├── kotlin
│ │ │ ├── main.kt
│ │ │ └── person.kt
│ │ └── python
│ │ │ ├── a.py
│ │ │ └── b.py
│ ├── difficulty_levels
│ │ ├── file_with_all_difficulty_levels.py
│ │ ├── file_with_only_easy_issues.py
│ │ ├── file_with_only_hard_issues.py
│ │ ├── file_with_only_medium_issues.py
│ │ └── file_without_issues.py
│ ├── disable
│ │ └── contains_flake8_issues.py
│ ├── duplicates
│ │ └── code_with_duplicate_issues.py
│ ├── exit_codes
│ │ ├── no_issues.py
│ │ └── with_issues.py
│ ├── file_or_project
│ │ ├── file.py
│ │ ├── project
│ │ │ ├── __init__.py
│ │ │ ├── one.py
│ │ │ └── other.py
│ │ └── project_with_unknown_extensions
│ │ │ ├── file.abc
│ │ │ ├── file.py
│ │ │ └── file.xyz
│ ├── lines_range
│ │ └── code_with_multiple_issues.py
│ └── verbosity
│ │ └── some_code.py
│ └── inspectors
│ ├── checkstyle
│ ├── empty_file.xml
│ ├── issues
│ │ ├── BooleanExpressionComplexityCheck.java
│ │ ├── CyclomaticComplexityCheck.java
│ │ ├── JavaNCSSCheck.java
│ │ ├── LineLengthCheck.java
│ │ └── MagicNumberCheck.java
│ ├── multi_file_project_with_metric_issues.xml
│ ├── multi_file_project_without_issues.xml
│ ├── multi_file_project_without_metric_issues.xml
│ ├── single_file_project_with_metric_issues.xml
│ ├── single_file_project_without_issues.xml
│ └── single_file_project_without_metric_issues.xml
│ ├── detekt
│ └── issues
│ │ ├── ComplexCondition.kt
│ │ ├── ComplexMethod.kt
│ │ ├── LongMethod.kt
│ │ └── MagicNumber.kt
│ ├── eslint
│ └── issues
│ │ └── complexity.js
│ ├── flake8
│ └── issues
│ │ ├── b007.py
│ │ ├── c901.py
│ │ ├── e501.py
│ │ ├── h601.py
│ │ ├── wps350.py
│ │ └── wps432.py
│ ├── go
│ ├── case0_empty.go
│ ├── case10_gocritic_issues.go
│ ├── case11_gosimple_issues.go
│ ├── case12_stylecheck_issues.go
│ ├── case13_staticcheck_issues.go
│ ├── case14_whitespace.go
│ ├── case15_deadcode.go
│ ├── case16_errcheck.go
│ ├── case17_magic_numbers.go
│ ├── case18_generics.go
│ ├── case1_simple_valid_program.go
│ ├── case2_program_with_syntax_errors.go
│ ├── case3_issues_with_related_information.go
│ ├── case4_cyclomatic_complexity.go
│ ├── case5_function_length.go
│ ├── case6_line_length.go
│ ├── case7_maintainability.go
│ ├── case8_govet_issues.go
│ └── case9_revive_issues.go
│ ├── golang_lint
│ ├── empty_file.json
│ ├── issues
│ │ ├── cyclop.go
│ │ ├── funlen.go
│ │ ├── gomnd.go
│ │ ├── lll.go
│ │ └── maintidx.go
│ ├── multi_file_project_with_issues.json
│ ├── multi_file_project_without_issues.json
│ ├── single_file_project_with_issues.json
│ └── single_file_project_without_issues.json
│ ├── intellij_output
│ └── test.xml
│ ├── java
│ ├── test_algorithm_with_scanner.java
│ ├── test_array_type.java
│ ├── test_blocks.java
│ ├── test_boolean_expr.java
│ ├── test_builder.java
│ ├── test_class_with_booleans.java
│ ├── test_closing_streams.java
│ ├── test_code_with_comments.java
│ ├── test_comparing_strings.java
│ ├── test_constants.java
│ ├── test_covariant_equals.java
│ ├── test_curly_braces.java
│ ├── test_cyclomatic_complexity.java
│ ├── test_cyclomatic_complexity_bad.java
│ ├── test_double_checked_locking.java
│ ├── test_empty_line_separator.java
│ ├── test_empty_lines_btw_members.java
│ ├── test_for_loop.java
│ ├── test_implementation_types.java
│ ├── test_indentation_google_style.java
│ ├── test_indentation_with_spaces.java
│ ├── test_indentation_with_tabs.java
│ ├── test_invalid_naming.java
│ ├── test_long_lines.java
│ ├── test_magic_numbers.java
│ ├── test_manual_array_copy.java
│ ├── test_method_params.java
│ ├── test_missing_default.java
│ ├── test_multi_statements.java
│ ├── test_multiple_literals.java
│ ├── test_nested_blocks.java
│ ├── test_pattern_matching.java
│ ├── test_reassigning_example.java
│ ├── test_records.java
│ ├── test_sealed_classes.java
│ ├── test_simple_valid_program.java
│ ├── test_spaces.java
│ ├── test_suppress_rules.java
│ ├── test_switch_statement.java
│ ├── test_ternary_operator.java
│ ├── test_thread_run.java
│ ├── test_todo.java
│ ├── test_too_long_method.java
│ ├── test_unused_imports.java
│ ├── test_upper_ell.java
│ ├── test_valid_algorithm_1.java
│ ├── test_valid_blocks.java
│ ├── test_valid_curly_braces.java
│ ├── test_valid_default.java
│ ├── test_valid_naming.java
│ ├── test_valid_spaces.java
│ └── test_when_only_equals_overridden.java
│ ├── js
│ ├── case0_no_issues.js
│ ├── case1_with_issues.js
│ └── case2_semi_node_and_unused.js
│ ├── kotlin
│ ├── case0_good_program.kt
│ ├── case10_long_lines.kt
│ ├── case11_bad_ident.kt
│ ├── case12_bad_filename.kt
│ ├── case13_good_filename.kt
│ ├── case14_keyword_spacing.kt
│ ├── case15_empty_class_func.kt
│ ├── case16_redundant_unit.kt
│ ├── case17_modifier_order.kt
│ ├── case18_redundant_braces.kt
│ ├── case19_private_property.kt
│ ├── case1_coffee_machine.kt
│ ├── case20_cyclomatic_complexity.kt
│ ├── case21_cyclomatic_complexity_bad.kt
│ ├── case22_too_many_arguments.kt
│ ├── case23_bad_range_performance.kt
│ ├── case24_duplicate_when_bug.kt
│ ├── case25_unreachable_code.kt
│ ├── case26_var_could_be_val.kt
│ ├── case2_valid_program.kt
│ ├── case3_todo.kt
│ ├── case4_semicolons.kt
│ ├── case5_imports.kt
│ ├── case6_missing_spaces.kt
│ ├── case7_immutability.kt
│ ├── case8_needless_blank_line.kt
│ └── case9_braces.kt
│ ├── pmd
│ ├── empty_file.csv
│ ├── multi_file_project.csv
│ ├── project_without_issues.csv
│ └── single_file_project.csv
│ ├── pylint
│ └── issues
│ │ ├── r1721.py
│ │ └── w1404.py
│ ├── python
│ ├── case0_folder_without_init
│ │ └── hello.py
│ ├── case0_spaces.py
│ ├── case10_unused_variable_in_loop.py
│ ├── case11_redundant_parentheses.py
│ ├── case12_unreachable_code.py
│ ├── case13_complex_logic.py
│ ├── case13_complex_logic_2.py
│ ├── case14_returns_errors.py
│ ├── case15_redefining.py
│ ├── case16_comments.py
│ ├── case17_dangerous_default_value.py
│ ├── case18_comprehensions.py
│ ├── case19_bad_indentation.py
│ ├── case1_simple_valid_program.py
│ ├── case20_imports_order.py
│ ├── case21_imports.py
│ ├── case22_reassigning.py
│ ├── case23_merging_comparisons.py
│ ├── case24_long_function.py
│ ├── case25_django.py
│ ├── case26_from_stepik.py
│ ├── case27_using_requests.py
│ ├── case28_todo_list.py
│ ├── case29_whitespaces.py
│ ├── case2_boolean_expressions.py
│ ├── case30_allow_else_return.py
│ ├── case31_line_break.py
│ ├── case31_spellcheck.py
│ ├── case32_string_format.py
│ ├── case33_commas.py
│ ├── case34_cohesion.py
│ ├── case35_line_break.py
│ ├── case36_unpacking.py
│ ├── case37_wildcard_import.py
│ ├── case38_spellcheck.py
│ ├── case39_no_issues.py
│ ├── case3_redefining_builtin.py
│ ├── case4_naming.py
│ ├── case5_returns.py
│ ├── case6_unused_variables.py
│ ├── case7_empty_lines.py
│ ├── case8_good_class.py
│ └── case_duplicates.py
│ ├── python_ast
│ ├── function.py
│ ├── many_bool_expressions.py
│ └── one_bool_expression.py
│ └── spring
│ ├── case1
│ └── test_promiscuous_controller.java
│ ├── case2
│ └── test_class_with_booleans.java
│ └── springlint-result-example.html
├── tox.ini
└── whitelist.txt
/.dockerignore:
--------------------------------------------------------------------------------
1 | **/*.pyc
2 | **/.pytest_cache/
3 | **/__pycache__/
4 | .git
5 | .github
6 | .idea
7 | node_modules
8 | venv
9 | .venv
10 | build
11 | **/*.egg-info
12 | **/model_pb2*
13 | linters
14 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "github-actions"
4 | directory: "/"
5 | target-branch: main
6 | schedule:
7 | interval: "daily"
8 | time: "00:00"
9 | groups:
10 | all-actions:
11 | patterns: [ "*" ]
12 |
13 | - package-ecosystem: "pip"
14 | directory: "/"
15 | target-branch: main
16 | schedule:
17 | interval: "daily"
18 | time: "00:00"
19 | open-pull-requests-limit: 1
20 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | **Issues**:
2 | [Issue#](https://github.com/hyperskill/hyperstyle/issues/#)
3 |
4 | **Description**:
5 |
6 |
--------------------------------------------------------------------------------
/.github/workflows/build_base_image.yml:
--------------------------------------------------------------------------------
1 | name: Build Base Image
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | image_tag:
7 | type: string
8 | description: 'Image tag'
9 | required: true
10 | default: 'py3.10.14-java11.0.11-node14.17.3-go1.18.5'
11 |
12 | concurrency:
13 | group: ${{ github.workflow }}-${{ github.ref }}
14 | cancel-in-progress: false
15 |
16 | jobs:
17 | build_base_image:
18 | name: Build Base Image
19 | runs-on: [ self-hosted, small ]
20 | steps:
21 | - uses: actions/checkout@v4
22 |
23 | - uses: docker/login-action@v3
24 | with:
25 | registry: hyperskill.azurecr.io
26 | username: ${{ secrets.REGISTRY_USER }}
27 | password: ${{ secrets.REGISTRY_PASSWORD }}
28 |
29 | - uses: docker/setup-buildx-action@v3
30 |
31 | - name: Build and push server image
32 | uses: docker/build-push-action@v6
33 | with:
34 | platforms: linux/amd64
35 | context: .
36 | pull: true
37 | push: true
38 | file: base.Dockerfile
39 | tags: hyperskill.azurecr.io/hyperstyle-base:${{ inputs.image_tag }}
40 | cache-from: |
41 | type=gha
42 | type=gha,scope=main
43 | cache-to: type=gha,mode=max
44 |
--------------------------------------------------------------------------------
/.github/workflows/build_image.yml:
--------------------------------------------------------------------------------
1 | name: Build Image after Release
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | image_tag:
7 | description: 'Image tag'
8 | required: true
9 | default: 'latest'
10 | release:
11 | types:
12 | - released
13 |
14 | concurrency:
15 | group: ${{ github.workflow }}-${{ github.ref }}
16 | cancel-in-progress: false
17 |
18 | jobs:
19 | build_image:
20 | name: Build Image
21 | runs-on: [ self-hosted, small ]
22 | steps:
23 | - uses: actions/checkout@v4
24 |
25 | - uses: docker/login-action@v3
26 | with:
27 | registry: hyperskill.azurecr.io
28 | username: ${{ secrets.REGISTRY_USER }}
29 | password: ${{ secrets.REGISTRY_PASSWORD }}
30 |
31 | - uses: docker/setup-buildx-action@v3
32 |
33 | - name: Build and push server image
34 | uses: docker/build-push-action@v6
35 | with:
36 | context: .
37 | pull: true
38 | push: true
39 | tags: hyperskill.azurecr.io/hyperstyle:${{ inputs.image_tag || github.event.release.tag_name }}
40 | cache-from: |
41 | type=gha
42 | type=gha,scope=main
43 | cache-to: type=gha,mode=max
44 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish to PyPI in case of releasing
2 |
3 | on:
4 | push:
5 |
6 | concurrency:
7 | group: ${{ github.workflow }}-${{ github.ref }}
8 | cancel-in-progress: false
9 |
10 | jobs:
11 | build-n-publish:
12 | name: Build and publish Python 🐍 distributions 📦 to PyPI
13 | runs-on: [ self-hosted, small ]
14 |
15 | steps:
16 | - uses: actions/checkout@v4
17 | - name: Set up Python
18 | uses: actions/setup-python@v5
19 | with:
20 | python-version-file: .python-version
21 | - name: Install pypa/build
22 | run: |
23 | python -m pip install build --user
24 | - name: Build a binary wheel and a source tarball
25 | run: |
26 | python -m build --sdist --wheel --outdir dist/ .
27 | - name: Publish distribution 📦 to PyPI
28 | if: startsWith(github.ref, 'refs/tags')
29 | uses: pypa/gh-action-pypi-publish@master
30 | with:
31 | password: ${{ secrets.SECRETS_TEST_PYPI_API_TOKEN }}
32 |
--------------------------------------------------------------------------------
/.github/workflows/sort_whitespaces.yml:
--------------------------------------------------------------------------------
1 | name: Sort whitespaces
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | - develop
8 | paths:
9 | - 'whitelist.txt'
10 | - 'hyperstyle/src/python/review/inspectors/flake8/whitelist.txt'
11 | pull_request:
12 | paths:
13 | - 'whitelist.txt'
14 | - 'hyperstyle/src/python/review/inspectors/flake8/whitelist.txt'
15 |
16 | concurrency:
17 | group: ${{ github.workflow }}-${{ github.ref }}
18 | cancel-in-progress: true
19 |
20 | jobs:
21 | sort_whitespaces:
22 | name: Sort whitespaces
23 | runs-on: [ self-hosted, small ]
24 | steps:
25 | - name: Checkout
26 | uses: actions/checkout@v4
27 |
28 | - name: Sort whitelists
29 | run: |
30 | for file in "whitelist.txt" "hyperstyle/src/python/review/inspectors/flake8/whitelist.txt"
31 | do
32 | LC_ALL=C sort $file -o $file
33 | done
34 |
35 | - name: Commit sorted whitelists
36 | uses: EndBug/add-and-commit@v9.1.4
37 | with:
38 | add: "['whitelist.txt', 'hyperstyle/src/python/review/inspectors/flake8/whitelist.txt']"
39 | message: 'Sort whitelists (Github Actions)'
40 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 |
3 | # Byte-compiled / optimized / DLL files
4 | __pycache__/
5 | *$py.class
6 |
7 | # C extensions
8 | *.so
9 |
10 | # Distribution / packaging
11 | *.Python
12 | *env/
13 | *build/
14 | *develop-eggs/
15 | *dist/
16 | *downloads/
17 | *eggs/
18 | *.eggs/
19 | *lib64/
20 | *parts/
21 | *sdist/
22 | *var/
23 | *.egg-info/
24 | *.installed.cfg
25 | *.egg
26 |
27 | # PyInstaller
28 | # Usually these files are written by a python script from a template
29 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
30 | *.manifest
31 | *.spec
32 |
33 | # Installer logs
34 | *pip-log.txt
35 | *pip-delete-this-directory.txt
36 |
37 | # Unit test / coverage reports
38 | *htmlcov/
39 | *.tox/
40 | *.coverage
41 | *.coverage.*
42 | *.cache
43 | *nosetests.xml
44 | *coverage.xml
45 | *,cover
46 |
47 | # Translations
48 | *.mo
49 | *.pot
50 |
51 | # Django stuff:
52 | *.log
53 |
54 | # Sphinx documentation
55 | *docs/_build/
56 |
57 | # PyBuilder
58 | *target/
59 |
60 | # Zip files
61 | *.zip
62 |
63 | *.pickle
64 | *.ipynb_checkpoints/
65 |
66 | *.gz
67 |
68 | *.tmp
69 | *.pmd
70 | *.checkstyle
71 | *.intellij_formatter
72 | *.all/
73 |
74 | /.idea/
75 | /.intellij/
76 | /.intellij_inspector/src/*
77 | /.intellij_inspector/out/
78 |
79 | lightweight.Dockerfile
80 | linters
81 |
82 | node_modules
83 | .eslintrc.js
84 | package-lock.json
85 |
86 | hyperstyle/src/python/review/inspectors/common/inspector/proto/model_pb2*
87 | .env
88 |
--------------------------------------------------------------------------------
/.intellij_inspector/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.intellij_inspector/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | 1577277297642
21 |
22 |
23 | 1577277297642
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/.python-version:
--------------------------------------------------------------------------------
1 | 3.10.14
2 |
--------------------------------------------------------------------------------
/hyperstyle/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/hyperstyle/__init__.py
--------------------------------------------------------------------------------
/hyperstyle/src/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/hyperstyle/src/__init__.py
--------------------------------------------------------------------------------
/hyperstyle/src/python/__init__.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from pathlib import Path
4 |
5 | MAIN_FOLDER = Path(__file__)
6 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/common/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/hyperstyle/src/python/common/__init__.py
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/hyperstyle/src/python/review/__init__.py
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/application_config.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from dataclasses import dataclass
4 | from typing import TYPE_CHECKING
5 |
6 | if TYPE_CHECKING:
7 | from hyperstyle.src.python.review.common.language import Language
8 | from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType
9 |
10 |
11 | @dataclass
12 | class ApplicationConfig:
13 | disabled_inspectors: set[InspectorType]
14 | allow_duplicates: bool
15 | n_cpu: int
16 | inspectors_config: dict
17 | with_all_categories: bool
18 | start_line: int = 1
19 | language: Language | None = None
20 | end_line: int | None = None
21 | new_format: bool = False
22 | history: str | None = None
23 | group_by_difficulty: bool = False
24 | ij_config: str | None = None
25 |
26 | @staticmethod
27 | def get_default_config() -> ApplicationConfig:
28 | return ApplicationConfig(
29 | disabled_inspectors=set(),
30 | allow_duplicates=False,
31 | n_cpu=1,
32 | inspectors_config={"n_cpu": 1},
33 | with_all_categories=True,
34 | start_line=1,
35 | language=None,
36 | new_format=False,
37 | group_by_difficulty=False,
38 | )
39 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/common/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/hyperstyle/src/python/review/common/__init__.py
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/common/java_compiler.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | import logging
4 | import subprocess
5 | from typing import TYPE_CHECKING
6 |
7 | from hyperstyle.src.python.review.common.file_system import Encoding, Extension
8 |
9 | if TYPE_CHECKING:
10 | from pathlib import Path
11 |
12 | logger = logging.getLogger(__name__)
13 |
14 |
15 | # TODO: it cannot compile gradle-based projects
16 | def javac_project(dir_path: Path) -> bool:
17 | return javac(f'$(find {dir_path} -name "*{Extension.JAVA.value}")')
18 |
19 |
20 | def javac(javac_args: str | Path) -> bool:
21 | try:
22 | output_bytes: bytes = subprocess.check_output(
23 | f"javac {javac_args}",
24 | shell=True,
25 | stderr=subprocess.STDOUT,
26 | )
27 | output_str = str(output_bytes, Encoding.UTF_ENCODING.value)
28 |
29 | if output_str:
30 | logger.debug(output_str)
31 | except subprocess.CalledProcessError as error:
32 | logger.exception(
33 | f"Failed compile java code with error: " f"{str(error.stdout, Encoding.UTF_ENCODING.value)}"
34 | )
35 | return False
36 | else:
37 | return True
38 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/common/language.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from enum import Enum, unique
4 | from typing import TYPE_CHECKING
5 |
6 | from hyperstyle.src.python.review.common.file_system import Extension
7 | from hyperstyle.src.python.review.common.language_version import LanguageVersion
8 |
9 | if TYPE_CHECKING:
10 | from pathlib import Path
11 |
12 |
13 | @unique
14 | class Language(Enum):
15 | JAVA = "JAVA"
16 | PYTHON = "PYTHON"
17 | KOTLIN = "KOTLIN"
18 | JS = "JAVASCRIPT"
19 | GO = "GO"
20 | UNKNOWN = "UNKNOWN"
21 |
22 | @staticmethod
23 | def from_language_version(language_version: LanguageVersion) -> Language:
24 | version_to_lang = {
25 | LanguageVersion.JAVA_7: Language.JAVA,
26 | LanguageVersion.JAVA_8: Language.JAVA,
27 | LanguageVersion.JAVA_9: Language.JAVA,
28 | LanguageVersion.JAVA_11: Language.JAVA,
29 | LanguageVersion.JAVA_15: Language.JAVA,
30 | LanguageVersion.JAVA_17: Language.JAVA,
31 | LanguageVersion.PYTHON_3: Language.PYTHON,
32 | LanguageVersion.KOTLIN: Language.KOTLIN,
33 | LanguageVersion.JS: Language.JS,
34 | LanguageVersion.GO: Language.GO,
35 | }
36 |
37 | return version_to_lang.get(language_version, Language.UNKNOWN)
38 |
39 | @classmethod
40 | def values(cls) -> list[str]:
41 | return [member.value for member in Language]
42 |
43 | @classmethod
44 | def from_value(cls, value: str, default: Language | None = None) -> Language | None:
45 | try:
46 | return Language(value)
47 | except ValueError:
48 | return default
49 |
50 |
51 | EXTENSION_TO_LANGUAGE = {
52 | Extension.JAVA: Language.JAVA,
53 | Extension.PY: Language.PYTHON,
54 | Extension.KT: Language.KOTLIN,
55 | Extension.KTS: Language.KOTLIN,
56 | Extension.JS: Language.JS,
57 | Extension.GO: Language.GO,
58 | }
59 |
60 |
61 | def guess_file_language(file_path: Path) -> Language:
62 | extension = Extension.from_file(file_path)
63 |
64 | if extension is None:
65 | return Language.UNKNOWN
66 |
67 | return EXTENSION_TO_LANGUAGE.get(extension, Language.UNKNOWN)
68 |
69 |
70 | def filter_paths_by_language(file_paths: list[Path], language: Language) -> list[Path]:
71 | result = []
72 | for path in file_paths:
73 | if guess_file_language(path) == language:
74 | result.append(path)
75 | return result
76 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/common/language_version.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from enum import Enum, unique
4 |
5 | from hyperstyle.src.python.review.common.file_system import Extension
6 |
7 |
8 | @unique
9 | class LanguageVersion(Enum):
10 | JAVA_7 = "java7"
11 | JAVA_8 = "java8"
12 | JAVA_9 = "java9"
13 | JAVA_11 = "java11"
14 | JAVA_15 = "java15"
15 | JAVA_17 = "java17"
16 | PYTHON_3 = "python3"
17 | KOTLIN = "kotlin"
18 | JS = "javascript"
19 | GO = "go"
20 |
21 | @classmethod
22 | def values(cls) -> list[str]:
23 | return [member.value for member in cls.__members__.values()]
24 |
25 | @classmethod
26 | def language_to_extension_dict(cls) -> dict[LanguageVersion, Extension]:
27 | return {
28 | cls.JAVA_7: Extension.JAVA,
29 | cls.JAVA_8: Extension.JAVA,
30 | cls.JAVA_9: Extension.JAVA,
31 | cls.JAVA_11: Extension.JAVA,
32 | cls.JAVA_15: Extension.JAVA,
33 | cls.JAVA_17: Extension.JAVA,
34 | cls.PYTHON_3: Extension.PY,
35 | cls.KOTLIN: Extension.KT,
36 | cls.JS: Extension.JS,
37 | cls.GO: Extension.GO,
38 | }
39 |
40 | def extension_by_language(self) -> Extension:
41 | return self.language_to_extension_dict()[self]
42 |
43 | def is_java(self) -> bool:
44 | return self in {
45 | LanguageVersion.JAVA_7,
46 | LanguageVersion.JAVA_8,
47 | LanguageVersion.JAVA_9,
48 | LanguageVersion.JAVA_11,
49 | LanguageVersion.JAVA_15,
50 | LanguageVersion.JAVA_17,
51 | }
52 |
53 | @classmethod
54 | def from_value(cls, value: str, default: LanguageVersion | None = None) -> LanguageVersion | None:
55 | try:
56 | return LanguageVersion(value)
57 | except ValueError:
58 | return default
59 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/common/parallel_runner.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | import functools
4 | import itertools
5 | import logging
6 | import multiprocessing
7 | from typing import Any, TYPE_CHECKING
8 |
9 | if TYPE_CHECKING:
10 | from collections.abc import Callable
11 | from pathlib import Path
12 |
13 | from hyperstyle.src.python.review.application_config import ApplicationConfig
14 | from hyperstyle.src.python.review.inspectors.common.inspector.base_inspector import BaseInspector
15 | from hyperstyle.src.python.review.inspectors.common.issue.issue import BaseIssue
16 |
17 | logger = logging.getLogger(__name__)
18 |
19 |
20 | def run_inspector(path: Path, config: ApplicationConfig, inspector: BaseInspector) -> list[BaseIssue]:
21 | return _run_inspector(inspector.inspect, path, config, inspector)
22 |
23 |
24 | def run_inspector_in_memory(
25 | code: str, config: ApplicationConfig, inspector: BaseInspector
26 | ) -> list[BaseIssue]:
27 | return _run_inspector(inspector.inspect_in_memory, code, config, inspector)
28 |
29 |
30 | def _run_inspector(
31 | inspect_function: Callable[[Any, dict[str, Any]], list[BaseIssue]],
32 | data: Any,
33 | config: ApplicationConfig,
34 | inspector: BaseInspector,
35 | ) -> list[BaseIssue]:
36 | try:
37 | return inspect_function(data, config.inspectors_config)
38 | except Exception:
39 | logger.exception(f"Inspector {inspector.inspector_type} failed.")
40 | raise
41 |
42 |
43 | def inspect_in_parallel(
44 | inspector_runner: Callable[[Any, ApplicationConfig, BaseInspector], list[BaseIssue]],
45 | data: Any,
46 | config: ApplicationConfig,
47 | inspectors: list[BaseInspector],
48 | ) -> list[BaseIssue]:
49 | inspectors_to_run = filter(lambda i: i.inspector_type not in config.disabled_inspectors, inspectors)
50 |
51 | if config.n_cpu == 1:
52 | issues = []
53 | for inspector in inspectors_to_run:
54 | inspector_issues = inspector_runner(data, config, inspector)
55 | issues.extend(inspector_issues)
56 | return issues
57 |
58 | with multiprocessing.Pool(config.n_cpu) as pool:
59 | issues = pool.map(
60 | functools.partial(inspector_runner, data, config),
61 | inspectors_to_run,
62 | )
63 |
64 | return list(itertools.chain(*issues))
65 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/common/subprocess_runner.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | import logging
4 | import subprocess
5 | from typing import TYPE_CHECKING
6 |
7 | if TYPE_CHECKING:
8 | from pathlib import Path
9 |
10 | logger = logging.getLogger(__name__)
11 |
12 |
13 | def run_in_subprocess(
14 | command: list[str],
15 | working_directory: str | Path | None = None,
16 | encoding: str = "utf-8",
17 | subprocess_input: str | None = None,
18 | ) -> str:
19 | process = subprocess.run(
20 | command,
21 | capture_output=True,
22 | cwd=working_directory,
23 | encoding=encoding,
24 | input=subprocess_input,
25 | check=False,
26 | )
27 |
28 | stdout = process.stdout
29 | stderr = process.stderr
30 |
31 | if stdout:
32 | logger.debug(f"{command[0]}'s stdout:\n{stdout}")
33 | if stderr:
34 | logger.debug(f"{command[0]}'s stderr:\n{stderr}")
35 |
36 | return stdout
37 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/hyperstyle/src/python/review/inspectors/__init__.py
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/checkstyle/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/hyperstyle/src/python/review/inspectors/checkstyle/__init__.py
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/checkstyle/issue_configs.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | import re
4 |
5 | from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import (
6 | IssueConfig,
7 | IssueDescriptionParser,
8 | MeasurableIssueConfig,
9 | )
10 | from hyperstyle.src.python.review.inspectors.common.issue.tips import (
11 | get_bool_expr_len_tip,
12 | get_cyclomatic_complexity_tip,
13 | get_func_len_tip,
14 | get_line_len_tip,
15 | get_magic_number_tip,
16 | )
17 |
18 | ISSUE_CONFIGS: list[IssueConfig] = [
19 | IssueConfig(
20 | origin_class="MagicNumberCheck",
21 | new_description=get_magic_number_tip(),
22 | parser=IssueDescriptionParser(re.compile(r"'(.+)' is a magic number")),
23 | ),
24 | # Cyclomatic complexity
25 | MeasurableIssueConfig(
26 | origin_class="CyclomaticComplexityCheck",
27 | new_description=get_cyclomatic_complexity_tip(),
28 | parser=IssueDescriptionParser(
29 | regexp=re.compile(r"Cyclomatic Complexity is (\d+)"),
30 | converter={0: int},
31 | ),
32 | ),
33 | # Function length
34 | MeasurableIssueConfig(
35 | origin_class="JavaNCSSCheck",
36 | new_description=get_func_len_tip(),
37 | parser=IssueDescriptionParser(
38 | regexp=re.compile(r"NCSS for this method is (\d+)"),
39 | converter={0: int},
40 | ),
41 | ),
42 | # Bool expression length
43 | MeasurableIssueConfig(
44 | origin_class="BooleanExpressionComplexityCheck",
45 | new_description=get_bool_expr_len_tip(),
46 | parser=IssueDescriptionParser(
47 | regexp=re.compile(r"Boolean expression complexity is (\d+)"),
48 | converter={0: int},
49 | ),
50 | ),
51 | # Line length
52 | MeasurableIssueConfig(
53 | origin_class="LineLengthCheck",
54 | new_description=get_line_len_tip(),
55 | parser=IssueDescriptionParser(
56 | regexp=re.compile(r"Line is longer than \d+ characters \(found (\d+)\)"),
57 | converter={0: int},
58 | ),
59 | ),
60 | ]
61 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/common/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/hyperstyle/src/python/review/inspectors/common/__init__.py
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/common/inspector/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/hyperstyle/src/python/review/inspectors/common/inspector/__init__.py
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/common/inspector/ij_client.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | import grpc
4 |
5 | from hyperstyle.src.python.review.inspectors.common.inspector.proto import model_pb2, model_pb2_grpc
6 |
7 | TIMEOUT = 3
8 |
9 |
10 | class IJClient:
11 | def __init__(self, host: str = "localhost", port: int = 8080) -> None:
12 | self.host = host
13 | self.port = port
14 |
15 | # instantiate a channel
16 | self.channel = grpc.insecure_channel(f"{self.host}:{self.port}")
17 |
18 | # bind the client and the server
19 | try:
20 | grpc.channel_ready_future(self.channel).result(timeout=TIMEOUT)
21 | except grpc.FutureTimeoutError as e:
22 | msg = "Failed to connect to ij code server"
23 | raise Exception(msg) from e
24 | else:
25 | self.stub = model_pb2_grpc.CodeInspectionServiceStub(self.channel)
26 |
27 | def inspect(self, code: model_pb2.Code) -> model_pb2.InspectionResult:
28 | return self.stub.inspect(code, timeout=TIMEOUT)
29 |
30 | def init(self, service: model_pb2.Service) -> model_pb2.InitResult:
31 | return self.stub.init(service, timeout=TIMEOUT)
32 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/common/inspector/inspector_type.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from enum import Enum, unique
4 |
5 |
6 | @unique
7 | class InspectorType(Enum):
8 | # Python language
9 | PYLINT = "PYLINT"
10 | PYTHON_AST = "PYTHON_AST"
11 | FLAKE8 = "FLAKE8"
12 | RADON = "RADON"
13 | IJ_PYTHON = "IJ_PYTHON"
14 |
15 | # Java language
16 | PMD = "PMD"
17 | CHECKSTYLE = "CHECKSTYLE"
18 | IJ_JAVA = "IJ_JAVA"
19 |
20 | # Kotlin language
21 | DETEKT = "DETEKT"
22 | IJ_KOTLIN = "IJ_KOTLIN"
23 |
24 | # JavaScript language
25 | ESLINT = "ESLINT"
26 |
27 | # Go language
28 | GOLANG_LINT = "GOLANG_LINT"
29 |
30 | UNDEFINED = "UNDEFINED"
31 | QODANA = "QODANA"
32 | # TODO: it is used on production for java inspections, remove in the future releases
33 | IJ_OLD = "INTELLIJ"
34 |
35 | @classmethod
36 | def available_values(cls) -> list[str]:
37 | return [
38 | # Python language
39 | cls.PYLINT.value,
40 | cls.FLAKE8.value,
41 | cls.PYTHON_AST.value,
42 | cls.RADON.value,
43 | cls.IJ_PYTHON.value,
44 | # Java language
45 | cls.PMD.value,
46 | cls.CHECKSTYLE.value,
47 | cls.IJ_JAVA.value,
48 | # Kotlin language
49 | cls.DETEKT.value,
50 | cls.IJ_KOTLIN.value,
51 | # JavaScript language
52 | cls.ESLINT.value,
53 | # Go language
54 | cls.GOLANG_LINT.value,
55 | cls.IJ_OLD.value,
56 | ]
57 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/common/inspector/proto/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/hyperstyle/src/python/review/inspectors/common/inspector/proto/__init__.py
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/common/inspector/proto/model.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | option java_multiple_files = true;
4 | option java_package = "org.jetbrains.research.ij.headless.server";
5 | option java_outer_classname = "CodeServerProto";
6 |
7 | service CodeInspectionService {
8 | rpc inspect (Code) returns (InspectionResult) {};
9 | }
10 |
11 | enum LanguageId {
12 | python = 0;
13 | kotlin = 1;
14 | java = 2;
15 | }
16 |
17 | message Code {
18 | string text = 1;
19 | LanguageId languageId = 2;
20 | }
21 |
22 | message Problem {
23 | string name = 1;
24 | string inspector = 2;
25 | uint64 lineNumber = 3;
26 | uint64 offset = 4;
27 | uint64 length = 5;
28 | }
29 |
30 | message InspectionResult {
31 | repeated Problem problems = 1;
32 | }
33 |
34 | message Service {
35 | string name = 1;
36 | LanguageId languageId = 2;
37 | }
38 |
39 | message InitResult {
40 | uint64 status = 1;
41 | }
42 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/common/issue/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/hyperstyle/src/python/review/inspectors/common/issue/__init__.py
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/common/issue/base_issue_converter.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | import logging
4 | from typing import TYPE_CHECKING
5 |
6 | from hyperstyle.src.python.review.inspectors.common.issue.issue import (
7 | BaseIssue,
8 | get_issue_class_by_issue_type,
9 | get_measure_name_by_measurable_issue_type,
10 | IssueData,
11 | Measurable,
12 | )
13 |
14 | if TYPE_CHECKING:
15 | from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import IssueConfigsHandler
16 |
17 | logger = logging.getLogger(__name__)
18 |
19 |
20 | def convert_base_issue(base_issue: BaseIssue, issue_configs_handler: IssueConfigsHandler) -> BaseIssue | None:
21 | """Convert the ``base_issue`` to a code issue or measurable one.
22 |
23 | If necessary, the old description is replaced by the new one and the measure is parsed using the
24 | ``issue_configs_handler``.
25 |
26 | :param base_issue: A base issue to be converted.
27 | :param issue_configs_handler: A handler of issue configurations.
28 | :return:
29 | """
30 | origin_class = base_issue.origin_class
31 | issue_type = base_issue.type
32 | description = base_issue.description
33 | inspector_type = base_issue.inspector_type
34 |
35 | issue_data = vars(base_issue) # Get all the fields from BaseIssue, so we can change them
36 | issue_data[IssueData.DESCRIPTION.value] = issue_configs_handler.get_description(origin_class, description)
37 |
38 | issue_class = get_issue_class_by_issue_type(issue_type)
39 | if issubclass(issue_class, Measurable):
40 | measure = issue_configs_handler.parse_measure(origin_class, description)
41 | if measure is None:
42 | logger.error(f"{inspector_type.value}: Unable to parse measure.")
43 | return None
44 |
45 | issue_data[get_measure_name_by_measurable_issue_type(issue_type)] = measure
46 |
47 | try:
48 | return issue_class(**issue_data)
49 | except Exception:
50 | logger.exception(f"{inspector_type.value}: Unable to create a new issue.")
51 | return None
52 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/common/utils.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | import logging
4 | from math import floor
5 | from string import Formatter
6 | from typing import TYPE_CHECKING
7 |
8 | from hyperstyle.src.python.review.common.file_system import get_content_from_file
9 |
10 | if TYPE_CHECKING:
11 | from pathlib import Path
12 |
13 | from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType
14 |
15 | logger = logging.getLogger(__name__)
16 |
17 |
18 | def is_result_file_correct(file_path: Path, inspector_type: InspectorType) -> bool:
19 | """Check if the result of the inspectors is correct: it exists and it is not empty."""
20 | if not file_path.is_file():
21 | logger.error(f"{inspector_type.value}: error - no output file")
22 | return False
23 |
24 | file_content = get_content_from_file(file_path)
25 | if not file_content:
26 | logger.error(f"{inspector_type.value}: error - empty file")
27 | return False
28 |
29 | return True
30 |
31 |
32 | def convert_percentage_of_value_to_lack_of_value(percentage_of_value: float) -> int:
33 | """Converts percentage of value to lack of value.
34 | Calculated by the formula: floor(100 - percentage_of_value).
35 |
36 | :param percentage_of_value: value in the range from 0 to 100.
37 | :return: lack of value.
38 | """
39 | return floor(100 - percentage_of_value)
40 |
41 |
42 | def _get_format_fields(input_string: str) -> list[str]:
43 | """Get all format fields from the input string.
44 |
45 | :param input_string: A string from which all format fields need to be extracted.
46 | :return: A list of format fields.
47 | """
48 | return [elem[1] for elem in Formatter().parse(input_string) if elem[1] is not None]
49 |
50 |
51 | def contains_format_fields(input_string: str) -> bool:
52 | """Check that the input string contains format fields.
53 |
54 | :param input_string: A string for which you want to check whether it contains format fields or not.
55 | :return: Whether the input string contains format fields or not.
56 | """
57 | return len(_get_format_fields(input_string)) > 0
58 |
59 |
60 | def contains_named_format_fields(input_string: str) -> bool:
61 | """Check that the input string contains named format fields.
62 |
63 | :param input_string: A string for which you want to check whether it contains named format fields or not.
64 | :return: Whether the input string contains named format fields or not.
65 | """
66 | return any(field and not field.isdigit() for field in _get_format_fields(input_string))
67 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/detekt/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/hyperstyle/src/python/review/inspectors/detekt/__init__.py
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/detekt/issue_configs.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | import re
4 |
5 | from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import (
6 | IssueConfig,
7 | IssueDescriptionParser,
8 | MeasurableIssueConfig,
9 | )
10 | from hyperstyle.src.python.review.inspectors.common.issue.tips import (
11 | get_bool_expr_len_tip,
12 | get_cyclomatic_complexity_tip,
13 | get_func_len_tip,
14 | get_magic_number_tip,
15 | )
16 |
17 | ISSUE_CONFIGS: list[IssueConfig] = [
18 | IssueConfig(
19 | origin_class="MagicNumber",
20 | new_description=get_magic_number_tip(with_number_field=False),
21 | ),
22 | # Function length
23 | MeasurableIssueConfig(
24 | origin_class="LongMethod",
25 | new_description=get_func_len_tip(),
26 | parser=IssueDescriptionParser(
27 | regexp=re.compile(r"The function .* is too long \((\d+)\)"),
28 | converter={0: int},
29 | ),
30 | ),
31 | # Bool expression length
32 | MeasurableIssueConfig(
33 | origin_class="ComplexCondition",
34 | new_description=get_bool_expr_len_tip(unit_name="operands"),
35 | parser=IssueDescriptionParser(
36 | regexp=re.compile(r"This condition is too complex \((\d+)\)"),
37 | converter={0: int},
38 | ),
39 | ),
40 | # Cyclomatic complexity
41 | MeasurableIssueConfig(
42 | origin_class="ComplexMethod",
43 | new_description=get_cyclomatic_complexity_tip(),
44 | parser=IssueDescriptionParser(
45 | regexp=re.compile(r"The function .* appears to be too complex \((\d+)\)"),
46 | converter={0: int},
47 | ),
48 | ),
49 | ]
50 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/eslint/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parserOptions": {
3 | "ecmaVersion": 2020,
4 | "sourceType": "script",
5 | "ecmaFeatures": {}
6 | },
7 | "extends": "eslint:recommended",
8 | "rules": {
9 | "no-misleading-character-class": "off",
10 | "no-setter-return": "off",
11 | "no-unsafe-negation": "off",
12 | "no-unsafe-finally": "off",
13 | "no-undef": "off",
14 | "no-console": "off",
15 |
16 | "complexity": ["error", 5],
17 | "curly": "error",
18 | "consistent-return": "error",
19 | "default-case": "error",
20 | "eqeqeq": "error",
21 | "no-empty-function": "error",
22 | "no-fallthrough": "error",
23 | "no-multi-spaces": "error",
24 | "yoda": "error",
25 |
26 | "brace-style": "error",
27 | "camelcase": "error",
28 | "comma-style": "error",
29 | "comma-spacing": "error",
30 | "semi": "error",
31 | "no-multiple-empty-lines": "error",
32 | "no-var": "error",
33 | "space-infix-ops": "error",
34 | "object-curly-newline" : "error",
35 | "no-trailing-spaces": "error",
36 | "no-whitespace-before-property": "error",
37 | "max-len": ["error", { "code": 80 }],
38 | "constructor-super": "error"
39 | },
40 | "env": {}
41 | }
42 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/eslint/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/hyperstyle/src/python/review/inspectors/eslint/__init__.py
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/eslint/issue_configs.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | import re
4 |
5 | from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import (
6 | IssueConfig,
7 | IssueDescriptionParser,
8 | MeasurableIssueConfig,
9 | )
10 | from hyperstyle.src.python.review.inspectors.common.issue.tips import get_cyclomatic_complexity_tip
11 |
12 | ISSUE_CONFIGS: list[IssueConfig] = [
13 | MeasurableIssueConfig(
14 | origin_class="complexity",
15 | new_description=get_cyclomatic_complexity_tip(),
16 | parser=IssueDescriptionParser(
17 | regexp=re.compile(r"complexity of (\d+)"),
18 | converter={0: int},
19 | ),
20 | ),
21 | ]
22 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/flake8/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/hyperstyle/src/python/review/inspectors/flake8/__init__.py
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/flake8/issue_configs.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | import re
4 |
5 | from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import (
6 | IssueConfig,
7 | IssueDescriptionParser,
8 | MeasurableIssueConfig,
9 | )
10 | from hyperstyle.src.python.review.inspectors.common.issue.tips import (
11 | get_augmented_assign_pattern_tip,
12 | get_cohesion_tip,
13 | get_cyclomatic_complexity_tip,
14 | get_line_len_tip,
15 | get_magic_number_tip,
16 | )
17 | from hyperstyle.src.python.review.inspectors.common.utils import convert_percentage_of_value_to_lack_of_value
18 |
19 | ISSUE_CONFIGS: list[IssueConfig] = [
20 | IssueConfig(
21 | origin_class="WPS432",
22 | new_description=get_magic_number_tip(),
23 | parser=IssueDescriptionParser(re.compile(r"^Found magic number: (.+)$")),
24 | ),
25 | IssueConfig(
26 | origin_class="WPS350",
27 | new_description=get_augmented_assign_pattern_tip(),
28 | ),
29 | IssueConfig(
30 | origin_class="B007",
31 | new_description=(
32 | "Loop control variable '{0}' not used within the loop body. "
33 | "If this is intended, replace it with an underscore."
34 | ),
35 | parser=IssueDescriptionParser(
36 | re.compile(r"Loop control variable '(.+)' not used within the loop body")
37 | ),
38 | ),
39 | # Cyclomatic Complexity
40 | MeasurableIssueConfig(
41 | origin_class="C901",
42 | new_description=get_cyclomatic_complexity_tip(),
43 | parser=IssueDescriptionParser(
44 | regexp=re.compile(r"'.+' is too complex \((\d+)\)"),
45 | converter={0: int},
46 | ),
47 | ),
48 | # Cohesion
49 | MeasurableIssueConfig(
50 | origin_class="H601",
51 | new_description=get_cohesion_tip(),
52 | parser=IssueDescriptionParser(
53 | regexp=re.compile(r"class has low \((\d*\.?\d*)%\) cohesion"),
54 | converter={0: lambda match: convert_percentage_of_value_to_lack_of_value(float(match))},
55 | ),
56 | ),
57 | # Line len
58 | MeasurableIssueConfig(
59 | origin_class="E501",
60 | new_description=get_line_len_tip(),
61 | parser=IssueDescriptionParser(
62 | regexp=re.compile(r"line too long \((\d+) > \d+ characters\)"),
63 | converter={0: int},
64 | ),
65 | ),
66 | ]
67 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/flake8/whitelist.txt:
--------------------------------------------------------------------------------
1 | acc
2 | aggfunc
3 | appendleft
4 | arange
5 | argmax
6 | asctime
7 | astype
8 | barmode
9 | betavariate
10 | bgcolor
11 | birthdate
12 | blackbox
13 | bs4
14 | byteorder
15 | calc
16 | capwords
17 | casefold
18 | caseless
19 | chappie
20 | concat
21 | config
22 | configs
23 | consts
24 | coord
25 | copysign
26 | coroutine
27 | csgraph
28 | ctime
29 | dataframe
30 | dataframes
31 | dataset
32 | datasets
33 | decrypted
34 | dedent
35 | deque
36 | desc
37 | destructuring
38 | devs
39 | df
40 | dicts
41 | dirs
42 | divmod
43 | dtype
44 | edu
45 | eig
46 | elems
47 | etree
48 | expm1
49 | falsy
50 | fillna
51 | floordiv
52 | fromkeys
53 | fromstring
54 | fullmatch
55 | gensim
56 | getchildren
57 | gmtime
58 | groupby
59 | gryffindor
60 | halfs
61 | hashable
62 | hline
63 | href
64 | hufflepuff
65 | hyp
66 | hyperskill
67 | iadd
68 | iloc
69 | inp
70 | inplace
71 | ints
72 | isalnum
73 | isalpha
74 | isin
75 | islice
76 | islower
77 | isnumeric
78 | isprintable
79 | istitle
80 | isub
81 | iterrows
82 | kcal
83 | kcals
84 | lastname
85 | lateinit
86 | lemmatize
87 | lemmatizer
88 | lifes
89 | lightbulb
90 | lim
91 | linalg
92 | linecolor
93 | linewidth
94 | linspace
95 | lowercased
96 | lvl
97 | lxml
98 | matmul
99 | metaclass
100 | minsize
101 | multiline
102 | nbins
103 | ndarray
104 | ndigits
105 | ndim
106 | nltk
107 | nrows
108 | nullable
109 | numpy
110 | nums
111 | ost
112 | param
113 | params
114 | parsers
115 | pathlib
116 | popleft
117 | pos
118 | punct
119 | ravenclaw
120 | readline
121 | rfind
122 | rindex
123 | rmdir
124 | schur
125 | scipy
126 | showline
127 | sigmoid
128 | slytherin
129 | sqrt
130 | src
131 | stdlib
132 | stemmer
133 | stepik
134 | subdicts
135 | subdir
136 | subdirs
137 | substr
138 | substring
139 | svd
140 | textposition
141 | textwrap
142 | throwable
143 | todos
144 | tokenize
145 | tokenized
146 | tokenizer
147 | tolist
148 | toplevel
149 | tracklist
150 | treebank
151 | truediv
152 | truthy
153 | unary
154 | uniformtext
155 | unpickled
156 | upd
157 | util
158 | utils
159 | vline
160 | webpage
161 | whitespaces
162 | word2vec
163 | writeback
164 | xanchor
165 | xaxes
166 | yanchor
167 | yaxis
168 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/golang_lint/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/hyperstyle/src/python/review/inspectors/golang_lint/__init__.py
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/golang_lint/issue_configs.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | import re
4 |
5 | from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import (
6 | IssueConfig,
7 | IssueDescriptionParser,
8 | MeasurableIssueConfig,
9 | )
10 | from hyperstyle.src.python.review.inspectors.common.issue.tips import (
11 | get_cyclomatic_complexity_tip,
12 | get_func_len_tip,
13 | get_line_len_tip,
14 | get_magic_number_tip,
15 | get_maintainability_index_tip,
16 | )
17 | from hyperstyle.src.python.review.inspectors.common.utils import convert_percentage_of_value_to_lack_of_value
18 |
19 | ISSUE_CONFIGS: list[IssueConfig] = [
20 | IssueConfig(
21 | origin_class="gomnd",
22 | new_description=get_magic_number_tip(),
23 | parser=IssueDescriptionParser(re.compile("^mnd: Magic number: (.*), in .* detected$")),
24 | ),
25 | MeasurableIssueConfig(
26 | origin_class="cyclop",
27 | new_description=get_cyclomatic_complexity_tip(),
28 | parser=IssueDescriptionParser(
29 | regexp=re.compile(r"^calculated cyclomatic complexity for function .* is (\d+), max is -1$"),
30 | converter={0: int},
31 | ),
32 | ),
33 | MeasurableIssueConfig(
34 | origin_class="funlen",
35 | new_description=get_func_len_tip(),
36 | parser=IssueDescriptionParser(
37 | regexp=re.compile(r"^Function '.*' is too long \((\d+) > 1\)$"),
38 | converter={0: int},
39 | ),
40 | ),
41 | MeasurableIssueConfig(
42 | origin_class="lll",
43 | new_description=get_line_len_tip(),
44 | parser=IssueDescriptionParser(
45 | regexp=re.compile(r"^line is (\d+) characters$"),
46 | converter={0: int},
47 | ),
48 | ),
49 | MeasurableIssueConfig(
50 | origin_class="maintidx",
51 | new_description=get_maintainability_index_tip(),
52 | parser=IssueDescriptionParser(
53 | regexp=re.compile(
54 | r"^Function name: .*, Cyclomatic Complexity: .*, Halstead Volume: .*, Maintainability Index: (.+)$",
55 | ),
56 | converter={0: lambda group: convert_percentage_of_value_to_lack_of_value(float(group))},
57 | ),
58 | ),
59 | ]
60 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/ij_java/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/hyperstyle/src/python/review/inspectors/ij_java/__init__.py
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/ij_java/ij_java.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from hyperstyle.src.python.review.inspectors.common.inspector.base_inspector import BaseIJInspector
4 | from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType
5 | from hyperstyle.src.python.review.inspectors.common.inspector.proto import model_pb2
6 | from hyperstyle.src.python.review.inspectors.ij_java.issue_configs import ISSUE_CONFIGS
7 | from hyperstyle.src.python.review.inspectors.ij_java.issue_types import (
8 | IJ_INSPECTION_TO_ISSUE_TYPE,
9 | IJ_MESSAGE_TO_ISSUE_TYPE,
10 | )
11 |
12 |
13 | class JavaIJInspector(BaseIJInspector):
14 | inspector_type = InspectorType.IJ_JAVA
15 | language_id = model_pb2.LanguageId.java
16 | issue_configs = ISSUE_CONFIGS
17 | ij_inspection_to_issue_type = IJ_INSPECTION_TO_ISSUE_TYPE
18 | ij_message_to_issue_type = IJ_MESSAGE_TO_ISSUE_TYPE
19 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/ij_java/issue_configs.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from typing import TYPE_CHECKING
4 |
5 | if TYPE_CHECKING:
6 | from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import IssueConfig
7 |
8 | ISSUE_CONFIGS: list[IssueConfig] = []
9 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/ij_java/issue_types.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | IJ_INSPECTION_TO_ISSUE_TYPE = {}
4 |
5 | IJ_MESSAGE_TO_ISSUE_TYPE = {}
6 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/ij_kotlin/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/hyperstyle/src/python/review/inspectors/ij_kotlin/__init__.py
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/ij_kotlin/ij_kotlin.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from hyperstyle.src.python.review.inspectors.common.inspector.base_inspector import BaseIJInspector
4 | from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType
5 | from hyperstyle.src.python.review.inspectors.common.inspector.proto import model_pb2
6 | from hyperstyle.src.python.review.inspectors.ij_kotlin.issue_configs import ISSUE_CONFIGS
7 | from hyperstyle.src.python.review.inspectors.ij_kotlin.issue_types import (
8 | IJ_INSPECTION_TO_ISSUE_TYPE,
9 | IJ_MESSAGE_TO_ISSUE_TYPE,
10 | )
11 |
12 |
13 | class KotlinIJInspector(BaseIJInspector):
14 | inspector_type = InspectorType.IJ_KOTLIN
15 | language_id = model_pb2.LanguageId.kotlin
16 | issue_configs = ISSUE_CONFIGS
17 | ij_inspection_to_issue_type = IJ_INSPECTION_TO_ISSUE_TYPE
18 | ij_message_to_issue_type = IJ_MESSAGE_TO_ISSUE_TYPE
19 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/ij_kotlin/issue_configs.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from typing import TYPE_CHECKING
4 |
5 | if TYPE_CHECKING:
6 | from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import IssueConfig
7 |
8 | ISSUE_CONFIGS: list[IssueConfig] = []
9 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/ij_kotlin/issue_types.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | IJ_INSPECTION_TO_ISSUE_TYPE = {}
4 |
5 | IJ_MESSAGE_TO_ISSUE_TYPE = {}
6 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/ij_python/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/hyperstyle/src/python/review/inspectors/ij_python/__init__.py
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/ij_python/ij_python.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from hyperstyle.src.python.review.inspectors.common.inspector.base_inspector import BaseIJInspector
4 | from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType
5 | from hyperstyle.src.python.review.inspectors.common.inspector.proto import model_pb2
6 | from hyperstyle.src.python.review.inspectors.ij_python.issue_configs import ISSUE_CONFIGS
7 | from hyperstyle.src.python.review.inspectors.ij_python.issue_types import (
8 | IJ_INSPECTION_TO_ISSUE_TYPE,
9 | IJ_MESSAGE_TO_ISSUE_TYPE,
10 | )
11 |
12 |
13 | class PythonIJInspector(BaseIJInspector):
14 | inspector_type = InspectorType.IJ_PYTHON
15 | language_id = model_pb2.LanguageId.python
16 | issue_configs = ISSUE_CONFIGS
17 | ij_inspection_to_issue_type = IJ_INSPECTION_TO_ISSUE_TYPE
18 | ij_message_to_issue_type = IJ_MESSAGE_TO_ISSUE_TYPE
19 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/ij_python/issue_configs.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import IssueConfig
4 |
5 | ISSUE_CONFIGS: list[IssueConfig] = [
6 | IssueConfig(
7 | origin_class="E128",
8 | new_description="Incorrect indent",
9 | ),
10 | ]
11 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/pmd/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/hyperstyle/src/python/review/inspectors/pmd/__init__.py
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/pmd/issue_configs.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from typing import TYPE_CHECKING
4 |
5 | if TYPE_CHECKING:
6 | from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import IssueConfig
7 |
8 | ISSUE_CONFIGS: list[IssueConfig] = []
9 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/pyast/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/hyperstyle/src/python/review/inspectors/pyast/__init__.py
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/pylint/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/hyperstyle/src/python/review/inspectors/pylint/__init__.py
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/pylint/issue_configs.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from hyperstyle.src.python.review.inspectors.common.issue.issue_configs import IssueConfig
4 |
5 | ISSUE_CONFIGS: list[IssueConfig] = [
6 | IssueConfig(
7 | origin_class="W1404",
8 | new_description='Found implicit string concatenation. If you want to concatenate strings, use "+".',
9 | ),
10 | IssueConfig(
11 | origin_class="R1721",
12 | new_description=(
13 | "Unnecessary use of a comprehension. Instead of using an identity comprehension, "
14 | "consider using the list, dict or set constructor. It is faster and simpler. "
15 | "For example, instead of {{key: value for key, value in list_of_tuples}} use dict(list_of_tuples)."
16 | ),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/inspectors/radon/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/hyperstyle/src/python/review/inspectors/radon/__init__.py
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/logging_config.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | import sys
4 |
5 | logging_config: dict[str, object] = {
6 | "version": 1,
7 | "formatters": {
8 | "common": {
9 | "class": "logging.Formatter",
10 | "format": "%(asctime)s | %(levelname)s | %(message)s",
11 | },
12 | },
13 | "handlers": {
14 | "console": {
15 | "class": "logging.StreamHandler",
16 | "level": "DEBUG",
17 | "formatter": "common",
18 | "stream": sys.stdout,
19 | },
20 | },
21 | "loggers": {
22 | "": {
23 | "handlers": ["console"],
24 | "level": "INFO",
25 | },
26 | },
27 | "disable_existing_loggers": False,
28 | }
29 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/quality/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/hyperstyle/src/python/review/quality/__init__.py
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/quality/rules/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/hyperstyle/src/python/review/quality/rules/__init__.py
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/quality/rules/class_response_scoring.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from dataclasses import dataclass
4 |
5 | from hyperstyle.src.python.review.common.language import Language
6 | from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType
7 | from hyperstyle.src.python.review.quality.model import QualityType, Rule
8 |
9 |
10 | @dataclass
11 | class ResponseRuleConfig:
12 | response_moderate: int
13 | response_good: int
14 |
15 |
16 | common_response_rule_config = ResponseRuleConfig(
17 | response_moderate=69,
18 | response_good=59,
19 | )
20 |
21 | LANGUAGE_TO_RESPONSE_RULE_CONFIG = {
22 | Language.JAVA: common_response_rule_config,
23 | Language.PYTHON: common_response_rule_config,
24 | Language.KOTLIN: common_response_rule_config,
25 | Language.JS: common_response_rule_config,
26 | Language.GO: common_response_rule_config,
27 | }
28 |
29 |
30 | class ResponseRule(Rule):
31 | def __init__(self, config: ResponseRuleConfig) -> None:
32 | self.config = config
33 | self.rule_type = IssueType.CLASS_RESPONSE
34 | self.response: int | None = None
35 |
36 | def apply(self, response: int) -> None:
37 | self.response = response
38 | if response > self.config.response_moderate:
39 | self.quality_type = QualityType.MODERATE
40 | self.next_level_delta = response - self.config.response_moderate
41 | elif response > self.config.response_good:
42 | self.quality_type = QualityType.GOOD
43 | self.next_level_delta = response - self.config.response_good
44 | else:
45 | self.quality_type = QualityType.EXCELLENT
46 | self.next_level_delta = response
47 | self.next_level_type = self.__get_next_quality_type()
48 |
49 | def __get_next_quality_type(self) -> QualityType:
50 | if self.quality_type == QualityType.MODERATE:
51 | return QualityType.GOOD
52 | return QualityType.EXCELLENT
53 |
54 | def merge(self, other: ResponseRule) -> ResponseRule:
55 | config = ResponseRuleConfig(
56 | min(self.config.response_moderate, other.config.response_moderate),
57 | min(self.config.response_good, other.config.response_good),
58 | )
59 | result_rule = ResponseRule(config)
60 | result_rule.apply(max(self.response, other.response))
61 |
62 | return result_rule
63 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/quality/rules/coupling_scoring.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from dataclasses import dataclass
4 |
5 | from hyperstyle.src.python.review.common.language import Language
6 | from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType
7 | from hyperstyle.src.python.review.quality.model import QualityType, Rule
8 |
9 |
10 | @dataclass
11 | class CouplingRuleConfig:
12 | coupling_bad: int
13 | coupling_moderate: int
14 |
15 |
16 | common_coupling_rule_config = CouplingRuleConfig(
17 | coupling_bad=30,
18 | coupling_moderate=20,
19 | )
20 |
21 | LANGUAGE_TO_COUPLING_RULE_CONFIG = {
22 | Language.JAVA: common_coupling_rule_config,
23 | Language.PYTHON: common_coupling_rule_config,
24 | Language.KOTLIN: common_coupling_rule_config,
25 | Language.JS: common_coupling_rule_config,
26 | Language.GO: common_coupling_rule_config,
27 | }
28 |
29 |
30 | class CouplingRule(Rule):
31 | def __init__(self, config: CouplingRuleConfig) -> None:
32 | self.config = config
33 | self.rule_type = IssueType.COUPLING
34 | self.coupling: int | None = None
35 |
36 | def apply(self, coupling: int) -> None:
37 | self.coupling = coupling
38 | if coupling > self.config.coupling_bad:
39 | self.quality_type = QualityType.BAD
40 | self.next_level_delta = coupling - self.config.coupling_bad
41 | elif coupling > self.config.coupling_moderate:
42 | self.quality_type = QualityType.MODERATE
43 | self.next_level_delta = coupling - self.config.coupling_moderate
44 | else:
45 | self.quality_type = QualityType.EXCELLENT
46 | self.next_level_delta = coupling
47 | self.next_level_type = self.__get_next_quality_type()
48 |
49 | def __get_next_quality_type(self) -> QualityType:
50 | if self.quality_type == QualityType.BAD:
51 | return QualityType.MODERATE
52 | return QualityType.EXCELLENT
53 |
54 | def merge(self, other: CouplingRule) -> CouplingRule:
55 | config = CouplingRuleConfig(
56 | min(self.config.coupling_bad, other.config.coupling_bad),
57 | min(self.config.coupling_moderate, other.config.coupling_moderate),
58 | )
59 | result_rule = CouplingRule(config)
60 | result_rule.apply(max(self.coupling, other.coupling))
61 |
62 | return result_rule
63 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/quality/rules/error_prone_scoring.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from dataclasses import dataclass
4 |
5 | from hyperstyle.src.python.review.common.language import Language
6 | from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType
7 | from hyperstyle.src.python.review.quality.model import QualityType, Rule
8 |
9 |
10 | @dataclass
11 | class ErrorProneRuleConfig:
12 | n_error_prone_bad: int
13 |
14 |
15 | # TODO: It is necessary to add subcategories where the following boundaries can be used:
16 | # GOOD: 0
17 | # MODERATE: 1
18 | # BAD: 2
19 | common_error_prone_rule_config = ErrorProneRuleConfig(
20 | n_error_prone_bad=0,
21 | )
22 |
23 | LANGUAGE_TO_ERROR_PRONE_RULE_CONFIG = {
24 | Language.JAVA: common_error_prone_rule_config,
25 | Language.KOTLIN: common_error_prone_rule_config,
26 | Language.PYTHON: common_error_prone_rule_config,
27 | Language.JS: common_error_prone_rule_config,
28 | Language.GO: common_error_prone_rule_config,
29 | }
30 |
31 |
32 | class ErrorProneRule(Rule):
33 | def __init__(self, config: ErrorProneRuleConfig) -> None:
34 | self.config = config
35 | self.rule_type = IssueType.ERROR_PRONE
36 | self.n_error_prone: int | None = None
37 |
38 | def apply(self, n_error_prone: int) -> None:
39 | self.n_error_prone = n_error_prone
40 | if n_error_prone > self.config.n_error_prone_bad:
41 | self.quality_type = QualityType.BAD
42 | self.next_level_delta = n_error_prone - self.config.n_error_prone_bad
43 | else:
44 | self.quality_type = QualityType.EXCELLENT
45 | self.next_level_delta = n_error_prone
46 | self.next_level_type = self.__get_next_quality_type()
47 |
48 | def __get_next_quality_type(self) -> QualityType:
49 | return QualityType.EXCELLENT
50 |
51 | def merge(self, other: ErrorProneRule) -> ErrorProneRule:
52 | config = ErrorProneRuleConfig(min(self.config.n_error_prone_bad, other.config.n_error_prone_bad))
53 | result_rule = ErrorProneRule(config)
54 | result_rule.apply(self.n_error_prone + other.n_error_prone)
55 |
56 | return result_rule
57 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/quality/rules/function_length_scoring.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from dataclasses import dataclass
4 |
5 | from hyperstyle.src.python.review.common.language import Language
6 | from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType
7 | from hyperstyle.src.python.review.quality.model import QualityType, Rule
8 |
9 |
10 | @dataclass
11 | class FunctionLengthRuleConfig:
12 | func_len_bad: int
13 |
14 |
15 | LANGUAGE_TO_FUNCTION_LENGTH_RULE_CONFIG = {
16 | Language.JAVA: FunctionLengthRuleConfig(
17 | func_len_bad=69,
18 | ),
19 | Language.KOTLIN: FunctionLengthRuleConfig(
20 | func_len_bad=69,
21 | ),
22 | Language.PYTHON: FunctionLengthRuleConfig(
23 | func_len_bad=49,
24 | ),
25 | Language.JS: FunctionLengthRuleConfig(
26 | func_len_bad=69,
27 | ),
28 | # Using java config
29 | Language.GO: FunctionLengthRuleConfig(
30 | func_len_bad=69,
31 | ),
32 | }
33 |
34 |
35 | class FunctionLengthRule(Rule):
36 | def __init__(self, config: FunctionLengthRuleConfig) -> None:
37 | self.config = config
38 | self.rule_type = IssueType.FUNC_LEN
39 | self.func_len: int | None = None
40 |
41 | def apply(self, func_len: int) -> None:
42 | self.func_len = func_len
43 | if func_len > self.config.func_len_bad:
44 | self.quality_type = QualityType.BAD
45 | self.next_level_delta = func_len - self.config.func_len_bad
46 | else:
47 | self.quality_type = QualityType.EXCELLENT
48 | self.next_level_delta = 0
49 | self.next_level_type = self.__get_next_quality_type()
50 |
51 | def __get_next_quality_type(self) -> QualityType:
52 | return QualityType.EXCELLENT
53 |
54 | def merge(self, other: FunctionLengthRule) -> FunctionLengthRule:
55 | config = FunctionLengthRuleConfig(
56 | min(self.config.func_len_bad, other.config.func_len_bad),
57 | )
58 | result_rule = FunctionLengthRule(config)
59 | result_rule.apply(max(self.func_len, other.func_len))
60 |
61 | return result_rule
62 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/quality/rules/inheritance_depth_scoring.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from dataclasses import dataclass
4 |
5 | from hyperstyle.src.python.review.common.language import Language
6 | from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType
7 | from hyperstyle.src.python.review.quality.model import QualityType, Rule
8 |
9 |
10 | @dataclass
11 | class InheritanceDepthRuleConfig:
12 | depth_bad: int
13 |
14 |
15 | common_inheritance_depth_rule_config = InheritanceDepthRuleConfig(
16 | depth_bad=3,
17 | )
18 |
19 | LANGUAGE_TO_INHERITANCE_DEPTH_RULE_CONFIG = {
20 | Language.JAVA: common_inheritance_depth_rule_config,
21 | Language.PYTHON: common_inheritance_depth_rule_config,
22 | Language.KOTLIN: common_inheritance_depth_rule_config,
23 | Language.JS: common_inheritance_depth_rule_config,
24 | Language.GO: common_inheritance_depth_rule_config,
25 | }
26 |
27 |
28 | class InheritanceDepthRule(Rule):
29 | def __init__(self, config: InheritanceDepthRuleConfig) -> None:
30 | self.config = config
31 | self.rule_type = IssueType.INHERITANCE_DEPTH
32 | self.depth: int | None = None
33 |
34 | def apply(self, depth: int) -> None:
35 | self.depth = depth
36 | if depth > self.config.depth_bad:
37 | self.quality_type = QualityType.BAD
38 | self.next_level_delta = depth - self.config.depth_bad
39 | else:
40 | self.quality_type = QualityType.EXCELLENT
41 | self.next_level_delta = depth
42 | self.next_level_type = self.__get_next_quality_type()
43 |
44 | def __get_next_quality_type(self) -> QualityType:
45 | return QualityType.EXCELLENT
46 |
47 | def merge(self, other: InheritanceDepthRule) -> InheritanceDepthRule:
48 | config = InheritanceDepthRuleConfig(min(self.config.depth_bad, other.config.depth_bad))
49 | result_rule = InheritanceDepthRule(config)
50 | result_rule.apply(max(self.depth, other.depth))
51 |
52 | return result_rule
53 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/reviewers/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/hyperstyle/src/python/review/reviewers/__init__.py
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/reviewers/exceptions.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 |
4 | class UnsupportedLanguageError(Exception):
5 | pass
6 |
7 |
8 | class InspectionError(Exception):
9 | pass
10 |
11 |
12 | class PathNotExistsError(Exception):
13 | pass
14 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/reviewers/go.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from typing import TYPE_CHECKING
4 |
5 | from hyperstyle.src.python.review.common.language import Language
6 | from hyperstyle.src.python.review.reviewers.common import perform_language_review
7 | from hyperstyle.src.python.review.reviewers.utils.metadata_exploration import Metadata, ProjectMetadata
8 |
9 | if TYPE_CHECKING:
10 | from hyperstyle.src.python.review.application_config import ApplicationConfig
11 | from hyperstyle.src.python.review.reviewers.review_result import GeneralReviewResult
12 |
13 |
14 | def perform_go_review(metadata: Metadata, config: ApplicationConfig) -> GeneralReviewResult:
15 | # The project must contain a go.mod file. If it's missing, then create it.
16 | if isinstance(metadata, ProjectMetadata):
17 | mod_file_path = metadata.path / "go.mod"
18 | if not mod_file_path.exists():
19 | mod_file_path.write_text("module main")
20 |
21 | return perform_language_review(metadata, config, Language.GO)
22 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/reviewers/python.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from typing import TYPE_CHECKING
4 |
5 | from hyperstyle.src.python.review.common.file_system import FileSystemItem, get_all_file_system_items
6 | from hyperstyle.src.python.review.common.language import Language
7 | from hyperstyle.src.python.review.reviewers.common import perform_language_review
8 | from hyperstyle.src.python.review.reviewers.utils.metadata_exploration import Metadata, ProjectMetadata
9 |
10 | if TYPE_CHECKING:
11 | from pathlib import Path
12 |
13 | from hyperstyle.src.python.review.application_config import ApplicationConfig
14 | from hyperstyle.src.python.review.reviewers.review_result import GeneralReviewResult
15 |
16 |
17 | def perform_python_review(metadata: Metadata, config: ApplicationConfig) -> GeneralReviewResult:
18 | created_file_paths = []
19 | if isinstance(metadata, ProjectMetadata):
20 | created_file_paths.extend(create_init_scripts_in_subdirs(metadata.path))
21 |
22 | review_result = perform_language_review(metadata, config, Language.PYTHON)
23 | review_result.file_review_results = [
24 | file_review_result
25 | for file_review_result in review_result.file_review_results
26 | if file_review_result.file_path not in created_file_paths
27 | ]
28 | return review_result
29 |
30 |
31 | def create_init_scripts_in_subdirs(path: Path) -> list[Path]:
32 | created_file_paths = []
33 | for subdir in get_all_file_system_items(path, item_type=FileSystemItem.SUBDIR):
34 | init_file_path = subdir / "__init__.py"
35 | if not init_file_path.is_file():
36 | init_file_path.touch()
37 | created_file_paths.append(init_file_path)
38 |
39 | return created_file_paths
40 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/reviewers/review_result.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from dataclasses import dataclass
4 | from typing import TYPE_CHECKING
5 |
6 | if TYPE_CHECKING:
7 | from pathlib import Path
8 |
9 | from hyperstyle.src.python.review.inspectors.common.issue.issue import BaseIssue, IssueDifficulty
10 | from hyperstyle.src.python.review.quality.model import Quality
11 | from hyperstyle.src.python.review.quality.penalty import Punisher
12 |
13 |
14 | @dataclass
15 | class ReviewResult:
16 | """ReviewResult contains a list of issues, as well as quality and punisher obtained with these issues."""
17 |
18 | quality_by_difficulty: dict[IssueDifficulty, Quality]
19 | punisher_by_difficulty: dict[IssueDifficulty, Punisher]
20 | issues: list[BaseIssue]
21 |
22 |
23 | @dataclass
24 | class FileReviewResult(ReviewResult):
25 | """FileReviewResult contains the information needed to output about a particular inspected file."""
26 |
27 | file_path: Path
28 |
29 |
30 | @dataclass
31 | class GeneralReviewResult(ReviewResult):
32 | """GeneralReviewResult contains the information needed to output about the entire inspected project."""
33 |
34 | file_review_results: list[FileReviewResult]
35 |
--------------------------------------------------------------------------------
/hyperstyle/src/python/review/reviewers/utils/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/hyperstyle/src/python/review/reviewers/utils/__init__.py
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "code-review-tool",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "eslint": "./node_modules/eslint/bin/eslint.js"
7 | },
8 | "dependencies": {
9 | "eslint-plugin-standard": "4.0.1"
10 | },
11 | "devDependencies": {
12 | "eslint": "^7.19.0"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/test/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/test/__init__.py
--------------------------------------------------------------------------------
/test/python/__init__.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from pathlib import Path
4 |
5 | TEST_DATA_FOLDER = Path(__file__).parent.parent / "resources"
6 |
--------------------------------------------------------------------------------
/test/python/functional_tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/test/python/functional_tests/__init__.py
--------------------------------------------------------------------------------
/test/python/functional_tests/test_different_languages.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | import subprocess
4 |
5 | from test.python.functional_tests.conftest import DATA_PATH, LocalCommandBuilder
6 |
7 |
8 | def test_python(local_command: LocalCommandBuilder) -> None:
9 | file_path = DATA_PATH / "different_languages" / "python"
10 |
11 | local_command.path = file_path
12 | process = subprocess.run(
13 | local_command.build(),
14 | capture_output=True,
15 | check=False,
16 | )
17 | output = process.stdout.decode()
18 |
19 | assert process.returncode == 1
20 | assert "a.py" in output
21 | assert "b.py" in output
22 |
23 |
24 | def test_java(local_command: LocalCommandBuilder) -> None:
25 | file_path = DATA_PATH / "different_languages" / "java"
26 |
27 | local_command.path = file_path
28 | process = subprocess.run(
29 | local_command.build(),
30 | capture_output=True,
31 | check=False,
32 | )
33 | output = process.stdout.decode()
34 |
35 | assert process.returncode == 1
36 | assert "First.java" in output
37 | assert "Second.java" in output
38 |
39 |
40 | def test_kotlin(local_command: LocalCommandBuilder) -> None:
41 | file_path = DATA_PATH / "different_languages" / "kotlin"
42 |
43 | local_command.path = file_path
44 | process = subprocess.run(
45 | local_command.build(),
46 | capture_output=True,
47 | check=False,
48 | )
49 | output = process.stdout.decode()
50 |
51 | assert process.returncode == 1
52 | assert "main.kt" in output
53 | assert "person.kt" in output
54 |
55 |
56 | def test_all_java_inspectors(local_command: LocalCommandBuilder) -> None:
57 | file_path = DATA_PATH / "different_languages" / "java"
58 |
59 | local_command.path = file_path
60 | local_command.disable = []
61 | process = subprocess.run(
62 | local_command.build(),
63 | capture_output=True,
64 | check=False,
65 | )
66 | output = process.stdout.decode()
67 |
68 | assert process.returncode == 1
69 | assert "First.java" in output
70 | assert "Second.java" in output
71 |
72 |
73 | def test_go(local_command: LocalCommandBuilder) -> None:
74 | file_path = DATA_PATH / "different_languages" / "go"
75 |
76 | local_command.path = file_path
77 | local_command.disable = []
78 | process = subprocess.run(
79 | local_command.build(),
80 | capture_output=True,
81 | check=False,
82 | )
83 | output = process.stdout.decode()
84 |
85 | assert process.returncode == 1
86 | assert "a.go" in output
87 | assert "b.go" in output
88 |
--------------------------------------------------------------------------------
/test/python/functional_tests/test_disable.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | import subprocess
4 |
5 | from test.python.functional_tests.conftest import DATA_PATH, LocalCommandBuilder
6 |
7 |
8 | def test_disable_works(local_command: LocalCommandBuilder) -> None:
9 | file_path = DATA_PATH / "disable" / "contains_flake8_issues.py"
10 |
11 | local_command.path = file_path
12 | process = subprocess.run(
13 | local_command.build(),
14 | capture_output=True,
15 | check=False,
16 | )
17 | output = process.stdout.decode()
18 |
19 | assert "FLAKE8" in output
20 |
21 | local_command.disable.append("flake8")
22 | process = subprocess.run(
23 | local_command.build(),
24 | capture_output=True,
25 | check=False,
26 | )
27 | output = process.stdout.decode()
28 |
29 | assert "FLAKE8" not in output
30 |
--------------------------------------------------------------------------------
/test/python/functional_tests/test_duplicates.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | import re
4 | import subprocess
5 |
6 | from test.python.functional_tests.conftest import DATA_PATH, LocalCommandBuilder
7 |
8 |
9 | def test_allow_duplicates(local_command: LocalCommandBuilder) -> None:
10 | file_with_duplicate_issue_path = DATA_PATH / "duplicates" / "code_with_duplicate_issues.py"
11 |
12 | local_command.allow_duplicates = True
13 | local_command.path = file_with_duplicate_issue_path
14 |
15 | process = subprocess.run(
16 | local_command.build(),
17 | capture_output=True,
18 | check=False,
19 | )
20 | stdout_allow_duplicates = process.stdout.decode()
21 |
22 | local_command.allow_duplicates = False
23 |
24 | process = subprocess.run(
25 | local_command.build(),
26 | capture_output=True,
27 | check=False,
28 | )
29 | stdout_filter_duplicates = process.stdout.decode()
30 |
31 | flake8_var_issue_re = re.compile(r".*FLAKE8.*local variable \'var\'.*", re.DOTALL)
32 | pylint_var_issue_re = re.compile(r".*PYLINT.*Unused variable \'var\'.*", re.DOTALL)
33 |
34 | assert len(stdout_filter_duplicates) < len(stdout_allow_duplicates)
35 | assert flake8_var_issue_re.match(stdout_allow_duplicates) is not None
36 | assert pylint_var_issue_re.match(stdout_allow_duplicates) is not None
37 | assert (flake8_var_issue_re.match(stdout_filter_duplicates) is not None) ^ (
38 | pylint_var_issue_re.match(stdout_filter_duplicates) is not None
39 | )
40 |
--------------------------------------------------------------------------------
/test/python/functional_tests/test_exit_code.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | import subprocess
4 | from pathlib import Path
5 |
6 | from test.python.functional_tests.conftest import DATA_PATH, LocalCommandBuilder
7 |
8 |
9 | def test_exit_code_zero(local_command: LocalCommandBuilder) -> None:
10 | file_path = DATA_PATH / "exit_codes" / "no_issues.py"
11 |
12 | local_command.path = file_path
13 | process = subprocess.run(
14 | local_command.build(),
15 | capture_output=True,
16 | check=False,
17 | )
18 |
19 | assert process.returncode == 0
20 |
21 |
22 | def test_exit_code_one(local_command: LocalCommandBuilder) -> None:
23 | file_path = DATA_PATH / "exit_codes" / "with_issues.py"
24 |
25 | local_command.path = file_path
26 | process = subprocess.run(
27 | local_command.build(),
28 | capture_output=True,
29 | check=False,
30 | )
31 |
32 | assert process.returncode == 1
33 |
34 |
35 | def test_exit_code_two(local_command: LocalCommandBuilder) -> None:
36 | file_path = Path("no_such_file.py")
37 |
38 | local_command.path = file_path
39 | process = subprocess.run(
40 | local_command.build(),
41 | capture_output=True,
42 | check=False,
43 | )
44 |
45 | assert process.returncode == 2
46 |
--------------------------------------------------------------------------------
/test/python/functional_tests/test_file_or_project.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | import subprocess
4 |
5 | from test.python.functional_tests.conftest import DATA_PATH, LocalCommandBuilder
6 |
7 |
8 | def test_inspect_file_works(local_command: LocalCommandBuilder) -> None:
9 | file_path = DATA_PATH / "file_or_project" / "file.py"
10 |
11 | local_command.path = file_path
12 |
13 | process = subprocess.run(
14 | local_command.build(),
15 | capture_output=True,
16 | check=False,
17 | )
18 | output = process.stdout.decode()
19 |
20 | assert process.returncode == 1
21 | assert file_path.name in output
22 |
23 |
24 | def test_inspect_project_works(local_command: LocalCommandBuilder) -> None:
25 | file_path = DATA_PATH / "file_or_project" / "project"
26 |
27 | local_command.path = file_path
28 |
29 | process = subprocess.run(
30 | local_command.build(),
31 | capture_output=True,
32 | check=False,
33 | )
34 | output = process.stdout.decode()
35 |
36 | assert process.returncode == 1
37 | assert "one.py" in output
38 | assert "other.py" in output
39 |
40 |
41 | def test_inspect_project_with_unknown_extensions_works(local_command: LocalCommandBuilder) -> None:
42 | file_path = DATA_PATH / "file_or_project" / "project_with_unknown_extensions"
43 |
44 | local_command.path = file_path
45 |
46 | process = subprocess.run(
47 | local_command.build(),
48 | capture_output=True,
49 | check=False,
50 | )
51 | output = process.stdout.decode()
52 |
53 | assert process.returncode == 1
54 | assert "file.py" in output
55 |
--------------------------------------------------------------------------------
/test/python/functional_tests/test_verbosity.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | import json
4 | import subprocess
5 |
6 | from test.python.functional_tests.conftest import DATA_PATH, LocalCommandBuilder
7 |
8 |
9 | def test_disable_logs_text(local_command: LocalCommandBuilder) -> None:
10 | file_path = DATA_PATH / "verbosity" / "some_code.py"
11 |
12 | local_command.verbosity = 0
13 | local_command.path = file_path
14 |
15 | process = subprocess.run(
16 | local_command.build(),
17 | capture_output=True,
18 | check=False,
19 | )
20 | output = process.stdout.decode()
21 | output = output.lower()
22 |
23 | assert " debug " not in output
24 | assert " info " not in output
25 | assert " error " not in output
26 |
27 |
28 | def test_disable_logs_json(local_command: LocalCommandBuilder) -> None:
29 | file_path = DATA_PATH / "verbosity" / "some_code.py"
30 |
31 | local_command.verbosity = 0
32 | local_command.format = "json"
33 | local_command.path = file_path
34 |
35 | process = subprocess.run(
36 | local_command.build(),
37 | capture_output=True,
38 | check=False,
39 | )
40 |
41 | output = process.stdout.decode()
42 | json.loads(output)
43 |
44 |
45 | def test_enable_all_logs(local_command: LocalCommandBuilder) -> None:
46 | file_path = DATA_PATH / "verbosity" / "some_code.py"
47 |
48 | local_command.verbosity = 3
49 | local_command.path = file_path
50 |
51 | process = subprocess.run(
52 | local_command.build(),
53 | capture_output=True,
54 | check=False,
55 | )
56 | output = process.stdout.decode()
57 | output = output.lower()
58 |
59 | assert " debug " in output
60 |
--------------------------------------------------------------------------------
/test/python/inspectors/__init__.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from test.python import TEST_DATA_FOLDER
4 |
5 | CURRENT_TEST_DATA_FOLDER = TEST_DATA_FOLDER / "inspectors"
6 |
7 | PYTHON_DATA_FOLDER = CURRENT_TEST_DATA_FOLDER / "python"
8 |
9 | JAVA_DATA_FOLDER = CURRENT_TEST_DATA_FOLDER / "java"
10 |
11 | KOTLIN_DATA_FOLDER = CURRENT_TEST_DATA_FOLDER / "kotlin"
12 |
13 | SPRING_DATA_FOLDER = CURRENT_TEST_DATA_FOLDER / "spring"
14 |
15 | JS_DATA_FOLDER = CURRENT_TEST_DATA_FOLDER / "js"
16 |
17 | GO_DATA_FOLDER = CURRENT_TEST_DATA_FOLDER / "go"
18 |
19 | PYTHON_AST_DATA_FOLDER = CURRENT_TEST_DATA_FOLDER / "python_ast"
20 |
21 | CHECKSTYLE_DATA_FOLDER = CURRENT_TEST_DATA_FOLDER / "checkstyle"
22 |
23 | PMD_DATA_FOLDER = CURRENT_TEST_DATA_FOLDER / "pmd"
24 |
25 | FLAKE_DATA_FOLDER = CURRENT_TEST_DATA_FOLDER / "flake8"
26 |
27 | PYLINT_DATA_FOLDER = CURRENT_TEST_DATA_FOLDER / "pylint"
28 |
29 | DETEKT_DATA_FOLDER = CURRENT_TEST_DATA_FOLDER / "detekt"
30 |
31 | ESLINT_DATA_FOLDER = CURRENT_TEST_DATA_FOLDER / "eslint"
32 |
33 | GOLANG_LINT_FOLDER = CURRENT_TEST_DATA_FOLDER / "golang_lint"
34 |
--------------------------------------------------------------------------------
/test/python/inspectors/test_common.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | import pytest
4 |
5 | from hyperstyle.src.python.review.inspectors.common.utils import (
6 | _get_format_fields,
7 | contains_format_fields,
8 | contains_named_format_fields,
9 | )
10 |
11 | GET_FORMAT_FIELDS_TEST_DATA = [
12 | ("", []),
13 | ("abcdef", []),
14 | ("{{}}", []),
15 | ("{{0}}", []),
16 | ("{{false}}", []),
17 | ("{{abc:.3f}}", []),
18 | ("{}", [""]),
19 | ("{0}", ["0"]),
20 | ("{false}", ["false"]),
21 | ("{abc:.3f}", ["abc"]),
22 | ("{} {{}} {0} {abc}", ["", "0", "abc"]),
23 | ("This is a {f}-string!", ["f"]),
24 | ("{key: value for key, value in dct.items()}", ["key"]),
25 | ]
26 |
27 |
28 | @pytest.mark.parametrize(("string", "expected_fields"), GET_FORMAT_FIELDS_TEST_DATA)
29 | def test_get_format_fields(string: str, expected_fields: list[str]) -> None:
30 | assert _get_format_fields(string) == expected_fields
31 |
32 |
33 | CONTAINS_FORMAT_FIELDS_TEST_DATA = [
34 | ("", False),
35 | ("abcdef", False),
36 | ("{{}}", False),
37 | ("{{0}}", False),
38 | ("{{false}}", False),
39 | ("{{abc:.3f}}", False),
40 | ("{}", True),
41 | ("{0}", True),
42 | ("{false}", True),
43 | ("{abc:.3f}", True),
44 | ("{} {{}} {0} {abc}", True),
45 | ("This is a {f}-string!", True),
46 | ("{key: value for key, value in dct.items()}", True),
47 | ]
48 |
49 |
50 | @pytest.mark.parametrize(("string", "expected"), CONTAINS_FORMAT_FIELDS_TEST_DATA)
51 | def test_contains_format_fields(string: str, expected: bool) -> None:
52 | assert contains_format_fields(string) == expected
53 |
54 |
55 | CONTAINS_NAMED_FORMAT_FIELDS_TEST_DATA = [
56 | ("", False),
57 | ("abcdef", False),
58 | ("{{}}", False),
59 | ("{{0}}", False),
60 | ("{{false}}", False),
61 | ("{{abc:.3f}}", False),
62 | ("{}", False),
63 | ("{0}", False),
64 | ("{false}", True),
65 | ("{abc:.3f}", True),
66 | ("{} {{}} {0} {abc}", True),
67 | ("This is a {f}-string!", True),
68 | ("{key: value for key, value in dct.items()}", True),
69 | ]
70 |
71 |
72 | @pytest.mark.parametrize(("string", "expected"), CONTAINS_NAMED_FORMAT_FIELDS_TEST_DATA)
73 | def test_contains_named_format_fields(string: str, expected: bool) -> None:
74 | assert contains_named_format_fields(string) == expected
75 |
--------------------------------------------------------------------------------
/test/python/inspectors/test_eslint_inspector.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | import pytest
4 |
5 | from hyperstyle.src.python.review.common.language import Language
6 | from hyperstyle.src.python.review.inspectors.common.issue.tips import get_cyclomatic_complexity_tip
7 | from hyperstyle.src.python.review.inspectors.eslint.eslint import ESLintInspector
8 | from hyperstyle.src.python.review.reviewers.utils.issues_filter import filter_low_measure_issues
9 | from test.python.inspectors import ESLINT_DATA_FOLDER, JS_DATA_FOLDER
10 | from test.python.inspectors.conftest import use_file_metadata
11 |
12 | FILE_NAMES_AND_N_ISSUES = [
13 | ("case0_no_issues.js", 0),
14 | ("case1_with_issues.js", 7),
15 | ("case2_semi_node_and_unused.js", 5),
16 | ]
17 |
18 |
19 | @pytest.mark.parametrize(("file_name", "n_issues"), FILE_NAMES_AND_N_ISSUES)
20 | def test_file_with_issues(file_name: str, n_issues: int) -> None:
21 | inspector = ESLintInspector()
22 |
23 | path_to_file = JS_DATA_FOLDER / file_name
24 | with use_file_metadata(path_to_file) as file_metadata:
25 | issues = inspector.inspect(file_metadata.path, {})
26 | issues = filter_low_measure_issues(issues, Language.JS)
27 |
28 | assert len(issues) == n_issues
29 |
30 |
31 | MEASURE_TEST_DATA = [
32 | ("complexity", 13),
33 | ]
34 |
35 |
36 | @pytest.mark.parametrize(("origin_class", "expected_measure"), MEASURE_TEST_DATA)
37 | def test_measure_parse(origin_class: str, expected_measure: int) -> None:
38 | inspector = ESLintInspector()
39 |
40 | path_to_file = ESLINT_DATA_FOLDER / "issues" / f"{origin_class.replace('-', '_')}.js"
41 | with use_file_metadata(path_to_file) as file_metadata:
42 | issues = inspector.inspect(file_metadata.path, {})
43 |
44 | issue = next(filter(lambda elem: elem.origin_class == origin_class, issues))
45 |
46 | assert hasattr(issue, "measure")
47 | assert issue.measure() == expected_measure
48 |
49 |
50 | NEW_DESCRIPTION_TEST_DATA = [
51 | ("complexity", get_cyclomatic_complexity_tip().format(13)),
52 | ]
53 |
54 |
55 | @pytest.mark.parametrize(("origin_class", "expected_description"), NEW_DESCRIPTION_TEST_DATA)
56 | def test_new_issue_description(origin_class: str, expected_description: str) -> None:
57 | inspector = ESLintInspector()
58 |
59 | path_to_file = ESLINT_DATA_FOLDER / "issues" / f"{origin_class.replace('-', '_')}.js"
60 | with use_file_metadata(path_to_file) as file_metadata:
61 | issues = inspector.inspect(file_metadata.path, {})
62 |
63 | issue = next(filter(lambda elem: elem.origin_class == origin_class, issues))
64 |
65 | assert issue.description == expected_description
66 |
--------------------------------------------------------------------------------
/test/python/inspectors/test_out_of_range_issues.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from pathlib import Path
4 |
5 | from hyperstyle.src.python.review.inspectors.common.inspector.inspector_type import InspectorType
6 | from hyperstyle.src.python.review.inspectors.common.issue.issue import (
7 | BaseIssue,
8 | CodeIssue,
9 | IssueDifficulty,
10 | IssueType,
11 | )
12 | from hyperstyle.src.python.review.reviewers.common import filter_out_of_range_issues
13 |
14 | DEFAULT_PATH = Path("test_out_of_range_issues.py")
15 |
16 |
17 | def create_code_issue_by_line(line_no: int) -> BaseIssue:
18 | return CodeIssue(
19 | file_path=DEFAULT_PATH,
20 | line_no=line_no,
21 | description="",
22 | inspector_type=InspectorType.FLAKE8,
23 | type=IssueType.CODE_STYLE,
24 | column_no=1,
25 | origin_class="",
26 | difficulty=IssueDifficulty.EASY,
27 | )
28 |
29 |
30 | def test_out_of_range_issues_when_no_issues() -> None:
31 | issues = []
32 |
33 | assert filter_out_of_range_issues(issues) == []
34 | assert filter_out_of_range_issues(issues, start_line=2) == []
35 | assert filter_out_of_range_issues(issues, end_line=4) == []
36 | assert filter_out_of_range_issues(issues, start_line=2, end_line=4) == []
37 |
38 |
39 | def test_out_of_range_issues_when_some_out_of_range_issues() -> None:
40 | issues = [
41 | create_code_issue_by_line(line_no)
42 | for line_no in range(1, 6) # 1, 2, 3, 4, 5
43 | ]
44 |
45 | assert filter_out_of_range_issues(issues) == issues
46 | assert filter_out_of_range_issues(issues, start_line=2) == issues[1:5]
47 | assert filter_out_of_range_issues(issues, end_line=4) == issues[:4]
48 | assert filter_out_of_range_issues(issues, start_line=2, end_line=4) == issues[1:4]
49 | assert filter_out_of_range_issues(issues, start_line=4, end_line=8) == [issues[3], issues[4]]
50 | assert filter_out_of_range_issues(issues, start_line=6, end_line=10) == []
51 |
52 |
53 | def test_out_of_range_issues_when_the_same_borders() -> None:
54 | first_line_issues = [
55 | create_code_issue_by_line(1),
56 | create_code_issue_by_line(1),
57 | create_code_issue_by_line(1),
58 | ]
59 |
60 | assert filter_out_of_range_issues(first_line_issues, start_line=1, end_line=1) == first_line_issues
61 |
62 | assert filter_out_of_range_issues(first_line_issues, start_line=2, end_line=2) == []
63 |
--------------------------------------------------------------------------------
/test/python/inspectors/test_radon_inspector.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from textwrap import dedent
4 |
5 | import pytest
6 |
7 | from hyperstyle.src.python.review.common.language import Language
8 | from hyperstyle.src.python.review.inspectors.common.issue.issue import IssueType
9 | from hyperstyle.src.python.review.inspectors.common.issue.tips import get_maintainability_index_tip
10 | from hyperstyle.src.python.review.inspectors.radon.radon import RadonInspector
11 | from hyperstyle.src.python.review.reviewers.utils.issues_filter import filter_low_measure_issues
12 | from test.python.inspectors import PYTHON_DATA_FOLDER
13 | from test.python.inspectors.conftest import use_file_metadata
14 |
15 | FILE_NAMES_AND_N_ISSUES = [
16 | ("case13_complex_logic.py", 1),
17 | ("case13_complex_logic_2.py", 1),
18 | ("case8_good_class.py", 0),
19 | ]
20 |
21 |
22 | @pytest.mark.parametrize(("file_name", "n_issues"), FILE_NAMES_AND_N_ISSUES)
23 | def test_file_with_issues(file_name: str, n_issues: int) -> None:
24 | inspector = RadonInspector()
25 |
26 | path_to_file = PYTHON_DATA_FOLDER / file_name
27 | with use_file_metadata(path_to_file) as file_metadata:
28 | issues = inspector.inspect(file_metadata.path, {})
29 | issues = filter_low_measure_issues(issues, Language.PYTHON)
30 |
31 | assert len(issues) == n_issues
32 |
33 |
34 | def test_mi_parse() -> None:
35 | file_name = "test.py"
36 | output = f"""\
37 | {file_name} - C (4.32)
38 | {file_name} - B (13.7)
39 | {file_name} - A (70.0)
40 | """
41 | output = dedent(output)
42 |
43 | issues = RadonInspector.mi_parse(output)
44 |
45 | assert all(str(issue.file_path) == file_name for issue in issues)
46 | assert [issue.line_no for issue in issues] == [1, 1, 1]
47 | assert [issue.column_no for issue in issues] == [1, 1, 1]
48 | assert [issue.description for issue in issues] == [get_maintainability_index_tip()] * 3
49 | assert [issue.type for issue in issues] == [
50 | IssueType.MAINTAINABILITY,
51 | IssueType.MAINTAINABILITY,
52 | IssueType.MAINTAINABILITY,
53 | ]
54 | assert hasattr(issues[0], "maintainability_lack")
55 | assert issues[0].maintainability_lack == 95
56 |
57 | assert hasattr(issues[1], "maintainability_lack")
58 | assert issues[1].maintainability_lack == 86
59 |
60 | assert hasattr(issues[2], "maintainability_lack")
61 | assert issues[2].maintainability_lack == 30
62 |
--------------------------------------------------------------------------------
/test/python/quality/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/test/python/quality/__init__.py
--------------------------------------------------------------------------------
/test/resources/functional_tests/different_languages/go/a.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func hello(name string) string {
6 | if "Jerry" == name {
7 | return "Hello, Jerry!"
8 | } else {
9 | return "Hello, non-Jerry!"
10 | }
11 | return "Hello?"
12 | }
13 |
14 | func main() {
15 | var name string
16 | fmt.Scan(&name)
17 | fmt.Println(hello(name))
18 | }
19 |
--------------------------------------------------------------------------------
/test/resources/functional_tests/different_languages/go/b.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "math"
5 | )
6 |
7 | func hypotenuse(a int, b int) float64 {
8 | return math.Sqrt(math.Pow(float64(a), 2) + math.Pow(float64(b), 2))
9 | }
10 |
--------------------------------------------------------------------------------
/test/resources/functional_tests/different_languages/go/go.mod:
--------------------------------------------------------------------------------
1 | module main
2 |
3 | go 1.18
4 |
--------------------------------------------------------------------------------
/test/resources/functional_tests/different_languages/java/src/First.java:
--------------------------------------------------------------------------------
1 | public class First{
2 | int x = 5;
3 | }
--------------------------------------------------------------------------------
/test/resources/functional_tests/different_languages/java/src/Second.java:
--------------------------------------------------------------------------------
1 | public class Second{
2 |
3 | public static void main() {
4 | First f = new First();
5 | }
6 |
7 | }
--------------------------------------------------------------------------------
/test/resources/functional_tests/different_languages/kotlin/main.kt:
--------------------------------------------------------------------------------
1 | fun main(args:Array) {
2 | val a = Person()
3 | val b = Person()
4 | println("${a.age} ${b.age}") // Prints "32 32"
5 | a.age = 42
6 | println("${a.age} ${b.age}") // Prints "42 32"
7 | }
--------------------------------------------------------------------------------
/test/resources/functional_tests/different_languages/kotlin/person.kt:
--------------------------------------------------------------------------------
1 | class Person {
2 | var name ="Anne"
3 | var age = 32
4 | }
--------------------------------------------------------------------------------
/test/resources/functional_tests/different_languages/python/a.py:
--------------------------------------------------------------------------------
1 | def GREETING():
2 | print('hi!')
3 |
4 |
5 | class myclass:
6 |
7 | def __init__(self, a, b, C):
8 | self.A = a
9 | self.B = b
10 | self.C = C
11 |
12 | def myFun(self):
13 | print('hello 1')
14 |
15 | def my_fun(self, QQ):
16 | print('hello 2' + QQ)
17 |
18 | @classmethod
19 | def test_fun(first):
20 | print('hello 3')
21 |
22 |
23 | valid_variable = 'ok'
24 | invalidVariable = 'invalid'
25 |
26 | print(valid_variable)
27 | print(invalidVariable)
28 |
--------------------------------------------------------------------------------
/test/resources/functional_tests/different_languages/python/b.py:
--------------------------------------------------------------------------------
1 |
2 | def is_even(number):
3 | return number % 2 == 0
4 |
5 |
6 | n = int(input())
7 | for i in range(n):
8 | print(i)
9 |
--------------------------------------------------------------------------------
/test/resources/functional_tests/difficulty_levels/file_with_all_difficulty_levels.py:
--------------------------------------------------------------------------------
1 | from math import sqrt
2 |
3 | MUTABLE_CONSTANT = {"1": 1, "2": 2}
4 |
5 | class BadClass:
6 | def __init__(self, x: int, y: int):
7 | self.x = x
8 | self.y = y
9 |
10 | @staticmethod
11 | def Length(x: int, y: int) -> float:
12 | return sqrt(x ** 2 + y ** 2)
13 |
14 | @staticmethod
15 | def dot(self_x: int, self_y: int, other_x: int, other_y: int) -> int:
16 | return self_x * other_x + self_y * other_y
17 |
18 | @staticmethod
19 | def plus(self_x: int, self_y: int, other_x: int, other_y: int) -> 'BadClass':
20 | return BadClass(self_x + other_x, self_y + other_y)
21 |
22 | @staticmethod
23 | def minus(self_x: int, self_y: int, other_x: int, other_y: int) -> 'BadClass':
24 | return BadClass(self_x - other_x, self_y - other_y)
--------------------------------------------------------------------------------
/test/resources/functional_tests/difficulty_levels/file_with_only_easy_issues.py:
--------------------------------------------------------------------------------
1 | def MAIN(Number):
2 | if Number > 0:
3 | return Number
4 |
5 | return 0
6 |
7 |
8 | if __name__ == "__main__":
9 | print(
10 | "Hello, World")
11 |
12 | MAIN(0)
13 |
--------------------------------------------------------------------------------
/test/resources/functional_tests/difficulty_levels/file_with_only_hard_issues.py:
--------------------------------------------------------------------------------
1 | from math import sqrt
2 |
3 |
4 | class BadClass:
5 | def __init__(self, x: int, y: int):
6 | self.x = x
7 | self.y = y
8 |
9 | @staticmethod
10 | def length(x: int, y: int) -> float:
11 | return sqrt(x ** 2 + y ** 2)
12 |
13 | @staticmethod
14 | def dot(self_x: int, self_y: int, other_x: int, other_y: int) -> int:
15 | return self_x * other_x + self_y * other_y
16 |
17 | @staticmethod
18 | def plus(self_x: int, self_y: int, other_x: int, other_y: int) -> 'BadClass':
19 | return BadClass(self_x + other_x, self_y + other_y)
20 |
21 | @staticmethod
22 | def minus(self_x: int, self_y: int, other_x: int, other_y: int) -> 'BadClass':
23 | return BadClass(self_x - other_x, self_y - other_y)
24 |
25 |
26 | if __name__ == "__main__":
27 | print("Hello, World!")
28 |
--------------------------------------------------------------------------------
/test/resources/functional_tests/difficulty_levels/file_with_only_medium_issues.py:
--------------------------------------------------------------------------------
1 | MUTABLE_CONSTANT = {"1": 1, "2": 2}
2 |
3 | PI = 3.14
4 | DOUBLE_PI = 6.28
5 | E = 2.71
6 |
7 |
8 | def function_with_bad_try(b, c):
9 | result = None
10 |
11 | try:
12 | result = b / c
13 | except Exception:
14 | print("It's fine")
15 |
16 | return result
17 |
18 |
19 | def bad_generator(some_value):
20 | if some_value:
21 | raise StopIteration
22 | yield 1
23 |
24 |
25 | if __name__ == "__main__":
26 |
27 | print("Hello, World!")
28 |
--------------------------------------------------------------------------------
/test/resources/functional_tests/difficulty_levels/file_without_issues.py:
--------------------------------------------------------------------------------
1 | if __name__ == '__main__':
2 | print("Hello, world")
--------------------------------------------------------------------------------
/test/resources/functional_tests/disable/contains_flake8_issues.py:
--------------------------------------------------------------------------------
1 |
2 | a = int(input())
3 | b = int(input())
4 | c = int(input())
5 | d = int(input())
6 |
7 | if a > b:
8 | print('a > b')
9 |
10 | if a > b and a > b:
11 | print('a > b again')
12 |
13 | if a > b and a < d:
14 | print('b < a < d')
15 |
16 | if not a > b:
17 | print('not a > b')
18 |
19 | if b < a < d:
20 | print('b < a < d again')
21 |
22 | if a > b == True:
23 | print('a > b and True')
24 |
25 | if True:
26 | print('qqq')
27 |
28 | enabled = False # It does not work now
29 | if a > b and b < c and c > d or c < a and enabled:
30 | print('Too complex expression')
31 |
--------------------------------------------------------------------------------
/test/resources/functional_tests/duplicates/code_with_duplicate_issues.py:
--------------------------------------------------------------------------------
1 | a, b = input().split()
2 | print(int(a) + int(b))
3 |
4 |
5 | def fooBar():
6 | var = 1
7 | print(
8 | "Hello"
9 | "World"
10 | )
11 |
12 |
13 | x = 42 # noqa: E222,E305
14 | text = "This line is longer than 99 characters. This line is longer than 99 characters. This line is longer than 99 characters"
15 | pass
--------------------------------------------------------------------------------
/test/resources/functional_tests/exit_codes/no_issues.py:
--------------------------------------------------------------------------------
1 | def say_hello():
2 | print('hello')
3 |
4 |
5 | if __name__ == '__main__':
6 | say_hello()
7 |
--------------------------------------------------------------------------------
/test/resources/functional_tests/exit_codes/with_issues.py:
--------------------------------------------------------------------------------
1 | a, b, c = (input(),input(),input())
2 | print(f'{a} {b} {c}')
3 |
4 | print('1', '2', '3', sep = '|')
5 |
6 | result = int(a)+10
7 | print(result)
--------------------------------------------------------------------------------
/test/resources/functional_tests/file_or_project/file.py:
--------------------------------------------------------------------------------
1 | def grade(score, max_score):
2 | return score * 100 / max_score
3 |
4 |
5 | score = int(input())
6 | max_score = int(input())
7 |
8 | grade(score, max_score)
--------------------------------------------------------------------------------
/test/resources/functional_tests/file_or_project/project/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/test/resources/functional_tests/file_or_project/project/__init__.py
--------------------------------------------------------------------------------
/test/resources/functional_tests/file_or_project/project/one.py:
--------------------------------------------------------------------------------
1 | from other import do_something_useless
2 |
3 | if __name__ == '__main__':
4 | do_something_useless()
--------------------------------------------------------------------------------
/test/resources/functional_tests/file_or_project/project/other.py:
--------------------------------------------------------------------------------
1 | def do_something_useless():
2 | a = 1
3 | b = 2
4 | c = 3
--------------------------------------------------------------------------------
/test/resources/functional_tests/file_or_project/project_with_unknown_extensions/file.abc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/test/resources/functional_tests/file_or_project/project_with_unknown_extensions/file.abc
--------------------------------------------------------------------------------
/test/resources/functional_tests/file_or_project/project_with_unknown_extensions/file.py:
--------------------------------------------------------------------------------
1 | def FunctionWithIssue():
2 | pass
3 |
4 | answer = 42
5 | print(answer)
6 |
--------------------------------------------------------------------------------
/test/resources/functional_tests/file_or_project/project_with_unknown_extensions/file.xyz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/test/resources/functional_tests/file_or_project/project_with_unknown_extensions/file.xyz
--------------------------------------------------------------------------------
/test/resources/functional_tests/lines_range/code_with_multiple_issues.py:
--------------------------------------------------------------------------------
1 | a=10
2 | b=20
3 | print(b)
4 | c=a + b
5 | print(c)
6 |
--------------------------------------------------------------------------------
/test/resources/functional_tests/verbosity/some_code.py:
--------------------------------------------------------------------------------
1 |
2 | def fun(param):
3 | a = 10
4 | b = 20
5 | c = 30
6 | print(c)
7 | d = 40
8 |
--------------------------------------------------------------------------------
/test/resources/inspectors/checkstyle/empty_file.xml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/test/resources/inspectors/checkstyle/empty_file.xml
--------------------------------------------------------------------------------
/test/resources/inspectors/checkstyle/issues/BooleanExpressionComplexityCheck.java:
--------------------------------------------------------------------------------
1 | class ComplexBooleanExpression {
2 | public static void main(String[] args) {
3 | Scanner scanner = new Scanner(System.in);
4 |
5 | int a = scanner.nextInt();
6 | int b = scanner.nextInt();
7 | int c = scanner.nextInt();
8 | int d = scanner.nextInt();
9 |
10 | if (a > b && a > b && a > c && a > d) {
11 | System.out.println("'a' is the largest");
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/test/resources/inspectors/checkstyle/issues/CyclomaticComplexityCheck.java:
--------------------------------------------------------------------------------
1 | class ComplexBooleanExpression {
2 | public static void main(String[] args) {
3 | Scanner scanner = new Scanner(System.in);
4 |
5 | int a = scanner.nextInt();
6 | int b = scanner.nextInt();
7 | int c = scanner.nextInt();
8 | int d = scanner.nextInt();
9 |
10 | if (a > b) {
11 | if (a > c) {
12 | if (a > d) {
13 | System.out.println("'a' is the largest");
14 | }
15 | }
16 | }
17 |
18 | if (b > a) {
19 | if (b > c) {
20 | if (b > d) {
21 | System.out.println("'b' is the largest");
22 | }
23 | }
24 | }
25 |
26 | if (c > a) {
27 | if (c > b) {
28 | if (c > d) {
29 | System.out.println("'c' is the largest");
30 | }
31 | }
32 | }
33 |
34 | if (d > a) {
35 | if (d > b) {
36 | if (d > c) {
37 | System.out.println("'d' is the largest");
38 | }
39 | }
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/test/resources/inspectors/checkstyle/issues/JavaNCSSCheck.java:
--------------------------------------------------------------------------------
1 | class LongHelloWorld {
2 | public static void main(String[] args) {
3 | System.out.println("H");
4 | System.out.println("e");
5 | System.out.println("l");
6 | System.out.println("l");
7 | System.out.println("o");
8 | System.out.println(",");
9 | System.out.println(" ");
10 | System.out.println("W");
11 | System.out.println("o");
12 | System.out.println("r");
13 | System.out.println("l");
14 | System.out.println("d");
15 | System.out.println("!");
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/test/resources/inspectors/checkstyle/issues/LineLengthCheck.java:
--------------------------------------------------------------------------------
1 | class LongLine {
2 | public static void main(String[] args) {
3 | System.out.println("Wow! This line is soooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo long...");
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/test/resources/inspectors/checkstyle/issues/MagicNumberCheck.java:
--------------------------------------------------------------------------------
1 | class ComplexBooleanExpression {
2 | public static void main(String[] args) {
3 | System.out.println(42);
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/test/resources/inspectors/checkstyle/multi_file_project_with_metric_issues.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
8 |
9 |
10 |
12 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/test/resources/inspectors/checkstyle/multi_file_project_without_issues.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/test/resources/inspectors/checkstyle/multi_file_project_without_metric_issues.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
9 |
10 |
11 |
14 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/test/resources/inspectors/checkstyle/single_file_project_with_metric_issues.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
8 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/test/resources/inspectors/checkstyle/single_file_project_without_issues.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/test/resources/inspectors/checkstyle/single_file_project_without_metric_issues.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/test/resources/inspectors/detekt/issues/ComplexCondition.kt:
--------------------------------------------------------------------------------
1 | fun main() {
2 | val a = readLine()?.toInt() ?: 0
3 | val b = readLine()?.toInt() ?: 0
4 | val c = readLine()?.toInt() ?: 0
5 | val d = readLine()?.toInt() ?: 0
6 |
7 | if (a > b && a > b && a > c && a > d) {
8 | println(a)
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/resources/inspectors/detekt/issues/ComplexMethod.kt:
--------------------------------------------------------------------------------
1 | fun main() {
2 | val a = readLine()?.toInt() ?: 0
3 | val b = readLine()?.toInt() ?: 0
4 | val c = readLine()?.toInt() ?: 0
5 | val d = readLine()?.toInt() ?: 0
6 |
7 | if (a > b) {
8 | if (a > c) {
9 | if (a > d) {
10 | println("'a' is the largest");
11 | }
12 | }
13 | }
14 |
15 | if (b > a) {
16 | if (b > c) {
17 | if (b > d) {
18 | println("'b' is the largest");
19 | }
20 | }
21 | }
22 |
23 | if (c > a) {
24 | if (c > b) {
25 | if (c > d) {
26 | println("'c' is the largest");
27 | }
28 | }
29 | }
30 |
31 | if (d > a) {
32 | if (d > b) {
33 | if (d > c) {
34 | println("'d' is the largest");
35 | }
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/test/resources/inspectors/detekt/issues/LongMethod.kt:
--------------------------------------------------------------------------------
1 | fun main() {
2 | println("H")
3 | println("e")
4 | println("l")
5 | println("l")
6 | println("o")
7 | println(",")
8 | println(" ")
9 | println("W")
10 | println("o")
11 | println("r")
12 | println("l")
13 | println("d")
14 | println("!")
15 | }
16 |
--------------------------------------------------------------------------------
/test/resources/inspectors/detekt/issues/MagicNumber.kt:
--------------------------------------------------------------------------------
1 | fun main() {
2 | println(42)
3 | }
4 |
--------------------------------------------------------------------------------
/test/resources/inspectors/eslint/issues/complexity.js:
--------------------------------------------------------------------------------
1 | function complexFunction(a, b, c, d) {
2 | if (a > b) {
3 | if (a > c) {
4 | if (a > d) {
5 | console.log("'a' is the largest!")
6 | }
7 | }
8 | }
9 |
10 | if (b > a) {
11 | if (b > c) {
12 | if (b > d) {
13 | console.log("'b' is the largest!")
14 | }
15 | }
16 | }
17 |
18 | if (c > a) {
19 | if (c > b) {
20 | if (c > d) {
21 | console.log("'c' is the largest!")
22 | }
23 | }
24 | }
25 |
26 | if (d > a) {
27 | if (d > b) {
28 | if (d > c) {
29 | console.log("'d' is the largest!")
30 | }
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/test/resources/inspectors/flake8/issues/b007.py:
--------------------------------------------------------------------------------
1 | n = int(input())
2 | for i in range(n):
3 | print(n)
4 |
--------------------------------------------------------------------------------
/test/resources/inspectors/flake8/issues/c901.py:
--------------------------------------------------------------------------------
1 | def main():
2 | n = int(input())
3 | if n > 0:
4 | print(f'{n} > 0')
5 | elif n < 0:
6 | print(f'{n} < 0')
7 | else:
8 | print(f'{n} = 0')
9 |
--------------------------------------------------------------------------------
/test/resources/inspectors/flake8/issues/e501.py:
--------------------------------------------------------------------------------
1 | def main():
2 | n = input()
3 | if len(n) > 120:
4 | print('Wow! This is such a looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong line.')
5 |
--------------------------------------------------------------------------------
/test/resources/inspectors/flake8/issues/h601.py:
--------------------------------------------------------------------------------
1 | class Foo:
2 | def __init__(self, a: int, b: int):
3 | self.a = a
4 | self.b = b
5 |
--------------------------------------------------------------------------------
/test/resources/inspectors/flake8/issues/wps350.py:
--------------------------------------------------------------------------------
1 | x = int(input())
2 | x = x * x
3 |
--------------------------------------------------------------------------------
/test/resources/inspectors/flake8/issues/wps432.py:
--------------------------------------------------------------------------------
1 | print(42)
2 |
--------------------------------------------------------------------------------
/test/resources/inspectors/go/case0_empty.go:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/test/resources/inspectors/go/case0_empty.go
--------------------------------------------------------------------------------
/test/resources/inspectors/go/case10_gocritic_issues.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | // gocritic-switchTrue
7 | switch true {
8 | case true:
9 | fmt.Println("Hello, True!")
10 | case false:
11 | fmt.Println("Hello, False!")
12 | default:
13 | fmt.Println("Hello, default!")
14 | }
15 |
16 | // gocritic-newDeref
17 | x := *new(int)
18 |
19 | // gocritic-assignOP
20 | x = x * 2
21 |
22 | fmt.Println(x)
23 | }
24 |
--------------------------------------------------------------------------------
/test/resources/inspectors/go/case11_gosimple_issues.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | // gosimple-S1006
7 | for true {
8 | fmt.Println("I am an infinity loop.")
9 | }
10 |
11 | var input string
12 | _, _ = fmt.Scan(&input)
13 |
14 | // gosimple-S1039
15 | input = fmt.Sprintf("My name is Jeff.")
16 |
17 | // gosimple-S1029
18 | for _, r := range []rune(input) {
19 | fmt.Println(r)
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/test/resources/inspectors/go/case12_stylecheck_issues.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | var input int
7 | _, _ = fmt.Scan(&input)
8 |
9 | // stylecheck-ST1017
10 | if 1 == input {
11 | fmt.Println("input == 1")
12 | }
13 |
14 | // stylecheck-ST1015
15 | switch {
16 | case input > 0:
17 | fmt.Println("input > 0")
18 | default:
19 | fmt.Println("input == 0")
20 | case input < 0:
21 | fmt.Println("input < 0")
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/test/resources/inspectors/go/case13_staticcheck_issues.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "strings"
6 | )
7 |
8 | // staticcheck-SA4026
9 | const TEST = -0.0
10 |
11 | func main() {
12 | fmt.Println(TEST)
13 |
14 | // staticcheck-SA4013
15 | if !!true {
16 | fmt.Println("Not true.")
17 | } else {
18 | fmt.Println("Not not true.")
19 | }
20 |
21 | // staticcheck-SA1018
22 | fmt.Println(strings.Replace("Hello, World!", "l", "", 0))
23 | }
24 |
--------------------------------------------------------------------------------
/test/resources/inspectors/go/case14_whitespace.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func printHelloWorld() {
6 |
7 |
8 | fmt.Println("Hello, world!")
9 |
10 |
11 | }
12 |
13 |
14 |
15 |
16 |
17 | func main() {
18 |
19 |
20 |
21 | printHelloWorld()
22 |
23 |
24 |
25 |
26 | }
27 |
28 |
--------------------------------------------------------------------------------
/test/resources/inspectors/go/case15_deadcode.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | var unusedVar int
6 |
7 | func unusedFunction() {
8 |
9 | }
10 |
11 | func factorial(n int) int {
12 | if n == 0 {
13 | return 1
14 | }
15 |
16 | return n * factorial(n-1)
17 | }
18 |
19 | func main() {
20 | fmt.Println("Hello, world!")
21 | }
22 |
--------------------------------------------------------------------------------
/test/resources/inspectors/go/case16_errcheck.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "errors"
5 | "fmt"
6 | "io/ioutil"
7 | )
8 |
9 | func returnError() error {
10 | return errors.New("empty name")
11 | }
12 |
13 | func main() {
14 | fmt.Println("Ignoring error")
15 |
16 | returnError()
17 | _ = returnError()
18 |
19 | ioutil.ReadFile("test.go")
20 | content, _ := ioutil.ReadFile("test.go")
21 |
22 | var someInterface interface{}
23 | stringInterface1 := someInterface.(string)
24 | stringInterface1 = someInterface.(string)
25 |
26 | stringInterface2, _ := someInterface.(string)
27 | stringInterface2, _ = someInterface.(string)
28 |
29 | fmt.Println(content, stringInterface1, stringInterface2)
30 | }
31 |
--------------------------------------------------------------------------------
/test/resources/inspectors/go/case17_magic_numbers.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func printNumber(number int) {
6 | fmt.Println(number)
7 | }
8 |
9 | func main() {
10 | printNumber(42)
11 |
12 | var input int
13 | fmt.Scan(&input)
14 |
15 | if input == 1 {
16 | printNumber(input)
17 | }
18 |
19 | switch input {
20 | case 0:
21 | printNumber(input)
22 | case 1:
23 | printNumber(input)
24 | case 2:
25 | printNumber(input)
26 | case 3:
27 | printNumber(input)
28 | default:
29 | fmt.Println("I don't want to print this number!")
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/test/resources/inspectors/go/case18_generics.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func generic_sum[K comparable, V int | float64](m map[K]V) V {
6 | var s V
7 | for _, v := range m {
8 | s += v
9 | }
10 | return s
11 | }
12 |
13 | func main() {
14 | fmt.Println(generic_sum(map[string]int{"first": 42, "second": 69}))
15 | fmt.Println(generic_sum(map[string]float64{"first": 42.69, "second": 69.42}))
16 | }
17 |
--------------------------------------------------------------------------------
/test/resources/inspectors/go/case1_simple_valid_program.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | fmt.Println("Hello, World!")
7 | }
8 |
--------------------------------------------------------------------------------
/test/resources/inspectors/go/case2_program_with_syntax_errors.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "fmt"
6 | )
7 |
8 | func main() {
9 | a := 42
10 | fmt.Println("Hello, World!")
11 | }
12 |
--------------------------------------------------------------------------------
/test/resources/inspectors/go/case3_issues_with_related_information.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func hello(name string) {
6 | name = "Jerry" // staticcheck-SA4009
7 | fmt.Printf("Hello, %s!", name)
8 | }
9 |
10 | func main() {
11 | hello("Teddy")
12 | }
13 |
--------------------------------------------------------------------------------
/test/resources/inspectors/go/case4_cyclomatic_complexity.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func plus(number int, bias int) int {
6 | if number == 0 && bias == 0 {
7 | return 0
8 | }
9 |
10 | if number == 0 && bias == 1 {
11 | return 1
12 | }
13 |
14 | if number == 0 && bias == 2 {
15 | return 2
16 | }
17 |
18 | if number == 1 && bias == 0 {
19 | return 1
20 | }
21 |
22 | if number == 1 && bias == 1 {
23 | return 2
24 | }
25 |
26 | if number == 1 && bias == 2 {
27 | return 3
28 | }
29 |
30 | if number == 2 && bias == 0 {
31 | return 2
32 | }
33 |
34 | if number == 2 && bias == 1 {
35 | return 3
36 | }
37 |
38 | if number == 2 && bias == 2 {
39 | return 4
40 | }
41 |
42 | return -1
43 | }
44 |
45 | func main() {
46 | fmt.Println(plus(1, 1))
47 | }
48 |
--------------------------------------------------------------------------------
/test/resources/inspectors/go/case5_function_length.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func printNumbersFrom0To99() {
6 | fmt.Println(0)
7 | fmt.Println(1)
8 | fmt.Println(2)
9 | fmt.Println(3)
10 | fmt.Println(4)
11 | fmt.Println(5)
12 | fmt.Println(6)
13 | fmt.Println(7)
14 | fmt.Println(8)
15 | fmt.Println(9)
16 | fmt.Println(10)
17 | fmt.Println(11)
18 | fmt.Println(12)
19 | fmt.Println(13)
20 | fmt.Println(14)
21 | fmt.Println(15)
22 | fmt.Println(16)
23 | fmt.Println(17)
24 | fmt.Println(18)
25 | fmt.Println(19)
26 | fmt.Println(20)
27 | fmt.Println(21)
28 | fmt.Println(22)
29 | fmt.Println(23)
30 | fmt.Println(24)
31 | fmt.Println(25)
32 | fmt.Println(26)
33 | fmt.Println(27)
34 | fmt.Println(28)
35 | fmt.Println(29)
36 | fmt.Println(30)
37 | fmt.Println(31)
38 | fmt.Println(32)
39 | fmt.Println(33)
40 | fmt.Println(34)
41 | fmt.Println(35)
42 | fmt.Println(36)
43 | fmt.Println(37)
44 | fmt.Println(38)
45 | fmt.Println(39)
46 | fmt.Println(40)
47 | fmt.Println(41)
48 | fmt.Println(42)
49 | fmt.Println(43)
50 | fmt.Println(44)
51 | fmt.Println(45)
52 | fmt.Println(46)
53 | fmt.Println(47)
54 | fmt.Println(48)
55 | fmt.Println(49)
56 | fmt.Println(50)
57 | fmt.Println(51)
58 | fmt.Println(52)
59 | fmt.Println(53)
60 | fmt.Println(54)
61 | fmt.Println(55)
62 | fmt.Println(56)
63 | fmt.Println(57)
64 | fmt.Println(58)
65 | fmt.Println(59)
66 | fmt.Println(60)
67 | fmt.Println(61)
68 | fmt.Println(62)
69 | fmt.Println(63)
70 | fmt.Println(64)
71 | fmt.Println(65)
72 | fmt.Println(66)
73 | fmt.Println(67)
74 | fmt.Println(68)
75 | fmt.Println(69)
76 | fmt.Println(70)
77 | fmt.Println(71)
78 | fmt.Println(72)
79 | fmt.Println(73)
80 | fmt.Println(74)
81 | fmt.Println(75)
82 | fmt.Println(76)
83 | fmt.Println(77)
84 | fmt.Println(78)
85 | fmt.Println(79)
86 | fmt.Println(80)
87 | fmt.Println(81)
88 | fmt.Println(82)
89 | fmt.Println(83)
90 | fmt.Println(84)
91 | fmt.Println(85)
92 | fmt.Println(86)
93 | fmt.Println(87)
94 | fmt.Println(88)
95 | fmt.Println(89)
96 | fmt.Println(90)
97 | fmt.Println(91)
98 | fmt.Println(92)
99 | fmt.Println(93)
100 | fmt.Println(94)
101 | fmt.Println(95)
102 | fmt.Println(96)
103 | fmt.Println(97)
104 | fmt.Println(98)
105 | fmt.Println(99)
106 | }
107 |
108 | func main() {
109 | printNumbersFrom0To99()
110 | }
111 |
--------------------------------------------------------------------------------
/test/resources/inspectors/go/case6_line_length.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func printVeryLongLine() {
6 | fmt.Println("Wow! This line is soooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo long.")
7 | }
8 |
9 | func main() {
10 | printVeryLongLine()
11 | }
12 |
--------------------------------------------------------------------------------
/test/resources/inspectors/go/case8_govet_issues.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "bytes"
5 | "fmt"
6 | )
7 |
8 | func main() {
9 | // govet-printf
10 | fmt.Printf("%b", "Hello!")
11 |
12 | // govet-unusedresult
13 | var buf bytes.Buffer
14 | buf.String()
15 |
16 | return
17 |
18 | // govet-unreachable
19 | fmt.Print("Unreachable!")
20 | }
21 |
--------------------------------------------------------------------------------
/test/resources/inspectors/go/case9_revive_issues.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | // revive-var-naming
7 | var this_is_int int
8 | _, _ = fmt.Scan(&this_is_int)
9 |
10 | // revive-bool-literal-in-expr and revive-identical-branches
11 | if this_is_int > 0 && true {
12 | fmt.Println("this_is_int > 0")
13 | } else {
14 | fmt.Println("this_is_int > 0")
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/test/resources/inspectors/golang_lint/empty_file.json:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/test/resources/inspectors/golang_lint/empty_file.json
--------------------------------------------------------------------------------
/test/resources/inspectors/golang_lint/issues/cyclop.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | var a int
7 | var b int
8 | var c int
9 | var d int
10 |
11 | fmt.Scan(&a)
12 | fmt.Scan(&b)
13 | fmt.Scan(&c)
14 | fmt.Scan(&d)
15 |
16 | if a > b {
17 | if a > c {
18 | if a > d {
19 | fmt.Println("'a' is the largest.")
20 | }
21 | }
22 | }
23 |
24 | if b > a {
25 | if b > c {
26 | if b > d {
27 | fmt.Println("'b' is the largest.")
28 | }
29 | }
30 | }
31 |
32 | if c > a {
33 | if c > b {
34 | if c > d {
35 | fmt.Println("'c' is the largest.")
36 | }
37 | }
38 | }
39 |
40 | if d > a {
41 | if d > b {
42 | if d > c {
43 | fmt.Println("'d' is the largest.")
44 | }
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/test/resources/inspectors/golang_lint/issues/funlen.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | fmt.Println("H")
7 | fmt.Println("e")
8 | fmt.Println("l")
9 | fmt.Println("l")
10 | fmt.Println("o")
11 | fmt.Println(",")
12 | fmt.Println(" ")
13 | fmt.Println("W")
14 | fmt.Println("o")
15 | fmt.Println("r")
16 | fmt.Println("l")
17 | fmt.Println("d")
18 | fmt.Println("!")
19 | }
20 |
--------------------------------------------------------------------------------
/test/resources/inspectors/golang_lint/issues/gomnd.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | fmt.Print(42)
7 | }
8 |
--------------------------------------------------------------------------------
/test/resources/inspectors/golang_lint/issues/lll.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | fmt.Println("Wow! This line is soooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo long...")
7 | }
8 |
--------------------------------------------------------------------------------
/test/resources/inspectors/golang_lint/issues/maintidx.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | var a int
7 | var b int
8 | var operator string
9 |
10 | fmt.Scan(&a)
11 | fmt.Scan(&b)
12 | fmt.Scan(&operator)
13 |
14 | if operator == "+" {
15 | if a == 0 && b == 0 {
16 | fmt.Print(0)
17 | } else if a == 0 && b == 1 {
18 | fmt.Print(1)
19 | } else if a == 0 && b == 2 {
20 | fmt.Print(2)
21 | } else if a == 1 && b == 0 {
22 | fmt.Print(1)
23 | } else if a == 1 && b == 1 {
24 | fmt.Print(2)
25 | } else if a == 1 && b == 2 {
26 | fmt.Print(3)
27 | } else if a == 2 && b == 0 {
28 | fmt.Print(2)
29 | } else if a == 2 && b == 1 {
30 | fmt.Print(3)
31 | } else if a == 2 && b == 2 {
32 | fmt.Print(4)
33 | } else {
34 | fmt.Print("I don't known :(")
35 | }
36 | } else if operator == "-" {
37 | if a == 0 && b == 0 {
38 | fmt.Print(0)
39 | } else if a == 0 && b == 1 {
40 | fmt.Print(-1)
41 | } else if a == 0 && b == 2 {
42 | fmt.Print(-2)
43 | } else if a == 1 && b == 0 {
44 | fmt.Print(1)
45 | } else if a == 1 && b == 1 {
46 | fmt.Print(0)
47 | } else if a == 1 && b == 2 {
48 | fmt.Print(-1)
49 | } else if a == 2 && b == 0 {
50 | fmt.Print(2)
51 | } else if a == 2 && b == 1 {
52 | fmt.Print(1)
53 | } else if a == 2 && b == 2 {
54 | fmt.Print(0)
55 | } else {
56 | fmt.Print("I don't know :(")
57 | }
58 | } else if operator == "*" {
59 | if a == 0 && b == 0 {
60 | fmt.Print(0)
61 | } else if a == 0 && b == 1 {
62 | fmt.Print(0)
63 | } else if a == 0 && b == 2 {
64 | fmt.Print(0)
65 | } else if a == 1 && b == 0 {
66 | fmt.Print(0)
67 | } else if a == 1 && b == 1 {
68 | fmt.Print(1)
69 | } else if a == 1 && b == 2 {
70 | fmt.Print(2)
71 | } else if a == 2 && b == 0 {
72 | fmt.Print(0)
73 | } else if a == 2 && b == 1 {
74 | fmt.Print(2)
75 | } else if a == 2 && b == 2 {
76 | fmt.Print(4)
77 | } else {
78 | fmt.Print("I don't know :(")
79 | }
80 | } else if operator == "/" {
81 | if a == 0 && b == 0 {
82 | fmt.Print("I don't know :(")
83 | } else if a == 0 && b == 1 {
84 | fmt.Print(0)
85 | } else if a == 0 && b == 2 {
86 | fmt.Print(0)
87 | } else if a == 1 && b == 0 {
88 | fmt.Print("o_0")
89 | } else if a == 1 && b == 1 {
90 | fmt.Print(1)
91 | } else if a == 1 && b == 2 {
92 | fmt.Print(1 / 2)
93 | } else if a == 2 && b == 0 {
94 | fmt.Print(0)
95 | } else if a == 2 && b == 1 {
96 | fmt.Print(2)
97 | } else if a == 2 && b == 2 {
98 | fmt.Print(1)
99 | } else {
100 | fmt.Print("I don't know :(")
101 | }
102 | } else {
103 | fmt.Print("I don't know :(")
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/test/resources/inspectors/golang_lint/multi_file_project_without_issues.json:
--------------------------------------------------------------------------------
1 | {
2 | "Issues": []
3 | }
4 |
--------------------------------------------------------------------------------
/test/resources/inspectors/golang_lint/single_file_project_without_issues.json:
--------------------------------------------------------------------------------
1 | {
2 | "Issues": []
3 | }
4 |
--------------------------------------------------------------------------------
/test/resources/inspectors/intellij_output/test.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | file://$PROJECT_DIR$/python_sources/test.py
4 | 8
5 | python_sources
6 | <default>
7 |
8 | Unnecessary parentheses
9 | description_1
10 |
11 |
12 | file://$PROJECT_DIR$/python_sources/test.py
13 | 9
14 | python_sources
15 | <default>
16 |
17 | Overly complex boolean expression
18 | description_2
19 |
20 |
21 | file://$PROJECT_DIR$/python_sources/test.py
22 | 10
23 | python_sources
24 | <default>
25 |
26 | Wrong arguments to call super
27 | description_3
28 |
29 |
30 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_algorithm_with_scanner.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | class Main {
4 | public static void main(String[] args) {
5 | Scanner s = new Scanner(System.in);
6 | int length = s.nextInt();
7 | int[] nums = new int[length];
8 | for (int i = 0; i < length; i++) {
9 | nums[i] = s.nextInt();
10 | }
11 | int limit = s.nextInt();
12 | int sum = 0;
13 | for (int n : nums) {
14 | if (n > limit) {
15 | sum += n;
16 | }
17 | }
18 | System.out.println(sum);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_array_type.java:
--------------------------------------------------------------------------------
1 | class HelloWorld {
2 | public static void main(String args[]) {
3 | System.out.println("Hello World!");
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_blocks.java:
--------------------------------------------------------------------------------
1 | class HelloWorld {
2 | public static void main(String[] args) {
3 | try {
4 | System.out.println("Hello World!");
5 | } catch (Exception e) {
6 | }
7 |
8 | if (0 < 1) int i = 0;
9 | else { int i = 1; }
10 |
11 | for (i = 0; i < 1; i++)
12 | System.out.println("Hello World Again!");
13 |
14 | {
15 | int i = 1;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_boolean_expr.java:
--------------------------------------------------------------------------------
1 | import java.util.Scanner;
2 |
3 | class BooleanExpressions {
4 |
5 | public static void main(String[] args) {
6 | Scanner scanner = new Scanner(System.in);
7 |
8 | int a = scanner.nextInt();
9 | int b = scanner.nextInt();
10 | int c = scanner.nextInt();
11 | int d = scanner.nextInt();
12 |
13 | if (a > b) { // ok
14 | System.out.println("a > b");
15 | }
16 |
17 | if (a > b && a > b) { // duplicated
18 | System.out.println("a > b again");
19 | }
20 |
21 | if (a > b && a < d) {
22 | System.out.println("b < a < d");
23 | }
24 |
25 | if (a > b && true) { // should be simplified
26 | System.out.println("a > b > c");
27 | }
28 |
29 | process(a, b, c, d);
30 | }
31 |
32 | private static void process(int a, int b, int c, int d) {
33 | boolean enabled = false;
34 | if (a > b && b < c && c > d || c < a && enabled) {
35 | System.out.println("Too complex");
36 | }
37 |
38 | for (int i = 0; i < 10; i++) {
39 | System.out.println(getValue(i));
40 | }
41 | }
42 |
43 | private static boolean getValue(int i) {
44 | if (i < 1) {
45 | return true;
46 | } else {
47 | return false;
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_builder.java:
--------------------------------------------------------------------------------
1 | import java.util.ArrayList;
2 | import java.util.List;
3 | import java.util.Scanner;
4 |
5 | class Geek {
6 |
7 | private String type;
8 | private List languages;
9 | private int experience;
10 |
11 | Geek(String type, List languages, int experience) {
12 | this.type = type;
13 | this.languages = languages;
14 | this.experience = experience;
15 | }
16 |
17 | public static class GeekBuilder {
18 |
19 | private String type;
20 | private List languages;
21 | private int experience;
22 |
23 | public GeekBuilder setType(String type) {
24 | this.type = type;
25 | return this;
26 | }
27 |
28 | public GeekBuilder setLanguages(List languages) {
29 | this.languages = languages;
30 | return this;
31 | }
32 |
33 | public GeekBuilder setExperience(int experience) {
34 | this.experience = experience;
35 | return this;
36 | }
37 |
38 | public Geek build() {
39 | return new Geek(type, languages, experience);
40 | }
41 | }
42 |
43 | public String toString() {
44 | return "Type : " + type + "\n" +
45 | "Languages : " + languages + "\n" +
46 | "Experience : " + experience + " years";
47 | }
48 | }
49 |
50 | class TestDrive {
51 | public static void main(String[] args) {
52 | final Scanner scanner = new Scanner(System.in);
53 | final String geekName = scanner.nextLine();
54 | scanner.close();
55 | System.out.println("Geek " + geekName + " created.");
56 |
57 | Geek geek = new Geek.GeekBuilder()
58 | .setType("Admin")
59 | .setLanguages(new ArrayList<>() {{
60 | add("Perl");
61 | add("PowerShell");
62 | }})
63 | .setExperience(10)
64 | .build();
65 |
66 | System.out.println(geek);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_class_with_booleans.java:
--------------------------------------------------------------------------------
1 | class ClassWithBooleans {
2 | private boolean enabled = true;
3 | private boolean isTyped = true;
4 | private boolean count = false;
5 | private boolean correct = true;
6 | private int isValid = 1;
7 |
8 | public boolean getEnabled() {
9 | return enabled;
10 | }
11 |
12 | public boolean isTyped() {
13 | return isTyped;
14 | }
15 |
16 | public boolean getCount() {
17 | return count;
18 | }
19 |
20 | public boolean isEnabled() {
21 | return enabled;
22 | }
23 |
24 | public boolean isCount() {
25 | return count;
26 | }
27 |
28 | public boolean isCorrect() {
29 | return correct;
30 | }
31 |
32 | public int getIsValid() {
33 | return isValid;
34 | }
35 |
36 |
37 | public static void main(String[] args) {
38 | ClassWithBooleans object = new ClassWithBooleans();
39 | System.out.println(object.isTyped());
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_closing_streams.java:
--------------------------------------------------------------------------------
1 | import java.io.FileInputStream;
2 | import java.io.IOException;
3 | import java.io.InputStream;
4 |
5 | class TryWithResourcesExample {
6 | private static final String FILE_NAME = "test.java";
7 |
8 | public static void main(String[] args) {
9 | InputStream in = null;
10 | try {
11 | in = new FileInputStream(FILE_NAME);
12 | System.out.println(in.read());
13 | } catch (IOException e) {
14 | System.out.println(e.getMessage());
15 | } finally {
16 | try {
17 | if (in != null) {
18 | in.close();
19 | }
20 | } catch (IOException ignored) {
21 | // ignored
22 | }
23 | }
24 |
25 | // better use try-with-resources
26 | try (InputStream in2 = new FileInputStream(FILE_NAME)) {
27 | System.out.println(in2.read());
28 | } catch (IOException e) {
29 | System.out.println(e.getMessage());
30 | }
31 |
32 | try {
33 | InputStream in3 = new FileInputStream(FILE_NAME);
34 | System.out.println(in3.read());
35 | } catch (IOException e) {
36 | System.out.print(e.getMessage());
37 | // it will be good to check closing
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_code_with_comments.java:
--------------------------------------------------------------------------------
1 | import java.util.Scanner;
2 |
3 | class CodeWithCommentsExample {
4 |
5 | public static void main(String[] args) {
6 | Scanner scanner = new Scanner(System.in);
7 |
8 | int a = scanner.nextInt();
9 | a += 20;
10 | // a += 30
11 | // a += 40
12 | System.out.print(a); // good
13 |
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_comparing_strings.java:
--------------------------------------------------------------------------------
1 | import java.util.Scanner;
2 |
3 | class ComparingStrings {
4 |
5 | public static void main(String[] args) {
6 | Scanner scanner = new Scanner(System.in);
7 | String line = scanner.nextLine();
8 |
9 | System.out.println(line == "Hello");
10 | System.out.println(line.equalsIgnoreCase("Hello, World"));
11 | System.out.println(line.equals("World"));
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_constants.java:
--------------------------------------------------------------------------------
1 | class MyClass {
2 | static final int log = 10; // OK
3 | static final int logger = 50; // OK
4 | static final int logMYSELF = 10; // violation
5 | static final int loggerMYSELF = 5; // violation
6 | static final int MYSELF = 100; // OK
7 | static final int myselfConstant = 1; // violation
8 | static final long serialVersionUID = 1L; // OK
9 | static final long thingCost = 400L; // violation
10 | }
11 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_covariant_equals.java:
--------------------------------------------------------------------------------
1 | import java.util.Objects;
2 |
3 | class Device {
4 | private String name;
5 | private String model;
6 |
7 | public boolean equals(Device device) {
8 | return Objects.equals(name, device.name)
9 | && Objects.equals(model, device.model);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_curly_braces.java:
--------------------------------------------------------------------------------
1 | import java.util.Scanner;
2 |
3 | class HelloWorld {
4 | public static void main(String[] args) {
5 | for (int i = 0; i < args[0].length(); i++)
6 | System.out.println("Hello World!");
7 |
8 | Scanner scanner = new Scanner(System.in);
9 | int num = scanner.nextInt();
10 | int counter = 0;
11 |
12 | switch (num) {
13 | case 1:
14 | counter++;
15 | break; // OK
16 | case 6:
17 | counter += 10;
18 | break; // OK
19 | default:
20 | counter = 100;
21 | break; // OK
22 | }
23 |
24 | for (int i = 0; i < 10; i++) System.out.println(i);
25 |
26 | System.out.println(counter);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_double_checked_locking.java:
--------------------------------------------------------------------------------
1 | // Broken multithreaded version
2 | class Helper {
3 | private Helper helper;
4 |
5 | public Helper getHelper() {
6 | if (helper == null) {
7 | synchronized (this) {
8 | if (helper == null) {
9 | helper = new Helper();
10 | }
11 | }
12 | }
13 | return helper;
14 | }
15 |
16 | // other functions and members...
17 | }
18 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_empty_line_separator.java:
--------------------------------------------------------------------------------
1 |
2 | public class QQMain {
3 |
4 | public static void main(String[] args) {
5 | System.out.println("SADASD");
6 | }
7 | public static void f() {
8 | System.out.println("ASDS");
9 | }
10 | }
11 | class Application {
12 |
13 | String name;
14 |
15 | public void run(String[] args) {
16 | System.out.println(name);
17 |
18 | for (String arg : args) {
19 | System.out.println(arg);
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_empty_lines_btw_members.java:
--------------------------------------------------------------------------------
1 | class ClassWithMembers {
2 | private static final int LIGHT_SPEED = 3 * 100_000_000;
3 | private static final double PI = 3.1415;
4 |
5 | private final String msg;
6 | private final int cost = 10;
7 | ClassWithMembers(String msg) {
8 | this.msg = msg;
9 | }
10 | public String getMsg() {
11 | return msg;
12 | }
13 |
14 | public int getCost() {
15 | return cost;
16 | }
17 |
18 | public static void main(String[] args) {
19 | ClassWithMembers instance = new ClassWithMembers("Hello");
20 | System.out.println(instance.getMsg());
21 | System.out.println(instance.getCost());
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_for_loop.java:
--------------------------------------------------------------------------------
1 | import java.util.List;
2 |
3 | class ForLoopExample {
4 |
5 | public static void main(String[] args) {
6 | List numbers = List.of(1, 2, 3, 4, 5);
7 | for (int n : numbers) {
8 | System.out.println(n);
9 | }
10 |
11 | for (int i = 0; i < numbers.size(); i++) {
12 | System.out.println(numbers.get(i));
13 | }
14 |
15 | for (int i = 0, j = 0, k = 0; i < 10; i++, j++, k++) {
16 | System.out.println(i + j + k);
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_implementation_types.java:
--------------------------------------------------------------------------------
1 | import java.util.ArrayList;
2 | import java.util.HashSet;
3 |
4 | class Main {
5 |
6 | public static void main(String[] args) {
7 | ArrayList words = new ArrayList<>();
8 |
9 | words.add("first");
10 | words.add("second");
11 | words.add("third");
12 |
13 | System.out.println(words);
14 |
15 | HashSet uniqueNumbers = new HashSet<>();
16 |
17 | uniqueNumbers.add(1);
18 | uniqueNumbers.add(2);
19 | uniqueNumbers.add(3);
20 |
21 | System.out.println(uniqueNumbers);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_indentation_google_style.java:
--------------------------------------------------------------------------------
1 | // See here https://github.com/checkstyle/checkstyle/blob/master/src/main/resources/google_checks.xml
2 | public class AndroidIndentation {
3 | public static void main(String[] args) {
4 | int a = 10;
5 | int b = 20;
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_indentation_with_spaces.java:
--------------------------------------------------------------------------------
1 | import java.util.Arrays;
2 | import java.util.List;
3 |
4 | class Indentation {
5 |
6 | public static void main(String[] args) {
7 | int a = 10;
8 | int b = 20;
9 |
10 | System.out.println(a + b);
11 |
12 | var words = List.of(
13 | "Hello",
14 | "How is it going?",
15 | "Let's program!"
16 | );
17 |
18 | var numbers = Arrays.asList(
19 | 100,
20 | 200,
21 | 300
22 | );
23 |
24 | invokeMethod(words, numbers);
25 | }
26 |
27 | private static void invokeMethod(List words,
28 | List numbers) {
29 |
30 | System.out.println(words);
31 | System.out.println(numbers);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_indentation_with_tabs.java:
--------------------------------------------------------------------------------
1 | import java.util.Arrays;
2 | import java.util.List;
3 |
4 | class Indentation {
5 |
6 | public static void main(String[] args) {
7 | int a = 10;
8 | int b = 20;
9 |
10 | System.out.println(a + b);
11 |
12 | var words = List.of(
13 | "Hello",
14 | "How is it going?",
15 | "Let's program!"
16 | );
17 |
18 | var numbers = Arrays.asList(
19 | 100,
20 | 200,
21 | 300
22 | );
23 |
24 | invokeMethod(words, numbers);
25 | }
26 |
27 | private static void invokeMethod(List words,
28 | List numbers) {
29 |
30 | System.out.println(words);
31 | System.out.println(numbers);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_invalid_naming.java:
--------------------------------------------------------------------------------
1 | class snake_class {
2 | private static final String text = "";
3 | private static final String anotherText = "";
4 |
5 | private String snake_field;
6 | private String CAPS_FIELD;
7 |
8 | public static void Main(String[] ARGS) {
9 | int CAPS_VAR;
10 | int snake_var;
11 | }
12 |
13 | private void snake_method(int snake_arg, int CAPS_ARG) {
14 | }
15 |
16 | private void CAPS() {
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_long_lines.java:
--------------------------------------------------------------------------------
1 | class Main {
2 |
3 | public static void main(String[] args) {
4 | System.out.println("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
5 | System.out.println("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
6 | System.out.println("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_magic_numbers.java:
--------------------------------------------------------------------------------
1 | class HelloWorld {
2 | private static final int VALUE = 123;
3 |
4 | public static void main(String[] args) {
5 | int i = 123;
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_manual_array_copy.java:
--------------------------------------------------------------------------------
1 | class Main {
2 | public static void main(String[] args) {
3 | String[] another = new String[args.length];
4 | for (int i = 0; i < args.length; i++) {
5 | another[i] = args[i];
6 | }
7 | }
8 | }
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_method_params.java:
--------------------------------------------------------------------------------
1 | class MethodsParametersExample {
2 |
3 | public static void main(String[] args) {
4 | message("Vasiliy", "Anna",
5 | "anna@gmail.com",
6 | "Hello!", "How are u?");
7 | System.out.println(calculate(10, 12, 15));
8 | }
9 |
10 | public static void message(String from, String to, String email,
11 | String header, String text) {
12 | System.out.printf("Sending from '%s' to '%s' on email '%s' " +
13 | "with header '%s' and text '%s'",
14 | from, to, email, header, text);
15 | }
16 |
17 | private static int calculate(int a, int b, int c) {
18 | return a + b;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_missing_default.java:
--------------------------------------------------------------------------------
1 | import java.util.Scanner;
2 |
3 | class HelloWorld {
4 | public static void main(String[] args) {
5 | Scanner scanner = new Scanner(System.in);
6 | int x = 1;
7 | int y = scanner.nextInt();
8 | switch (x) {
9 | case 0:
10 | y = 1;
11 | break;
12 | }
13 | System.out.println(x);
14 | System.out.println(y);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_multi_statements.java:
--------------------------------------------------------------------------------
1 | class MultistatementsPerLineExample {
2 |
3 | public static void main(String[] args) {
4 | int a = 10, b = 20;
5 | int c = 30; int result = a + b + c;
6 | System.out.println(c); System.out.println(result);
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_multiple_literals.java:
--------------------------------------------------------------------------------
1 | class Main {
2 | public static void main(String[] args) {
3 | // ok
4 | String shortRareLiteral1 = "12";
5 | String shortRareLiteral2 = "12";
6 | String shortRareLiteral3 = "12";
7 |
8 | // ok
9 | String longRareLiteral1 = "123";
10 | String longRareLiteral2 = "123";
11 | String longRareLiteral3 = "123";
12 |
13 | // ok
14 | String shortFrequentLiteral1 = "34";
15 | String shortFrequentLiteral2 = "34";
16 | String shortFrequentLiteral3 = "34";
17 | String shortFrequentLiteral4 = "34";
18 |
19 | // warning
20 | String longFrequentLiteral1 = "456";
21 | String longFrequentLiteral2 = "456";
22 | String longFrequentLiteral3 = "456";
23 | String longFrequentLiteral4 = "456";
24 |
25 | System.out.println(
26 | shortRareLiteral1 + shortRareLiteral2 + shortRareLiteral3 +
27 | longRareLiteral1 + longRareLiteral2 + longRareLiteral3 +
28 | shortFrequentLiteral1 + shortFrequentLiteral2 + shortFrequentLiteral3 + shortFrequentLiteral4 +
29 | longFrequentLiteral1 + longFrequentLiteral2 + longFrequentLiteral3 + longFrequentLiteral4
30 | );
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_nested_blocks.java:
--------------------------------------------------------------------------------
1 | class NestedBlocksExample {
2 | public static void main(String[] args) {
3 | int a = 10;
4 | {
5 | a = 20;
6 | System.out.println(a);
7 | }
8 | switch (a) {
9 | case 0:
10 | x = 1;
11 | break;
12 | case 1:
13 | // Never OK, statement outside block
14 | System.out.println("Hello 1");
15 | {
16 | x = 2;
17 | break;
18 | }
19 | case 2: {
20 | // OK if allowInSwitchCase is true
21 | System.out.println("Hello 2");
22 | x = 3;
23 | break;
24 | }
25 | default: {
26 | System.out.println("Unknown case");
27 | break;
28 | }
29 | }
30 | }
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_pattern_matching.java:
--------------------------------------------------------------------------------
1 | class Main {
2 | public static void main(String[] args)
3 | {
4 | Object obj = "TEST";
5 |
6 | if (obj instanceof String t) {
7 | System.out.println((t));
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_reassigning_example.java:
--------------------------------------------------------------------------------
1 | class ReassigningExample {
2 |
3 | public static void main(String[] args) {
4 | for (int i = 0, j = 0; i < 10; i++, j++) {
5 | i++;
6 | System.out.println(sum(i, j));
7 | }
8 | }
9 |
10 | private static int sum(int a, int b) {
11 | a = 10;
12 | return a + b;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_records.java:
--------------------------------------------------------------------------------
1 | record Book(String title, String author, String isbn) { }
2 |
3 | class OuterClass {
4 | class InnerClass {
5 | Book book = new Book("Title", "author", "isbn");
6 | }
7 | }
8 |
9 | class Main {
10 | public static void main(String[] args)
11 | {
12 | OuterClass.InnerClass a = new OuterClass.InnerClass();
13 | System.out.println((a.book));
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_sealed_classes.java:
--------------------------------------------------------------------------------
1 | package main;
2 |
3 | public sealed class Figure { }
4 |
5 | final class Circle extends Figure {
6 | float radius;
7 | }
8 | non-sealed class Square extends Figure {
9 | float side;
10 | }
11 | sealed class Rectangle extends Figure {
12 | float length, width;
13 | }
14 | final class FilledRectangle extends Rectangle {
15 | int red, green, blue;
16 | }
17 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_simple_valid_program.java:
--------------------------------------------------------------------------------
1 | class Main {
2 | public static void main(String[] args) {
3 | System.out.println("Hello World!");
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_spaces.java:
--------------------------------------------------------------------------------
1 | class HelloWorld {
2 | public static void main( String[] args) {
3 | int j=0+1;
4 | for( int i = 0; i System.out.println("Hello!"));
5 | t.run();
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_todo.java:
--------------------------------------------------------------------------------
1 | class HelloWorld {
2 | //TODO:
3 | public static void main(String[] args) {
4 | // TODO: stub
5 | System.out.println("Hello World!");
6 |
7 | // TODO:
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_unused_imports.java:
--------------------------------------------------------------------------------
1 | import java.utils.*; // valid
2 | import java.util.List;
3 | import java.lang.String;
4 | import java.util.List;
5 |
6 | class HelloWorld {
7 | public static void main(String[] args) {
8 | System.out.println("Hello World!");
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_upper_ell.java:
--------------------------------------------------------------------------------
1 | class HelloWorld {
2 | public static void main(String[] args) {
3 | long x = 1l;
4 | long y = 1L;
5 | System.out.println(x + y);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_valid_algorithm_1.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public class Main {
4 | public static void main(String[] args) {
5 | // write your code here
6 | Scanner scanner = new Scanner(System.in);
7 | int heightBus = scanner.nextInt();
8 | int bridges = scanner.nextInt();
9 | scanner.nextLine();
10 | String heightBridges = scanner.nextLine();
11 | String[] heightsList = heightBridges.split(" ");
12 | String willNotCrash = "Will not crash";
13 | String willCrash = "";
14 |
15 | for (int i = 0; i < bridges; i++) {
16 | if (heightBus >= Integer.parseInt(heightsList[i])) {
17 | willCrash = "Will crash on bridge " + (i + 1);
18 | break;
19 | }
20 | }
21 |
22 | if ("".equals(willCrash)) {
23 | System.out.println(willNotCrash);
24 | } else {
25 | System.out.println(willCrash);
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_valid_blocks.java:
--------------------------------------------------------------------------------
1 | class HelloWorld {
2 | public static void main(String[] args) {
3 | try {
4 | System.out.println("Hello World!");
5 | } catch (Exception e) {
6 | // ignored
7 | }
8 |
9 | if (0 < 1) {
10 | int i = 0;
11 | } else {
12 | int i = 1;
13 | }
14 |
15 | for (i = 0; i < 1; i++) {
16 | System.out.println("Hello World Again!");
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_valid_curly_braces.java:
--------------------------------------------------------------------------------
1 | class HelloWorld {
2 | public static void main(String[] args) {
3 | for (int i = 0; i < args[0].length(); i++) {
4 | if (i < 1) {
5 | System.out.println("Hello World!");
6 | }
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_valid_default.java:
--------------------------------------------------------------------------------
1 | class HelloWorld {
2 | public static void main(String[] args) {
3 | int x = 1;
4 | int y;
5 | switch (x) {
6 | case 0:
7 | y = 1;
8 | break;
9 | default:
10 | y = 0;
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_valid_naming.java:
--------------------------------------------------------------------------------
1 | class MyClass {
2 | private static final String NAME = "";
3 | private static final String ANOTHER_NAME = "";
4 |
5 | private String field;
6 | private String anotherField;
7 |
8 | public static void main(String[] args) {
9 | int value = 0;
10 | }
11 |
12 | private void foo() {
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_valid_spaces.java:
--------------------------------------------------------------------------------
1 | class HelloWorld {
2 | public static void main(String[] args) {
3 | int j = 1;
4 | for (int i = 0; i < j; i++) {
5 | System.out.println("Hello World!");
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/test/resources/inspectors/java/test_when_only_equals_overridden.java:
--------------------------------------------------------------------------------
1 | import java.util.Objects;
2 |
3 | class Person {
4 |
5 | private String firstName;
6 | private String lastName;
7 | private int age;
8 |
9 | // constructor, getters and setters
10 |
11 | @Override
12 | public boolean equals(Object other) {
13 | /* Check this and other refer to the same object */
14 | if (this == other) {
15 | return true;
16 | }
17 |
18 | /* Check other is Person and not null */
19 | if (!(other instanceof Person)) {
20 | return false;
21 | }
22 |
23 | Person person = (Person) other;
24 |
25 | /* Compare all required fields */
26 | return age == person.age &&
27 | Objects.equals(firstName, person.firstName) &&
28 | Objects.equals(lastName, person.lastName);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/test/resources/inspectors/js/case0_no_issues.js:
--------------------------------------------------------------------------------
1 | function sum(a, b) {
2 | return a + b;
3 | }
4 |
5 | console.log(sum(5, 6));
6 |
--------------------------------------------------------------------------------
/test/resources/inspectors/js/case1_with_issues.js:
--------------------------------------------------------------------------------
1 | function a(x) {
2 | var b = 10;
3 | if (true) {
4 | return x;
5 | } else if (false) {
6 | return x+1;
7 | } else {
8 | return 4;
9 | }
10 | }
11 |
12 | function sayHello(name){
13 | alert("Hello " + name);
14 | }
15 |
16 | name = "Douglas Crockford";
17 | sayHello(name)
18 |
--------------------------------------------------------------------------------
/test/resources/inspectors/js/case2_semi_node_and_unused.js:
--------------------------------------------------------------------------------
1 | var qqq = 10;
2 |
3 | var readline = require('readline')
4 | var rl = readline.createInterface({
5 | input: process.stdin,
6 | output: process.stdout
7 | });
8 |
9 | rl.on('line', (line) => {
10 | let arr = [];
11 | if (line.trim() !== '') {
12 | arr = line.split(' ').map((n) => parseInt(n, 10));
13 | }
14 |
15 | console.log(sum(arr[0], arr[1]));
16 | });
17 |
18 | function sum(a, b) {
19 | return a + b;
20 | }
21 |
--------------------------------------------------------------------------------
/test/resources/inspectors/kotlin/case0_good_program.kt:
--------------------------------------------------------------------------------
1 | import java.util.Scanner
2 |
3 | fun main() {
4 | val scanner = Scanner(System.`in`)
5 |
6 | val a = scanner.nextInt()
7 | val b = scanner.nextInt()
8 |
9 | println(a + b)
10 | }
11 |
--------------------------------------------------------------------------------
/test/resources/inspectors/kotlin/case10_long_lines.kt:
--------------------------------------------------------------------------------
1 | import java.util.Scanner
2 |
3 | class Person(id: Int, firstName: String, lastName: String, middleName: String?, age: Int, email: String?, phoneNumber: String?, twitterHandle: String?)
4 |
5 | fun main() {
6 | val scanner = Scanner(System.`in`)
7 |
8 | val n = scanner.nextInt() // sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
9 | print(n + n + n + n + n + n + n + n + n + n + n + n + n + n + n + n + n + n + n + n + n + n + n + n + n + n + n + n + n + n + n + n + n)
10 | }
11 |
--------------------------------------------------------------------------------
/test/resources/inspectors/kotlin/case11_bad_ident.kt:
--------------------------------------------------------------------------------
1 |
2 | import java.util.Scanner
3 |
4 | fun main() {
5 | val scanner = Scanner(System.`in`)
6 | val n = scanner.nextInt()
7 | println(n)
8 | }
9 |
--------------------------------------------------------------------------------
/test/resources/inspectors/kotlin/case12_bad_filename.kt:
--------------------------------------------------------------------------------
1 | open class MotorVehicle
2 |
--------------------------------------------------------------------------------
/test/resources/inspectors/kotlin/case13_good_filename.kt:
--------------------------------------------------------------------------------
1 | open class MotorVehicle
2 |
3 | class Car : MotorVehicle()
4 |
--------------------------------------------------------------------------------
/test/resources/inspectors/kotlin/case14_keyword_spacing.kt:
--------------------------------------------------------------------------------
1 | fun main() {
2 | if(true) {
3 | println(1)
4 | }
5 | while(true) {
6 | println(1)
7 | }
8 | do {
9 | println(1)
10 | } while(true)
11 | if (true) {
12 | println(1)
13 | } else {
14 | println(1)
15 | }
16 | }
17 |
18 | fun foo1() {
19 | try { "".trim() }
20 | catch (e: Exception) {
21 | println(1)
22 | }
23 | finally {
24 | println(1)
25 | }
26 | if (true) {
27 | } else {
28 | println(1)
29 | }
30 | if (true) { println(1) } else { println(1) }
31 | if (true)
32 | println()
33 | else
34 | entry.value
35 | }
36 |
37 | fun foo2() {
38 | try {
39 | "".trim()
40 | } catch (e: Exception) {
41 | } finally { println(1) }
42 | try { "".trim() } catch (e: Exception) { println(1) } finally { println(1) }
43 | val v = 0
44 | when (v) {
45 | 1 -> println("")
46 | else -> println("")
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/test/resources/inspectors/kotlin/case15_empty_class_func.kt:
--------------------------------------------------------------------------------
1 | class Nothing { }
2 |
3 | fun no() { }
4 |
--------------------------------------------------------------------------------
/test/resources/inspectors/kotlin/case16_redundant_unit.kt:
--------------------------------------------------------------------------------
1 | fun printHello(): Unit {
2 | println("Hello!")
3 | }
4 |
--------------------------------------------------------------------------------
/test/resources/inspectors/kotlin/case17_modifier_order.kt:
--------------------------------------------------------------------------------
1 | private final data class Nothing1(val field: Int)
2 |
3 | final data class Nothing2(val field: Int)
4 |
--------------------------------------------------------------------------------
/test/resources/inspectors/kotlin/case18_redundant_braces.kt:
--------------------------------------------------------------------------------
1 |
2 | fun main() {
3 | val minutes = 30
4 | val sec = 40
5 | val ms = 200
6 |
7 | println("Time taken ${minutes} min. ${sec} sec. ${ms} ms.")
8 | }
9 |
--------------------------------------------------------------------------------
/test/resources/inspectors/kotlin/case19_private_property.kt:
--------------------------------------------------------------------------------
1 |
2 | import java.util.*
3 |
4 | class ConsoleHelper(val scanner: Scanner) {
5 |
6 | fun print(msg: String = "") = println(msg)
7 |
8 | fun askLine(msg: String = ""): String {
9 | if (msg != "") this.print(msg)
10 | return scanner.nextLine()
11 | }
12 |
13 | fun askInt(msg: String = ""): Int {
14 | if (msg != "") this.print(msg)
15 | return scanner.nextInt()
16 | }
17 |
18 | fun askDouble(msg: String = ""): Double {
19 | if (msg != "") this.print(msg)
20 | return scanner.nextDouble()
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/test/resources/inspectors/kotlin/case1_coffee_machine.kt:
--------------------------------------------------------------------------------
1 | fun main() {
2 | println("Starting to make a coffee")
3 | println("Grinding coffee beans")
4 | println("Boiling water")
5 | println("Mixing boiled water with crushed coffee beans")
6 | println("Pouring coffee into the cup")
7 | println("Pouring some milk into the cup")
8 | println("Coffee is ready!")
9 | }
10 |
--------------------------------------------------------------------------------
/test/resources/inspectors/kotlin/case20_cyclomatic_complexity.kt:
--------------------------------------------------------------------------------
1 | import java.util.Scanner
2 |
3 | class Main {
4 | val yes = "YES"
5 | val no = "NO"
6 |
7 | fun main() {
8 | printArmy()
9 | checkTriangle()
10 | checkQueens()
11 | calculator()
12 | }
13 |
14 | // CC is 10
15 | fun printArmy() {
16 | val scanner = Scanner(System.`in`)
17 | val p = scanner.nextInt()
18 | if (p < 1) {
19 | println("no army")
20 | } else if (p < 5) {
21 | println("few")
22 | } else if (p < 10) {
23 | println("several")
24 | } else if (p < 20) {
25 | println("pack")
26 | } else if (p < 50) {
27 | println("lots")
28 | } else if (p < 100) {
29 | println("horde")
30 | } else if (p < 250) {
31 | println("throng")
32 | } else if (p < 500) {
33 | println("swarm")
34 | } else if (p < 1000) {
35 | println("zounds")
36 | } else {
37 | println("legion")
38 | }
39 | }
40 |
41 | fun checkTriangle() { // CC is 4
42 | val scanner = Scanner(System.`in`)
43 |
44 | val a = scanner.nextInt()
45 | val b = scanner.nextInt()
46 | val c = scanner.nextInt()
47 |
48 | if (a + b > c && b + c > a && c + a > b) {
49 | println(yes)
50 | } else {
51 | println(no)
52 | }
53 | }
54 |
55 | fun checkQueens() { // CC is 4
56 | val scanner = Scanner(System.`in`)
57 |
58 | val num1 = scanner.nextInt()
59 | val num2 = scanner.nextInt()
60 | val num3 = scanner.nextInt()
61 | val num4 = scanner.nextInt()
62 |
63 | if (num1 == num3) {
64 | println(yes)
65 | } else if (num2 == num4) {
66 | println(yes)
67 | } else if (Math.abs(num1 - num3) == Math.abs(num2 - num4)) {
68 | println(NO)
69 | } else {
70 | println(no)
71 | }
72 | }
73 |
74 | fun calculator() { // CC is 3
75 | val scanner = Scanner(System.`in`)
76 |
77 | val line = scanner.nextLine().split("\\s+")
78 |
79 | val a = Long.parseLong(line[0])
80 | val op = line[1].charAt(0)
81 | val b = Long.parseLong(line[2])
82 |
83 | when (op) {
84 | '+' -> println(a + b)
85 | '-' -> println(a - b)
86 | '*' -> println(a * b)
87 | '/' -> {
88 | if (b == 0) {
89 | println("Division by 0!")
90 | } else {
91 | println(a / b)
92 | }
93 | else -> println("Unknown operator")
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/test/resources/inspectors/kotlin/case21_cyclomatic_complexity_bad.kt:
--------------------------------------------------------------------------------
1 | fun main() {
2 | if (true) {
3 | println(1)
4 | }
5 | while (true) {
6 | println(1)
7 | }
8 | do {
9 | println(1)
10 | } while (true)
11 | if (true) {
12 | println(1)
13 | } else {
14 | println(1)
15 | }
16 | try {
17 | "".trim()
18 | } catch (e: Exception) {
19 | println(1)
20 | } finally {
21 | println(1)
22 | }
23 | if (true) {
24 | println(1)
25 | } else {
26 | println(1)
27 | }
28 | if (true) {
29 | println(1)
30 | } else {
31 | println(1)
32 | }
33 | if (true) {
34 | println(1)
35 | } else {
36 | println(1)
37 | }
38 | if (true) {
39 | println(1)
40 | } else {
41 | println(1)
42 | }
43 | if (true) {
44 | println()
45 | } else {
46 | entry.value
47 | }
48 | try {
49 | "".trim()
50 | } catch (e: Exception) {
51 | println(1)
52 | } finally {
53 | println(1)
54 | }
55 | try {
56 | "".trim()
57 | } catch (e: Exception) {
58 | println(1)
59 | } finally {
60 | println(1)
61 | }
62 | val v = 0
63 | if (v == 1) {
64 | println("")
65 | } else {
66 | println("")
67 | }
68 | if (v) {
69 | v.let { "" }
70 | } else {
71 | v
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/test/resources/inspectors/kotlin/case22_too_many_arguments.kt:
--------------------------------------------------------------------------------
1 | import java.util.*
2 |
3 | class ConsoleHelper(val scanner: Scanner) {
4 | // 6+ -- is bad
5 | fun askLine(
6 | msg1: String = "",
7 | msg1: String = "",
8 | msg1: String = "",
9 | msg1: String = "",
10 | msg1: String = "",
11 | msg1: String = ""
12 | ): String {
13 | if (msg != "") {
14 | this.print(msg)
15 | }
16 | return scanner.nextLine()
17 | }
18 |
19 | // < 6 -- is ok
20 | fun askLine2(
21 | msg1: String = "",
22 | msg1: String = "",
23 | msg1: String = "",
24 | msg1: String = "",
25 | msg1: String = ""
26 | ): String {
27 | if (msg != "") {
28 | this.print(msg)
29 | }
30 | return scanner.nextLine()
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/test/resources/inspectors/kotlin/case23_bad_range_performance.kt:
--------------------------------------------------------------------------------
1 | fun main() {
2 | // bad
3 | (1..10).forEach {
4 | println(it)
5 | }
6 | (1 until 10).forEach {
7 | println(it)
8 | }
9 | (10 downTo 1).forEach {
10 | println(it)
11 | }
12 |
13 | // ok
14 | for (i in 1..10) {
15 | println(i)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/test/resources/inspectors/kotlin/case24_duplicate_when_bug.kt:
--------------------------------------------------------------------------------
1 | fun main() {
2 | // bad
3 | when (i) {
4 | 1 -> println("one")
5 | 1 -> println("one")
6 | else -> println("else")
7 | }
8 |
9 | // ok
10 | when (i) {
11 | 1 -> println("one")
12 | 2 -> println("two")
13 | else -> println("else")
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/test/resources/inspectors/kotlin/case25_unreachable_code.kt:
--------------------------------------------------------------------------------
1 | fun main() {
2 | for (i in 1..2) {
3 | break
4 | println() // unreachable
5 | }
6 |
7 | throw IllegalArgumentException("message")
8 | println() // unreachable
9 |
10 | fun f() {
11 | return
12 | println() // unreachable
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/test/resources/inspectors/kotlin/case26_var_could_be_val.kt:
--------------------------------------------------------------------------------
1 | fun example() {
2 | var i = 1 // violation: this variable is never re-assigned
3 | val j = i + 1
4 | }
5 |
6 | // ok
7 | fun example() {
8 | val i = 1
9 | val j = i + 1
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/test/resources/inspectors/kotlin/case2_valid_program.kt:
--------------------------------------------------------------------------------
1 | fun main() {
2 | println("Hello World!")
3 |
4 | val message = "Hello World!"
5 | println(message)
6 | }
7 |
--------------------------------------------------------------------------------
/test/resources/inspectors/kotlin/case3_todo.kt:
--------------------------------------------------------------------------------
1 | // TODO: stub
2 | fun main() {
3 | // TODO: stub
4 | println("Hello World!")
5 | // TODO: stub
6 | }
7 |
--------------------------------------------------------------------------------
/test/resources/inspectors/kotlin/case4_semicolons.kt:
--------------------------------------------------------------------------------
1 | import java.util.Scanner;
2 |
3 | fun main() {
4 | val scanner = Scanner(System.`in`);
5 |
6 | val a = scanner.nextInt();
7 | val b = scanner.nextInt();
8 |
9 | println(a + b);
10 | };
11 |
--------------------------------------------------------------------------------
/test/resources/inspectors/kotlin/case5_imports.kt:
--------------------------------------------------------------------------------
1 | import java.* // bad
2 | import java.util.*
3 | import java.time.LocalDate
4 | import java.util.Scanner
5 | import java.time.LocalDate
6 | import java.util.BitSet
7 |
8 | fun main() {
9 | val scanner = Scanner(System.`in`)
10 | val date = LocalDate.of(2020, 10, 10)
11 | println(date)
12 | }
13 |
--------------------------------------------------------------------------------
/test/resources/inspectors/kotlin/case6_missing_spaces.kt:
--------------------------------------------------------------------------------
1 | import java.util.Scanner
2 |
3 | fun main() {
4 | val scanner = Scanner(System.`in`)
5 |
6 | val a: Int = scanner.nextInt()
7 | val b:Int = scanner.nextInt()
8 | val c : Int = scanner.nextInt()
9 |
10 | //some operations below
11 | println(a+b)
12 | println(a- b)
13 | println("${a *b} ml of water")
14 |
15 | val q: Int ? = null // should be space
16 | }
17 |
--------------------------------------------------------------------------------
/test/resources/inspectors/kotlin/case7_immutability.kt:
--------------------------------------------------------------------------------
1 | import java.util.*
2 |
3 | fun main() {
4 | var scanner = Scanner(System.`in`)
5 | var n = scanner.nextInt()
6 | println(n)
7 | }
8 |
--------------------------------------------------------------------------------
/test/resources/inspectors/kotlin/case8_needless_blank_line.kt:
--------------------------------------------------------------------------------
1 | import java.util.Scanner
2 |
3 | fun main() {
4 | val scanner = Scanner(System.`in`)
5 |
6 |
7 | val n = scanner.nextInt()
8 |
9 |
10 |
11 | println(n)
12 | }
13 |
14 |
15 |
16 | fun first(): Int {
17 | return 0
18 | }
19 |
20 | fun second(): Int {
21 | return 1
22 | }
23 |
--------------------------------------------------------------------------------
/test/resources/inspectors/kotlin/case9_braces.kt:
--------------------------------------------------------------------------------
1 | import java.util.Scanner
2 |
3 | fun main() {
4 | val scanner = Scanner(System.`in`)
5 |
6 | val n = scanner.nextInt()
7 | if (n == 10)
8 | {
9 | println("abc")
10 | }
11 | }
12 |
13 | fun main(){
14 | val scanner = Scanner(System.`in`)
15 | val n = scanner.nextInt()
16 | println(n)}
17 |
--------------------------------------------------------------------------------
/test/resources/inspectors/pmd/empty_file.csv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperskill/hyperstyle/130f96ec5b92873de7e844db4ce09791ff531b41/test/resources/inspectors/pmd/empty_file.csv
--------------------------------------------------------------------------------
/test/resources/inspectors/pmd/multi_file_project.csv:
--------------------------------------------------------------------------------
1 | "Problem","Package","File","Priority","Line","Description","Rule set","Rule"
2 | "1","","/home/user/Desktop/some_project/main1.java","3","37","Use equals() to compare object references.","Error Prone","CompareObjectsWithEquals"
3 | "2","","/home/user/Desktop/some_project/main1.java","2","68","The method name and parameter number are suspiciously close to equals(Object)","Error Prone","SuspiciousEqualsMethodName"
4 | "3","","/home/user/Desktop/some_project/main2.java","4","113","Useless parentheses.","Code Style","UselessParentheses"
5 | "4","","/home/user/Desktop/some_project/main2.java","3","131","Avoid empty if statements","Error Prone","EmptyIfStmt"
6 |
--------------------------------------------------------------------------------
/test/resources/inspectors/pmd/project_without_issues.csv:
--------------------------------------------------------------------------------
1 | "Problem","Package","File","Priority","Line","Description","Rule set","Rule"
2 |
--------------------------------------------------------------------------------
/test/resources/inspectors/pmd/single_file_project.csv:
--------------------------------------------------------------------------------
1 | "Problem","Package","File","Priority","Line","Description","Rule set","Rule"
2 | "1","","/home/user/Desktop/some_project/main.java","3","6","The String literal 'Howdy' appears 4 times in this file; the first occurrence is on line 6","Error Prone","AvoidDuplicateLiterals"
3 | "2","","/home/user/Desktop/some_project/main.java","3","12","Document empty method body","Documentation","UncommentedEmptyMethodBody"
4 | "3","","/home/user/Desktop/some_project/main.java","3","31","Avoid unused local variables such as 'result'.","Best Practices","UnusedLocalVariable"
5 | "4","","/home/user/Desktop/some_project/main.java","3","61","Avoid unused private methods such as 'emptyLoop()'.","Best Practices","UnusedPrivateMethod"
--------------------------------------------------------------------------------
/test/resources/inspectors/pylint/issues/r1721.py:
--------------------------------------------------------------------------------
1 | a = [1, 2, 3]
2 | print([elem for elem in a])
3 |
--------------------------------------------------------------------------------
/test/resources/inspectors/pylint/issues/w1404.py:
--------------------------------------------------------------------------------
1 | a = "Hello, " "world!"
2 | print(a)
3 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case0_folder_without_init/hello.py:
--------------------------------------------------------------------------------
1 | if __name__ == '__main__':
2 | print('hello world!')
3 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case0_spaces.py:
--------------------------------------------------------------------------------
1 | a, b, c = (input(),input(),input())
2 | print(f'{a} {b} {c}')
3 |
4 | print('1', '2', '3', sep = '|')
5 |
6 | result = int(a)+10
7 | print(result)
8 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case10_unused_variable_in_loop.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 |
4 | def package_files(directory):
5 | paths = []
6 | for (path, directories, filenames) in os.walk(directory):
7 | for filename in filenames:
8 | paths.append(os.path.join('..', path, filename))
9 | return paths
10 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case11_redundant_parentheses.py:
--------------------------------------------------------------------------------
1 | nuts = int(input())
2 |
3 | if (nuts > 10):
4 | print('There is enough nuts')
5 | else:
6 | print('Not enough nuts')
7 |
8 | i = 1
9 | while (i <= nuts):
10 | print(f'Give the nuth №{i}')
11 | i += 1
12 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case12_unreachable_code.py:
--------------------------------------------------------------------------------
1 | def calc_sum(x, y):
2 | return x + y
3 | return x * y
4 |
5 |
6 | for i in range(10):
7 | print(i)
8 | continue
9 | print(i + i)
10 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case13_complex_logic_2.py:
--------------------------------------------------------------------------------
1 | elements = list(input('Enter cells: '))
2 | y = 0
3 | o = 0
4 |
5 | CROSS_SYMBOL = 'X'
6 | NOUGHT_SYMBOL = 'O'
7 |
8 | for x in elements:
9 | if x == CROSS_SYMBOL:
10 | y = y + 1
11 | elif x == NOUGHT_SYMBOL:
12 | o = o + 1
13 |
14 | odds = abs(y - o)
15 |
16 | up_row = [elements[0], elements[1], elements[2]]
17 | mid_row = [elements[3], elements[4], elements[5]]
18 | down_row = [elements[6], elements[7], elements[8]]
19 |
20 | up_col = [elements[0], elements[3], elements[6]]
21 | mid_col = [elements[1], elements[4], elements[7]]
22 | down_col = [elements[2], elements[5], elements[8]]
23 |
24 | diagonal_1 = [elements[0], elements[4], elements[8]]
25 | diagonal_2 = [elements[2], elements[4], elements[6]]
26 |
27 | full_field = [up_row, up_col, mid_row, mid_col, down_row, down_col, diagonal_1, diagonal_2]
28 |
29 | x_win = [CROSS_SYMBOL, CROSS_SYMBOL, CROSS_SYMBOL]
30 | o_win = [NOUGHT_SYMBOL, NOUGHT_SYMBOL, NOUGHT_SYMBOL]
31 |
32 | field = f"""
33 | ---------
34 | | {elements[0]} {elements[1]} {elements[2]} |
35 | | {elements[3]} {elements[4]} {elements[5]} |
36 | | {elements[6]} {elements[7]} {elements[8]} |
37 | ---------
38 | """
39 | if odds < 2:
40 | if x_win in full_field and o_win not in full_field:
41 | print(field)
42 | print(f'{CROSS_SYMBOL} wins')
43 | elif o_win in full_field and x_win not in full_field:
44 | print(field)
45 | print(f'{NOUGHT_SYMBOL} wins')
46 | elif o_win in full_field and x_win in full_field:
47 | print(field)
48 | print('Impossible')
49 | elif '_' not in elements:
50 | if o_win not in full_field and x_win not in full_field:
51 | print(field)
52 | print('Draw')
53 | elif '_' in elements:
54 | if o_win not in full_field and x_win not in full_field:
55 | print(field)
56 | print('Game not finished')
57 | elif odds >= 2:
58 | print(field)
59 | print('Impossible')
60 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case14_returns_errors.py:
--------------------------------------------------------------------------------
1 | def f_1(y):
2 | if not y:
3 | return
4 | return None # error!
5 |
6 |
7 | def f_2(y):
8 | if not y:
9 | return # error!
10 | return 1
11 |
12 |
13 | def f_3(y):
14 | if not y:
15 | return # error!
16 | return 1
17 |
18 |
19 | def f_4():
20 | a = 1
21 | # some code that not using `a`
22 | print('test')
23 | return a # error!
24 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case15_redefining.py:
--------------------------------------------------------------------------------
1 | def grade(score, max_score):
2 | return score * 100 / max_score
3 |
4 |
5 | score = int(input())
6 | max_score = int(input())
7 |
8 | grade(score, max_score)
9 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case16_comments.py:
--------------------------------------------------------------------------------
1 | n = int(input())
2 |
3 | # n += 20
4 | n += 10
5 |
6 | print(n) # ok
7 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case17_dangerous_default_value.py:
--------------------------------------------------------------------------------
1 | def some_fun(a=[]):
2 | a.append('h')
3 | print(a)
4 |
5 |
6 | some_fun([1, 2, 3])
7 | some_fun([1, 2, 3, 4])
8 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case18_comprehensions.py:
--------------------------------------------------------------------------------
1 | numbers = [0 for _ in range(10)]
2 |
3 | list(n + 1 for n in numbers)
4 | set(n + 1 for n in numbers)
5 |
6 | set([n + 1 for n in numbers])
7 | dict([(n, n * n) for n in numbers])
8 |
9 | tuple([1, 2]) # (1, 2)
10 | tuple([]) # ()
11 |
12 | dict(((1, 2),)) # {1: 2}
13 |
14 | sum([x ** 2 for x in range(10)]) # we allow this since flake8-comprehension 3.4.0 (see its changelog)
15 |
16 | test_dict = dict() # we allow this
17 | test_list = list() # we allow this
18 | test_tuple = tuple() # we allow this
19 |
20 | list([0 for _ in range(10)])
21 |
22 | reversed(sorted([2, 3, 1])) # sorted([2, 3, 1], reverse=True)
23 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case19_bad_indentation.py:
--------------------------------------------------------------------------------
1 |
2 | def is_even(number):
3 | return number % 2 == 0
4 |
5 |
6 | n = int(input())
7 | for i in range(n):
8 | print(i)
9 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case1_simple_valid_program.py:
--------------------------------------------------------------------------------
1 | days = int(input())
2 |
3 | cost_food_per_day = int(input())
4 | cost_flight = int(input())
5 | cost_night = int(input())
6 |
7 | nights = days - 1
8 | total_cost = days * cost_food_per_day + cost_night * nights + cost_flight * 2
9 |
10 | print(total_cost)
11 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case20_imports_order.py:
--------------------------------------------------------------------------------
1 | import itertools
2 | import functools
3 |
4 | from pylint import graph, exceptions
5 |
6 | print(itertools.__name__)
7 | print(functools.__name__)
8 | print(graph, exceptions)
9 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case21_imports.py:
--------------------------------------------------------------------------------
1 | import itertools
2 | import functools
3 | from math import ceil
4 |
5 | print(ceil(0.1))
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case22_reassigning.py:
--------------------------------------------------------------------------------
1 | def fun(greeting):
2 | greeting = 'hello'
3 | print(greeting)
4 |
5 |
6 | for i in range(20):
7 | i += 1
8 | print(i)
9 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case23_merging_comparisons.py:
--------------------------------------------------------------------------------
1 | elements = input()
2 |
3 | row1 = elements[:3]
4 | row2 = elements[3:6]
5 | row3 = elements[6:]
6 |
7 | CROSS = 'X' * 3
8 | ZERO = 'O' * 3
9 |
10 | row_with_x = row1 == CROSS or row2 == CROSS or row3 == CROSS
11 | row_with_o = row1 == ZERO or row2 == ZERO or row3 == ZERO
12 |
13 | if row1 == CROSS or row2 == CROSS or row3 == CROSS:
14 | print('X wins')
15 |
16 | if CROSS == row1 or CROSS == row2:
17 | print('X wins')
18 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case24_long_function.py:
--------------------------------------------------------------------------------
1 | def print_letters():
2 | print('a')
3 | print('b')
4 | print('c')
5 | print('d')
6 | print('e')
7 | print('f')
8 | print('g')
9 | print('a')
10 | print('b')
11 | print('c')
12 | print('d')
13 | print('e')
14 | print('f')
15 | print('g')
16 | print('a')
17 | print('b')
18 | print('c')
19 | print('d')
20 | print('e')
21 | print('f')
22 | print('g')
23 | print('a')
24 | print('b')
25 | print('c')
26 | print('d')
27 | print('e')
28 | print('f')
29 | print('g')
30 | print('a')
31 | print('b')
32 | print('c')
33 | print('d')
34 | print('e')
35 | print('f')
36 | print('g')
37 | print('a')
38 | print('b')
39 | print('c')
40 | print('d')
41 | print('e')
42 | print('f')
43 | print('g')
44 | print('a')
45 | print('b')
46 | print('c')
47 | print('d')
48 | print('e')
49 | print('f')
50 | print('g')
51 | print('a')
52 | print('b')
53 | print('c')
54 | print('d')
55 | print('e')
56 | print('f')
57 | print('g')
58 | print('a')
59 | print('b')
60 | print('c')
61 | print('d')
62 | print('e')
63 | print('f')
64 | print('g')
65 | print('a')
66 | print('b')
67 | print('c')
68 | print('d')
69 | print('e')
70 | print('f')
71 | print('g')
72 | print('a')
73 | print('b')
74 | print('c')
75 | print('d')
76 | print('e')
77 | print('f')
78 | print('g')
79 | print('c')
80 | print('d')
81 | print('e')
82 | print('f')
83 | print('g')
84 | print('a')
85 | print('b')
86 | print('c')
87 | print('d')
88 | print('e')
89 | print('f')
90 | print('g')
91 | print('a')
92 | print('b')
93 | print('c')
94 | print('d')
95 | print('e')
96 | print('f')
97 | print('g')
98 | print('c')
99 | print('d')
100 | print('e')
101 | print('f')
102 | print('g')
103 | print('a')
104 | print('b')
105 | print('c')
106 | print('d')
107 | print('e')
108 | print('f')
109 | print('g')
110 | print('a')
111 | print('b')
112 | print('c')
113 | print('d')
114 | print('e')
115 | print('f')
116 | print('g')
117 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case25_django.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render
2 | from django.views import View
3 |
4 |
5 | class ReviewView(View):
6 | reviews = ['review'] # List of reviews as plain strings
7 |
8 | def get(self, request, *args, **kwargs):
9 | return render(request, 'book/reviews.html', context={'reviews': self.reviews})
10 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case26_from_stepik.py:
--------------------------------------------------------------------------------
1 | a, b = input().split()
2 | print(int(a) + int(b))
3 |
4 |
5 | def fooBar():
6 | var = 1
7 | print(
8 | "Hello"
9 | "World"
10 | )
11 |
12 |
13 | x = 42 # noqa: E222,E305
14 | text = "This line is longer than 99 characters. This line is longer than 99 characters. This line is longer than 99 characters"
15 | pass
16 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case27_using_requests.py:
--------------------------------------------------------------------------------
1 | import requests
2 |
3 |
4 | def do_search(bookstore_url, params):
5 | return requests.get(url=bookstore_url,
6 | params=params)
7 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case29_whitespaces.py:
--------------------------------------------------------------------------------
1 | print('qqq')
2 |
3 | print('www')
4 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case2_boolean_expressions.py:
--------------------------------------------------------------------------------
1 |
2 | a = int(input())
3 | b = int(input())
4 | c = int(input())
5 | d = int(input())
6 |
7 | if a > b:
8 | print('a > b')
9 |
10 | if a > b and a > b:
11 | print('a > b again')
12 |
13 | if a > b and a < d:
14 | print('b < a < d')
15 |
16 | if not a > b:
17 | print('not a > b')
18 |
19 | if b < a < d:
20 | print('b < a < d again')
21 |
22 | if a > b == True:
23 | print('a > b and True')
24 |
25 | if True:
26 | print('qqq')
27 |
28 | enabled = False # It does not work now
29 | if a > b and b < c and c > d or c < a and enabled:
30 | print('Too complex expression')
31 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case30_allow_else_return.py:
--------------------------------------------------------------------------------
1 | def calculate(action: str, operand1: int, operand2: int) -> int:
2 | if action == '+':
3 | return operand1 + operand2
4 | elif action == '-':
5 | return operand1 - operand2
6 | elif action == '*':
7 | return operand1 * operand2
8 | else:
9 | raise ValueError(f'Unknown action {action}')
10 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case31_spellcheck.py:
--------------------------------------------------------------------------------
1 | import math
2 |
3 | number = math.sqrt(float(input()))
4 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case33_commas.py:
--------------------------------------------------------------------------------
1 | # Wrong C-812
2 | from math import (
3 | log
4 | )
5 |
6 | # Correct
7 | from math import (
8 | sin,
9 | )
10 |
11 | # Wrong C-812
12 | bad_multiline_dict = {
13 | "first": 1,
14 | "second": 2
15 | }
16 |
17 | # Correct
18 | good_multiline_dict = {
19 | "first": 1,
20 | "second": 2,
21 | }
22 |
23 | # Wrong C-812
24 | bad_multiline_list = [
25 | 1,
26 | 2,
27 | 3
28 | ]
29 |
30 | # Correct
31 | good_multiline_list = [
32 | 1,
33 | 2,
34 | 3,
35 | ]
36 |
37 | # Wrong C-812
38 | bad_multiline_tuple = (
39 | 3,
40 | 4
41 | )
42 |
43 | good_multiline_tuple = (
44 | 3,
45 | 4,
46 | )
47 |
48 |
49 | # Wrong C-812
50 | def bad_function(
51 | a,
52 | b
53 | ):
54 | return log(a, b)
55 |
56 |
57 | bad_function(
58 | 1,
59 | 2
60 | )
61 |
62 | bad_function(
63 | a=1,
64 | b=2
65 | )
66 |
67 |
68 | # Correct
69 | def good_function(
70 | a,
71 | b,
72 | ):
73 | return a + sin(b)
74 |
75 |
76 | good_function(
77 | 1,
78 | 2,
79 | )
80 |
81 | good_function(
82 | a=1,
83 | b=2,
84 | )
85 |
86 | # Wrong: C-813
87 | print(
88 | "Hello",
89 | "World"
90 | )
91 |
92 | # Correct
93 | print(
94 | "Hello",
95 | "World",
96 | )
97 |
98 |
99 | # Wrong: C-816
100 | def bad_function_with_unpacking(
101 | a,
102 | b,
103 | **kwargs
104 | ):
105 | pass
106 |
107 |
108 | # Correct
109 | def good_function_with_unpacking(
110 | a,
111 | b,
112 | **kwargs,
113 | ):
114 | pass
115 |
116 |
117 | # Wrong: C-815
118 | good_function_with_unpacking(
119 | 1,
120 | 2,
121 | **good_multiline_dict
122 | )
123 |
124 | # Correct
125 | good_function_with_unpacking(
126 | 1,
127 | 2,
128 | **good_multiline_dict,
129 | )
130 |
131 | # Wrong: C-818
132 | bad_comma = 1,
133 |
134 | # Correct
135 | good_comma = (1,)
136 |
137 | # Wrong: C-819
138 | bad_list = [1, 2, 3, ]
139 |
140 | # Correct:
141 | good_list = [1, 2, 3]
142 |
143 | # Wrong: C-819
144 | bad_dict = {"1": 1, "2": 2, "3": 3, }
145 |
146 | # Correct:
147 | good_dict = {"1": 1, "2": 2, "3": 3}
148 |
149 | # Wrong: C-819
150 | bad_tuple = (1, 2, 3,)
151 |
152 | # Correct
153 | good_tuple = (1, 2, 3)
154 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case34_cohesion.py:
--------------------------------------------------------------------------------
1 | from math import sqrt
2 |
3 |
4 | class BadClass:
5 | def __init__(self, x: int, y: int):
6 | self.x = x
7 | self.y = y
8 |
9 | @staticmethod
10 | def length(x: int, y: int) -> float:
11 | return sqrt(x ** 2 + y ** 2)
12 |
13 | @staticmethod
14 | def dot(self_x: int, self_y: int, other_x: int, other_y: int) -> int:
15 | return self_x * other_x + self_y * other_y
16 |
17 |
18 | class GoodClass(object):
19 | def __init__(self, x: int, y: int):
20 | self.x = x
21 | self.y = y
22 |
23 | @property
24 | def length(self) -> float:
25 | return sqrt(self.dot(self.x, self.y))
26 |
27 | def dot(self, other_x: int, other_y: int) -> int:
28 | return self.x * other_x + self.y * other_y
29 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case36_unpacking.py:
--------------------------------------------------------------------------------
1 | [a, b, c], [x, y, z] = (sorted(map(int, input().split())) for _ in 'lm')
2 | if [a, b, c] == [x, y, z]:
3 | a = "Boxes are equal"
4 | elif a <= x and b <= y and c <= z:
5 | a = "The first box is smaller than the second one"
6 | elif a >= x and b >= y and c >= z:
7 | a = "The first box is larger than the second one"
8 | else:
9 | a = "Boxes are incomparable"
10 | print(a)
11 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case37_wildcard_import.py:
--------------------------------------------------------------------------------
1 | from math import *
2 |
3 |
4 | def quick_reversed_sqrt(number):
5 | """
6 | It's quick. Trust me.
7 | """
8 | return 1 / sqrt(number)
9 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case38_spellcheck.py:
--------------------------------------------------------------------------------
1 | from lxml import etree
2 |
3 | root = etree.fromstring(input())
4 | children = root.getchildren(root)
5 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case39_no_issues.py:
--------------------------------------------------------------------------------
1 | print("Hello, world!")
2 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case3_redefining_builtin.py:
--------------------------------------------------------------------------------
1 | a = int(input())
2 | b = int(input())
3 |
4 | range = range(a, b + 1)
5 |
6 | list = list(filter(lambda x: x % 3 == 0, range))
7 | print(sum(list) / len(list))
8 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case4_naming.py:
--------------------------------------------------------------------------------
1 | def GREETING():
2 | print('hi!')
3 |
4 |
5 | class myclass:
6 |
7 | def __init__(self, a, b, C):
8 | self.A = a
9 | self.B = b
10 | self.C = C
11 |
12 | def myFun(self):
13 | print(f'hello 1 {self.A}')
14 |
15 | def my_fun(self, QQ):
16 | print('hello 2 {}'.format(QQ))
17 |
18 | @classmethod
19 | def test_fun(first):
20 | print('hello 3')
21 |
22 |
23 | valid_variable = 'ok'
24 | invalidVariable = 'invalid'
25 |
26 | print(valid_variable)
27 | print(invalidVariable)
28 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case5_returns.py:
--------------------------------------------------------------------------------
1 | def f(x):
2 | if x <= -2:
3 | return 1 - (x + 2) ** 2
4 | elif -2 < x <= 2:
5 | return -(x / 2)
6 | elif x > 2:
7 | return 1 + (x - 2) ** 2
8 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case6_unused_variables.py:
--------------------------------------------------------------------------------
1 |
2 | def fun(param):
3 | a = 10
4 | b = 20
5 | c = 30
6 | print(c)
7 | d = 40
8 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case7_empty_lines.py:
--------------------------------------------------------------------------------
1 | def fun():
2 | pass
3 |
4 | class Person:
5 |
6 | def __init__(self, name, age, gender):
7 | self.name = name
8 | self.age = age
9 |
10 |
11 | self.gender = gender
12 | def add_age(self, value):
13 | self.age += value
14 |
15 |
16 | def minus_age(self, value):
17 | self.age -= value
18 |
19 | class AnotherClass:
20 | def do_something(self):
21 | print(1)
22 |
23 | print(10)
24 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case8_good_class.py:
--------------------------------------------------------------------------------
1 | class Student:
2 |
3 | def __init__(self, name, last_name, birth_year):
4 | self.name = name
5 | self.last_name = last_name
6 | self.birth_year = birth_year
7 |
8 |
9 | student_name = Student(input(), input(), input())
10 | print(student_name.name[0])
11 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python/case_duplicates.py:
--------------------------------------------------------------------------------
1 | a, b = input().split()
2 | print(int(a) + int(b))
3 |
4 |
5 | def fooBar():
6 | var = 1
7 | print(
8 | "Hello"
9 | "World"
10 | )
11 |
12 |
13 | x = 42 # noqa: E222,E305
14 | text = "This line is longer than 99 characters. This line is longer than 99 characters. This line is longer than 99 characters"
15 | pass
16 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python_ast/function.py:
--------------------------------------------------------------------------------
1 | def foo():
2 | print(42)
3 | print(42)
4 | print(42)
5 | print(42)
6 | print(42)
7 | print(42)
8 | print(42)
9 | print(42)
10 | print(42)
11 | print(42)
12 | print(42)
13 | print(42)
14 | print(42)
15 | print(42)
16 | print(42)
17 |
--------------------------------------------------------------------------------
/test/resources/inspectors/python_ast/many_bool_expressions.py:
--------------------------------------------------------------------------------
1 | a = True
2 | b = False
3 | c = True
4 |
5 | if a or b:
6 | print('Hello')
7 |
8 | if b or c:
9 | print('world')
10 |
11 | if not c and a:
12 | print('!')
--------------------------------------------------------------------------------
/test/resources/inspectors/python_ast/one_bool_expression.py:
--------------------------------------------------------------------------------
1 | a, b, c, d, e, f = True, True, True, True, True, True
2 | if a or b and c or not d and e or f:
3 | print('Hello')
4 |
--------------------------------------------------------------------------------
/test/resources/inspectors/spring/case1/test_promiscuous_controller.java:
--------------------------------------------------------------------------------
1 | package org.hyperskill.webquizengine.controller;
2 |
3 | import org.springframework.stereotype.Controller;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.web.bind.annotation.RequestMapping;
6 |
7 | @Controller
8 | @X
9 | class ManyRoutesController {
10 |
11 |
12 | @RequestMapping
13 | public void m1() {
14 |
15 |
16 | }
17 |
18 | @RequestMapping
19 | public void m2() {
20 |
21 |
22 | }
23 |
24 | @RequestMapping
25 | public void m3() {
26 |
27 |
28 | }
29 |
30 | @RequestMapping
31 | public void m4() {
32 |
33 |
34 | }
35 |
36 | @RequestMapping
37 | public void m5() {
38 |
39 |
40 | }
41 |
42 | @RequestMapping
43 | public void m6() {
44 |
45 | }
46 | @RequestMapping
47 | public void m7() {
48 |
49 | }
50 | @RequestMapping
51 | public void m8() {
52 |
53 | }
54 |
55 | @RequestMapping
56 | public void m9() {
57 |
58 | }
59 | @RequestMapping
60 | public void m10() {
61 |
62 | }
63 |
64 | @RequestMapping
65 | public void m11() {
66 |
67 | }
68 | @RequestMapping
69 | public void m12() {
70 |
71 | }
72 | }
--------------------------------------------------------------------------------
/test/resources/inspectors/spring/case2/test_class_with_booleans.java:
--------------------------------------------------------------------------------
1 | class ClassWithBooleans {
2 | private boolean enabled = true;
3 | private boolean isTyped = true;
4 | private boolean count = false;
5 | private boolean correct = true;
6 | private int isValid = 1;
7 |
8 | public boolean getEnabled() {
9 | return enabled;
10 | }
11 |
12 | public boolean isTyped() {
13 | return isTyped;
14 | }
15 |
16 | public boolean getCount() {
17 | return count;
18 | }
19 |
20 | public boolean isEnabled() {
21 | return enabled;
22 | }
23 |
24 | public boolean isCount() {
25 | return count;
26 | }
27 |
28 | public boolean isCorrect() {
29 | return correct;
30 | }
31 |
32 | public int getIsValid() {
33 | return isValid;
34 | }
35 |
36 |
37 | public static void main(String[] args) {
38 | ClassWithBooleans object = new ClassWithBooleans();
39 | System.out.println(object.isTyped());
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/tox.ini:
--------------------------------------------------------------------------------
1 | [pytest]
2 | addopts = -rsxX -l --tb=short --strict
3 | xfail_strict = true
4 | norecursedirs = .* venv src *.egg dist build
--------------------------------------------------------------------------------