def test_func_with_raises(self) -> None: config = Configuration.get_default_configuration() result = validate_function( tests.test_class.raises_class.RaisesClass. func_with_raise_and_args_and_return, config, tests.test_class.incorrect_class) assert result.result == ResultType.OK
def test_func_no_summary_no_fail(self) -> None: config = Configuration.get_default_configuration() config.fail_on_missing_summary = False result = validate_function( tests.test_class.nodocstring_class.ClassNoDocString. func_no_summary, config, tests.test_class.correct_class) assert result.result == ResultType.OK
def test_func_with_incorrect_raise(self) -> None: config = Configuration.get_default_configuration() result = validate_function( tests.test_class.raises_class.RaisesClass. func_with_incorrect_raise, config, tests.test_class.incorrect_class) assert result.result == ResultType.FAILED
def test_incorrect_class_empty_func(self) -> None: config = Configuration.get_default_configuration() result = validate_function( tests.test_class.incorrect_class.IncorrectTestClass.empty_func, config, tests.test_class.incorrect_class) assert result.result == ResultType.FAILED assert result.fail_reason == "Number of arguments differ. Expected (from signature) 0 arguments, but found (in docs) 1."
def test_incorrect_class_func_type_mismatch(self) -> None: config = Configuration.get_default_configuration() result = validate_function( tests.test_class.incorrect_class.IncorrectTestClass. func_type_mismatch, config, tests.test_class.incorrect_class) assert result.result == ResultType.FAILED assert result.fail_reason == "Argument type differ. Argument 'a' was expected (from signature) to have type '<class 'int'>', but has (in docs) type '<class 'float'>'"
def test_incorrect_class_func_name_mismatch(self) -> None: config = Configuration.get_default_configuration() result = validate_function( tests.test_class.incorrect_class.IncorrectTestClass. func_name_mismatch, config, tests.test_class.incorrect_class) assert result.result == ResultType.FAILED assert result.fail_reason == "Argument name differ. Expected (from signature) 'a', but got (in docs) 'b'"
def test_incorrect_class_func_has_arg_returns_arg(self) -> None: config = Configuration.get_default_configuration() result = validate_function( tests.test_class.incorrect_class.IncorrectTestClass. func_has_arg_returns_arg, config, tests.test_class.incorrect_class) assert result.result == ResultType.FAILED assert result.fail_reason == "Return type differ. Expected (from signature) <class 'float'>, but got (in docs) <class 'NoneType'>."
def test_func_no_summary_do_fail(self) -> None: config = Configuration.get_default_configuration() config.fail_on_missing_summary = True result = validate_function( tests.test_class.nodocstring_class.ClassNoDocString. func_no_summary, config, tests.test_class.correct_class) assert result.result == ResultType.FAILED assert result.fail_reason == 'Function does not have a summary'
def test_fail_on_raises_section_dont_fail(self) -> None: config = Configuration.get_default_configuration() config.fail_on_raises_section = False result = validate_function( tests.test_class.raises_class.RaisesClass. func_with_incorrect_raise, config, tests.test_class.incorrect_class) assert result.result == ResultType.OK
def test_func_argument_type_differ(self) -> None: config = Configuration.get_default_configuration() result = validate_function( tests.test_ranges.example_class.ExampleClass. func_argument_type_differ, config, tests.test_ranges.example_class) assert result.result == ResultType.FAILED assert 'Argument type differ' in result.fail_reason assert result.range is not None assert result.range.start_line == 77 assert result.range.end_line == 84
def test_func_parse_exception(self) -> None: config = Configuration.get_default_configuration() result = validate_function( tests.test_ranges.example_class.ExampleClass.func_parse_exception, config, tests.test_ranges.example_class) assert result.result == ResultType.FAILED assert 'Unable to parse docstring' in result.fail_reason assert result.range is not None assert result.range.start_line == 22 assert result.range.end_line == 32
def test_func_no_docstring(self) -> None: config = Configuration.get_default_configuration() config.fail_on_missing_docstring = True result = validate_function( tests.test_ranges.example_class.ExampleClass.func_no_docstring, config, tests.test_ranges.example_class) assert result.result == ResultType.FAILED assert result.fail_reason == 'Function does not have a docstring' assert result.range is not None assert result.range.start_line == 16 assert result.range.end_line == 16
def test_func_number_of_raised_exceptions_differ(self) -> None: config = Configuration.get_default_configuration() result = validate_function( tests.test_ranges.example_class.ExampleClass. func_number_of_raised_exceptions_differ, config, tests.test_ranges.example_class) assert result.result == ResultType.FAILED assert 'Number of listed raised exceptions does not match actual' in result.fail_reason assert result.range is not None assert result.range.start_line == 89 assert result.range.end_line == 100
def validate_module(self, module_path: str) -> ModuleValidationResult: """Validates the module, given its path. Args: module_path (str): Path to a module. Returns: ModuleValidationResult: Result of validating the module. """ logging.log(f'Validating module: {module_path}') result = ModuleValidationResult(module_path) module_name = os.path.basename(module_path) module_spec: Optional[ ModuleSpec] = importlib.util.spec_from_file_location( module_name, module_path) if not os.path.exists( module_path) or module_spec is None or not isinstance( module_spec.loader, Loader): result.result = ResultType.NOT_RUN result.fail_reason = f"Failed to load file from location: {module_path}" return result try: module_type = importlib.util.module_from_spec(module_spec) module_spec.loader.exec_module(module_type) except ModuleNotFoundError as e: result.result = ResultType.FAILED result.fail_reason = f"Failed to load module dependant module: {str(e)}" return result except Exception as e: result.result = ResultType.FAILED result.fail_reason = f"Failed to load module (possibly due to syntax errors): {module_path}" return result # Validate top-level functions in module fns = self.get_global_functions(module_type) for fn in fns: function_result = validate_function(fn, self.config, module_type) if function_result.result == ResultType.FAILED: result.result = ResultType.FAILED result.function_results.append(function_result) # Validate top-level classes in module classes = self.get_classes(module_type) for cl in classes: class_result = validate_class(cl, self.config, module_type) if class_result.result == ResultType.FAILED: result.result = ResultType.FAILED result.class_results.append(class_result) return result
def test_correct_class_empty_func(self) -> None: config = Configuration.get_default_configuration() result = validate_function( tests.test_class.correct_class.CorrectTestClass.empty_func, config, tests.test_class.correct_class) assert result.result == ResultType.OK
def test_correct_class_has_arg_returns_arg(self) -> None: config = Configuration.get_default_configuration() result = validate_function( tests.test_class.correct_class.CorrectTestClass. func_has_arg_returns_arg, config, tests.test_class.correct_class) assert result.result == ResultType.OK
def test_get_type_from_module_raises(self) -> None: config = Configuration.get_default_configuration() result = validate_function(tests.test_utilities.example_class.ExampleClass.func_raises, config, tests.test_utilities.example_class) assert 'Unable to parse docstring: a (DEFINITELYNOTACLASS): [description]' in result.fail_reason