Skip to content

Commit

Permalink
Merge pull request #11 from rfrezino/add-support-form-toml
Browse files Browse the repository at this point in the history
Add windows tests
  • Loading branch information
rfrezino authored Jan 31, 2022
2 parents 1fbd7a1 + 570d931 commit 78c8711
Show file tree
Hide file tree
Showing 15 changed files with 84 additions and 53 deletions.
22 changes: 18 additions & 4 deletions .github/workflows/python-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,15 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- name: Set up Ubuntu
run: sudo apt-get install -y graphviz
- name: Set up Graphviz
run: |
echo $RUNNER_OS
if [ "$RUNNER_OS" == "Linux" ]; then
sudo apt-get install -y graphviz
else
echo "Graphviz tests will only run for ubuntu-latest"
fi
shell: bash
- name: Set up Python
uses: actions/setup-python@v2
with:
Expand All @@ -32,7 +39,14 @@ jobs:
poetry install
- name: Run MyPy Checks
run: poetry run mypy src
- name: Run Nose Tests
run: poetry run nosetests -v ./
- name: Run Tests
run: |
echo $RUNNER_OS
if [ "$RUNNER_OS" == "Linux" ]; then
poetry run python -m nose -v -w ./tests
else
poetry run python -m unittest -v
fi
shell: bash


2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "hexagonal-py"
version = "0.1.4"
version = "0.1.5"
description = """Hexagonal Coherence Check"""
readme = 'README.md'
authors = ["rfrezino <rodrigofrezino@gmail.com>"]
Expand Down
4 changes: 3 additions & 1 deletion src/hexagonal/domain/hexagonal_layer.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import os
from dataclasses import dataclass
from typing import List

Expand All @@ -17,4 +18,5 @@ def _valid_dirs(self):
raise Exception(f'Hexagonal Layer directory "{self.name}" must start with /. Example: "/domain"')

if dir.endswith('/'):
raise Exception(f'Hexagonal Layer directory "{self.name}" must not finish with /. Example: "/domain"')
raise Exception(
f'Hexagonal Layer directory "{self.name}" must not finish with /. Example: "/domain"')
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import os
from dataclasses import dataclass
from typing import List, Optional

Expand All @@ -23,7 +24,7 @@ def get_directory_group_index_for_file(self, relative_folder_path_from_project_f

for dir_group_index, dir_group in enumerate(self.directories_groups):
for dir_name in dir_group:
if dir_name == relative_folder_path_from_project_folder:
if os.path.normcase(os.path.normpath(dir_name)) == relative_folder_path_from_project_folder:
return dir_group_index + 1

return 0
Expand Down
7 changes: 7 additions & 0 deletions src/hexagonal/domain/raw_python_file.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import os.path
from dataclasses import dataclass


Expand All @@ -12,3 +13,9 @@ class RawPythonFile:
relative_folder_path_from_project_folder: str
project_folder_full_path: str

def __post_init__(self):
self.file_full_path = os.path.normcase(os.path.normpath(self.file_full_path))
self.file_folder_full_path = os.path.normcase(os.path.normpath(self.file_folder_full_path))
self.relative_folder_path_from_project_folder = os.path.normcase(
os.path.normpath(self.relative_folder_path_from_project_folder))
self.project_folder_full_path = os.path.normcase(os.path.normpath(self.project_folder_full_path))
4 changes: 2 additions & 2 deletions src/hexagonal/services/hexagonal_dependency_flow_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ class DependencyFlowError:
group_inter_dependency: bool



@dataclass
class DependencyFlowResponse:
errors: List[DependencyFlowError]
Expand Down Expand Up @@ -44,7 +43,8 @@ def _is_inner_layer_is_point_to_outer_layer(inner_layer: HexagonalProjectLayer,
outer_layer: HexagonalProjectLayer) -> bool:
return inner_layer.index < outer_layer.index

def _are_files_in_same_layer(self, source_layer: HexagonalProjectLayer,
@staticmethod
def _are_files_in_same_layer(source_layer: HexagonalProjectLayer,
module_layer: HexagonalProjectLayer) -> bool:
return source_layer.index == module_layer.index

Expand Down
17 changes: 8 additions & 9 deletions src/hexagonal/services/python_file_imports_resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,9 @@ def _get_all_modules_source_paths(self) -> List[str]:
all_modules.append(self.__get_module_file_name(module))

all_modules.extend(
self._convert_bad_modules_into_paths(base_file_full_path=self._raw_python_file.file_full_path,
bad_modules=list(finder.badmodules.keys())))
self._convert_bad_modules_into_paths(bad_modules=list(finder.badmodules.keys())))

return [value for value in all_modules if value is not None]
return [os.path.normcase(os.path.normpath(value)) for value in all_modules if value is not None]

@staticmethod
def __get_module_file_name(module: Module) -> Optional[str]:
Expand All @@ -52,19 +51,19 @@ def __get_module_file_name(module: Module) -> Optional[str]:
except Exception:
return None

def _convert_bad_modules_into_paths(self, base_file_full_path: str, bad_modules: List[str]) -> List[str]:
def _convert_bad_modules_into_paths(self, *, bad_modules: List[str]) -> List[str]:
result = []

for bad_module in bad_modules:
bad_module_file = bad_module.replace('.', '/') + '.py'
bad_module_file = bad_module.replace('.', os.sep) + '.py'

while '/' in bad_module_file:
full_bad_module_file = self._raw_python_file.project_folder_full_path + '/' + bad_module_file
while os.sep in bad_module_file:
full_bad_module_file = self._raw_python_file.project_folder_full_path + os.sep + bad_module_file

if os.path.isfile(full_bad_module_file):
result.append(full_bad_module_file)
result.append(os.path.normpath(full_bad_module_file))
break

bad_module_file = bad_module_file.split('/', 1)[1]
bad_module_file = bad_module_file.split(os.sep, 1)[1]

return result
7 changes: 2 additions & 5 deletions src/hexagonal/services/raw_python_file_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,14 @@ def __init__(self, file_full_path: str, project_source_folder_full_path: str):
if not file_full_path.startswith(project_source_folder_full_path):
raise Exception('File path and project path do not match.')

if not file_full_path.startswith('/'):
raise Exception("The param file_full_path must have the file's full path.")

if not file_full_path.endswith('.py'):
raise Exception('File must have .py extension.')

self._file_full_path = file_full_path
self._file_full_path = os.path.normcase(os.path.normpath(file_full_path))
self._project_source_folder_full_path = os.path.abspath(project_source_folder_full_path)

def _get_file_name_from_full_file_path(self) -> str:
return self._file_full_path.split('/')[-1]
return self._file_full_path.split(os.sep)[-1]

def _get_file_folder_path(self) -> str:
return os.path.abspath(self.file_full_path.replace(self._file_name, ''))
Expand Down
2 changes: 1 addition & 1 deletion src/hexagonal/services/raw_python_project_importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def _get_all_python_files_paths_from_source_folder(self) -> List[str]:
for file in all_files:
include_file = True

if '/.' in file:
if f'{os.sep}.' in file:
continue

for excluded_dir in self._excluded_folders:
Expand Down
7 changes: 5 additions & 2 deletions tests/integration_tests/infrastructure/test_cli.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import sys
import unittest
from unittest import TestCase

from click.testing import CliRunner
Expand Down Expand Up @@ -48,8 +50,8 @@ def test_cli_run_check_should_return_errors_for_wrong_clean_project(self):
]
)

