diff --git a/fiasko_bro/code_validator.py b/fiasko_bro/code_validator.py index 8e65775..1090bcd 100644 --- a/fiasko_bro/code_validator.py +++ b/fiasko_bro/code_validator.py @@ -122,7 +122,13 @@ class CodeValidator: 'has_no_extra_dockstrings_whitelist': [ '/migrations/', '/alembic/', - ] + ], + 'is_nesting_too_deep': [ + '/migrations/', + '/alembic/', + 'manage.py', + 'settings.py', + ], } _default_settings = { @@ -267,4 +273,4 @@ def validate(self, repo_path, original_repo_path=None, check_repo_size=True, **k self.validator_arguments ) return errors - return errors \ No newline at end of file + return errors diff --git a/fiasko_bro/validators.py b/fiasko_bro/validators.py index c0ab011..623601b 100644 --- a/fiasko_bro/validators.py +++ b/fiasko_bro/validators.py @@ -455,13 +455,17 @@ def has_no_long_files(solution_repo, max_number_of_lines, *args, **kwargs): return 'file_too_long', file_name -def is_nesting_too_deep(solution_repo, tab_size, max_indentation_level, *args, **kwargs): +def is_nesting_too_deep(solution_repo, tab_size, max_indentation_level, whitelists, *args, **kwargs): """Looks at the number of spaces in the beginning and decides if the code is too nested. As a precondition, the code has to pass has_indents_of_spaces. """ + whitelist = whitelists.get('is_nesting_too_deep', []) for file_path, file_content, _ in solution_repo.get_ast_trees(with_filenames=True, with_file_content=True): + for directory in whitelist: + if directory in file_path: + continue lines = file_content.split('\n') previous_line_indent = 0 for line_number, line in enumerate(lines): diff --git a/test_fixtures/general_repo/mccabe_test_file.py b/test_fixtures/general_repo/complex_functions.py similarity index 92% rename from test_fixtures/general_repo/mccabe_test_file.py rename to test_fixtures/general_repo/complex_functions.py index 68f0e9f..a3a469a 100644 --- a/test_fixtures/general_repo/mccabe_test_file.py +++ b/test_fixtures/general_repo/complex_functions.py @@ -1,4 +1,3 @@ -# This file for tests/test_general_validators/test_mccabe_difficulty.py def function_with_big_complexity(list_of_items): diff --git a/test_fixtures/general_repo/settings.py b/test_fixtures/general_repo/settings.py new file mode 100644 index 0000000..68144f8 --- /dev/null +++ b/test_fixtures/general_repo/settings.py @@ -0,0 +1,128 @@ +""" +Django settings for telegraph project. +Generated by 'django-admin startproject' using Django 1.11.5. +For more information on this file, see +https://docs.djangoproject.com/en/1.11/topics/settings/ +For the full list of settings and their values, see +https://docs.djangoproject.com/en/1.11/ref/settings/ +""" + +import os +import dj_database_url + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = False + +# SECURITY WARNING: keep the secret key used in production secret! +if DEBUG: + SECRET_KEY = 'j_el6or0rc&8npit+=db*!4yo9yxr40%6m!5vw03#cqz0y!tlo' +else: + SECRET_KEY = os.environ['SECRET_KEY'] + + +ALLOWED_HOSTS = ['safe-cove-33456.herokuapp.com'] + + +# Application definition + +INSTALLED_APPS = [ + 'entries.apps.EntriesConfig', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'telegraph.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'telegraph.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/1.11/ref/settings/#databases + +if DEBUG: + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } + } +else: + DATABASES = { + 'default': dj_database_url.config() + } + + +# Password validation +# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/1.11/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/1.11/howto/static-files/ + +STATIC_URL = '/static/' +SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' diff --git a/tests/test_general_validators/test_is_nesting_too_deep.py b/tests/test_general_validators/test_is_nesting_too_deep.py new file mode 100644 index 0000000..2e886fa --- /dev/null +++ b/tests/test_general_validators/test_is_nesting_too_deep.py @@ -0,0 +1,15 @@ +from fiasko_bro import validators +from fiasko_bro.code_validator import CodeValidator + + +def test_is_nesting_too_deep_fails(test_repo): + expected_output = 'too_nested', 'function_with_big_complexity' + output = validators.is_nesting_too_deep( + solution_repo=test_repo, + tab_size=CodeValidator._default_settings['tab_size'], + max_indentation_level=CodeValidator._default_settings['max_indentation_level'], + whitelists=CodeValidator.whitelists, + ) + assert isinstance(output, tuple) + assert output[0] == 'too_nested' + assert 'complex_functions' in output[1] diff --git a/tests/test_general_validators/test_pep8_violations.py b/tests/test_general_validators/test_pep8_violations.py index 2d518cd..544bf38 100644 --- a/tests/test_general_validators/test_pep8_violations.py +++ b/tests/test_general_validators/test_pep8_violations.py @@ -11,7 +11,8 @@ def test_pep8_violations_fail(test_repo): whitelists=whitelists, max_pep8_line_length=79, ) - assert output == expected_output + assert isinstance(expected_output, tuple) + assert expected_output[0] == 'pep8' def test_pep8_violations_ok(test_repo):