Skip to content
This repository was archived by the owner on Nov 19, 2023. It is now read-only.

Commit 89a34c6

Browse files
authored
Merge pull request #249 from snok/sondrelg/sonarcloud-upload
Add sonarcloud coverage upload
2 parents bdf3957 + 5ea8e89 commit 89a34c6

File tree

7 files changed

+55
-32
lines changed

7 files changed

+55
-32
lines changed

.github/workflows/testing.yml

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,32 @@ jobs:
8181
- name: Run tests
8282
run: |
8383
source .venv/bin/activate
84-
poetry run pytest --cov=openapi_tester --verbose --assert=plain --cov-report=xml
84+
poetry run pytest --cov=. --cov-report=xml
8585
poetry run coverage report
86+
- name: Archive coverage
87+
uses: actions/upload-artifact@v2
88+
with:
89+
name: coverage-xml
90+
path: coverage.xml
91+
if: matrix.python-version == '3.10' && matrix.django-version == '3.2'
92+
coverage:
93+
needs: test
94+
runs-on: ubuntu-latest
95+
steps:
96+
- uses: actions/checkout@v2
97+
- name: Get coverage
98+
uses: actions/download-artifact@v2
99+
with:
100+
name: coverage-xml
86101
- uses: codecov/codecov-action@v2
87102
with:
88103
file: ./coverage.xml
89104
fail_ci_if_error: true
90105
token: ${{ secrets.CODECOV_TOKEN }}
91-
if: matrix.python-version == '3.10'
106+
- name: Fix coverage file for sonarcloud
107+
run: |
108+
sed -i "s/<source>\/home\/runner\/work\/drf-openapi-tester\//<source>/g" coverage.xml
109+
- uses: sonarsource/sonarcloud-github-action@master
110+
env:
111+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
112+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

poetry.lock

Lines changed: 6 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ pytest = "*"
5858
pytest-django = "*"
5959
pylint = "*"
6060
coverage = { extras = ["toml"], version = "^6"}
61-
pytest-cov = "^2"
61+
pytest-cov = "*"
6262

6363
[tool.black]
6464
line-length = 120
@@ -101,13 +101,20 @@ good-names = "_,e,i"
101101

102102
[tool.coverage.run]
103103
source = ["openapi_tester/*"]
104-
omit = ["openapi_tester/type_declarations.py"]
104+
omit = [
105+
"openapi_tester/type_declarations.py",
106+
"manage.py",
107+
"test_project/*",
108+
]
105109
branch = true
106110

107111
[tool.coverage.report]
108112
show_missing = true
109113
skip_covered = true
110-
exclude_lines = ["raise NotImplementedError"]
114+
exclude_lines = [
115+
"raise NotImplementedError",
116+
"pragma: no cover",
117+
]
111118

112119
[tool.pytest.ini_options]
113120
DJANGO_SETTINGS_MODULE = "test_project.settings"

sonar-project.properties

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
sonar.projectKey=snok_drf-openapi-tester
2+
sonar.organization=snok
3+
4+
sonar.language=py
5+
sonar.python.version=3.6, 3.7, 3.8, 3.9, 3.10
6+
7+
sonar.test.inclusions=tests/*
8+
sonar.sources=openapi_tester
9+
sonar.sourceEncoding=UTF-8
10+
sonar.python.coverage.reportPaths=*coverage.xml

tests/schema_converter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def schema_type_to_mock_value(self, schema_object: Dict[str, Any]) -> Any:
7676
minimum += 1 if schema_object.get("exclusiveMinimum") else 0
7777
if maximum is not None:
7878
maximum -= 1 if schema_object.get("exclusiveMaximum") else 0
79-
if minimum is not None or maximum is not None:
79+
if minimum is not None or maximum is not None: # pragma: no cover
8080
minimum = minimum or 0
8181
maximum = maximum or minimum * 2
8282
if schema_type == "integer":

tests/test_schema_tester.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -401,17 +401,14 @@ def test_custom_validators():
401401
def uuid_4_validator(schema_section: dict, data: Any) -> Optional[str]:
402402
schema_format = schema_section.get("format")
403403
if schema_format == "uuid4":
404-
try:
405-
result = UUID(data, version=4)
406-
if str(result) != str(data):
407-
return f"Expected uuid4, but received {data}"
408-
except ValueError:
404+
result = UUID(data, version=4)
405+
if str(result) != str(data):
409406
return f"Expected uuid4, but received {data}"
410407
return None
411408

412-
def uuid_1_validator(schema_section: dict, data: Any) -> Optional[str]:
409+
def uuid_1_validator(schema_section: dict, data: Any) -> Optional[str]: # pragma: no cover
413410
schema_format = schema_section.get("format")
414-
if schema_format == "uuid1":
411+
if schema_format == "uuid1": #
415412
try:
416413
result = UUID(data, version=1)
417414
if str(result) != str(data):

tests/utils.py

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,15 @@
1-
import json
21
from contextlib import suppress
32
from copy import deepcopy
43
from pathlib import Path
54
from typing import Any, Callable, Generator, Optional, Tuple, Union
65

7-
import yaml
86
from rest_framework.response import Response
97

108
from tests.schema_converter import SchemaToPythonConverter
119

1210
TEST_ROOT = Path(__file__).resolve(strict=True).parent
1311

1412

15-
def load_schema(file_name: str) -> dict:
16-
with open(str(TEST_ROOT) + f"/schemas/{file_name}") as f:
17-
content = f.read()
18-
if "json" in file_name:
19-
return json.loads(content)
20-
else:
21-
return yaml.load(content, Loader=yaml.FullLoader)
22-
23-
2413
def response_factory(schema: dict, url_fragment: str, method: str, status_code: Union[int, str] = 200) -> Response:
2514
converted_schema = SchemaToPythonConverter(deepcopy(schema)).result
2615
response = Response(status=int(status_code), data=converted_schema)
@@ -67,7 +56,7 @@ def sort_object(data_object: Any) -> Any:
6756
if isinstance(data_object, list) and data_object:
6857
if not all(isinstance(entry, type(data_object[0])) for entry in data_object):
6958
return data_object
70-
if isinstance(data_object[0], (dict, list)):
59+
if isinstance(data_object[0], (dict, list)): # pragma: no cover
7160
return [sort_object(entry) for entry in data_object]
7261
return sorted(data_object)
7362
return data_object

0 commit comments

Comments
 (0)