self.assertEqual(result.exit_code, 1)
self.assertIn('Wrong dependency flow. An inner layer is pointing to an outer layer.', result.output)
self.assertEqual(result.exit_code, 1)

def test_cli_run_check_should_return_no_errors_for_correct_hexa_project(self):
# This tests check the consistency of this on project
Expand All @@ -72,10 +74,11 @@ def test_cli_run_check_should_return_errors_for_wrong_hexa_project(self):
['--project_path', get_sample_wrong_test_hexa_arch_project_path(),
'--source_path', get_sample_wrong_test_hexa_arch_project_path()])

self.assertEqual(result.exit_code, 1)
self.assertIn('A file from a directory group is pointing to a file in another directory group in same layer.',
result.output)
self.assertEqual(result.exit_code, 1)

@unittest.skipIf(sys.platform.startswith('win'), 'No Windows Support')
def test_cli_run_diagrams_should_return_no_errors_for_correct_hexa_project(self):
# This tests check the consistency of this on project
runner = CliRunner()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import os.path
from typing import List
from unittest import TestCase

Expand All @@ -14,19 +15,19 @@ def assertContainsItemWithSuffix(expected_suffix: str, item_list: List[str]):

def test_resolve_imported_modules_when_file_is_valid_return_list_of_imported_modules(self):
project_path = get_sample_correct_test_clean_arch_project_path()
file_path = project_path + '/usecases/create_person_usecase.py'
file_path = os.path.normcase(os.path.normpath(project_path + '/usecases/create_person_usecase.py'))

raw_python_file = RawPythonFile(
file_full_path=file_path,
file_name='create_person_usecase.py',
file_folder_full_path=project_path + '/usecases',
relative_folder_path_from_project_folder='/usecases',
file_folder_full_path=os.path.normpath(project_path + '/usecases'),
relative_folder_path_from_project_folder=os.path.normpath('/usecases'),
project_folder_full_path=project_path,
)

imports_resolver = PythonFileImportsResolver(raw_python_file=raw_python_file)
imported_modules = imports_resolver.resolve_imported_modules()

self.assertEqual(len(imported_modules), 2)
self.assertContainsItemWithSuffix('/domain/person.py', imported_modules)
self.assertContainsItemWithSuffix('services/person_repository.py', imported_modules)
self.assertEqual(len(imported_modules), 2, imported_modules)
self.assertContainsItemWithSuffix('person.py', imported_modules)
self.assertContainsItemWithSuffix('person_repository.py', imported_modules)
20 changes: 7 additions & 13 deletions tests/integration_tests/services/test_raw_python_file_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,14 @@
from unittest import TestCase

from hexagonal.services.raw_python_file_builder import RawPythonFileBuilder
from tests.utils import fix_path


class TestRawPythonFileBuilder(TestCase):

def test_init_should_raise_exception_when_param_file_full_path_is_relative_path(self):
invalid_source_path = '~/test.py'

with self.assertRaises(Exception) as error:
builder = RawPythonFileBuilder(file_full_path=invalid_source_path, project_source_folder_full_path='~/')
self.assertEqual("The param file_full_path must have the file's full path.", str(error.exception))

def test_init_should_return_valid_object_when_params_are_correct(self):
valid_source_path = os.path.abspath(__file__)
file_folder = os.path.abspath(__file__.replace('test_raw_python_file_builder.py', ''))
valid_source_path = fix_path(os.path.abspath(__file__))
file_folder = fix_path(os.path.abspath(__file__.replace('test_raw_python_file_builder.py', '')))

builder = RawPythonFileBuilder(file_full_path=valid_source_path, project_source_folder_full_path=file_folder)

Expand All @@ -29,14 +23,14 @@ def test_init_should_raise_exception_when_file_and_project_paths_does_not_match(
self.assertEqual('File path and project path do not match.', str(error.exception))

def test_build_should_return_valid_object_when_params_are_correct(self):
valid_source_path = os.path.abspath(__file__)
file_folder = os.path.abspath(__file__.replace('test_raw_python_file_builder.py', ''))
project_folder = file_folder.split('/services')[0]
valid_source_path = fix_path(os.path.abspath(__file__))
file_folder = fix_path(os.path.abspath(__file__.replace('test_raw_python_file_builder.py', '')))
project_folder = file_folder.split(f'{os.sep}services')[0]

builder = RawPythonFileBuilder(file_full_path=valid_source_path, project_source_folder_full_path=project_folder)
raw_python_file = builder.build()

self.assertEqual(valid_source_path, raw_python_file.file_full_path)
self.assertEqual('test_raw_python_file_builder.py', raw_python_file.file_name)
self.assertEqual(file_folder, raw_python_file.file_folder_full_path)
self.assertEqual('/services', raw_python_file.relative_folder_path_from_project_folder)
self.assertEqual(f'{os.sep}services', raw_python_file.relative_folder_path_from_project_folder)
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import os.path
import sys
import unittest
from tempfile import TemporaryDirectory
from time import sleep
from unittest import TestCase
Expand All @@ -10,6 +12,7 @@


class TestGenerateDiagramUseCase(TestCase):
@unittest.skipIf(sys.platform.startswith('win'), 'No Windows Support')
def test_generate_diagram(self):
temp_dir = TemporaryDirectory()
diagram_path = temp_dir.name + '/outputfile'
Expand Down
14 changes: 8 additions & 6 deletions tests/integration_tests/utils/utils.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
import os

from tests.utils import get_tests_path


def get_integration_tests_path():
return get_tests_path() + '/integration_tests'
return os.path.join(get_tests_path(), 'integration_tests')


def get_sample_wrong_test_clean_arch_project_path():
return get_integration_tests_path() + '/utils/sample_projects/wrong_clean_arch_project'
return os.path.join(get_integration_tests_path(), 'utils', 'sample_projects', 'wrong_clean_arch_project')


def get_sample_correct_test_clean_arch_project_path():
return get_integration_tests_path() + '/utils/sample_projects/correct_clean_arch_project'
return os.path.join(get_integration_tests_path(), 'utils', 'sample_projects', 'correct_clean_arch_project')


def get_sample_wrong_test_hexa_arch_project_path():
return get_integration_tests_path() + '/utils/sample_projects/wrong_hexa_arch_project'
return os.path.join(get_integration_tests_path(), 'utils', 'sample_projects', 'wrong_hexa_arch_project')


def get_sample_correct_test_hexa_arch_project_path():
return get_integration_tests_path() + '/utils/sample_projects/correct_hexa_arch_project'
return os.path.join(get_integration_tests_path(), 'utils', 'sample_projects', 'correct_hexa_arch_project')


def get_sample_correct_test_hexa_arch_project_toml_path():
return get_integration_tests_path() + '/utils/sample_projects/correct_hexa_arch_project_toml'
return os.path.join(get_integration_tests_path(), 'utils', 'sample_projects', 'correct_hexa_arch_project_toml')
12 changes: 10 additions & 2 deletions tests/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import os.path
import pathlib


def get_project_path() -> str:
return __file__.split('/tests')[0]
return str(pathlib.Path(__file__).resolve().parent.parent)


def get_tests_path() -> str:
return get_project_path() + '/tests'
return os.path.join(get_project_path(), 'tests')


def fix_path(path: str) -> str:
return os.path.normcase(os.path.normpath(path))

0 comments on commit 78c8711

Please sign in to comment.