def test__linter__linting_unexpected_error_handled_gracefully( patched_lint, patched_logger): """Test that an unexpected internal error is handled gracefully and returns the issue-surfacing file.""" patched_lint.side_effect = Exception("Something unexpected happened") lntr = Linter() lntr.lint_paths(("test/fixtures/linter/passing.sql", )) assert ( "Unable to lint test/fixtures/linter/passing.sql due to an internal error." # NB: Replace is to handle windows-style paths. in patched_logger.warning.call_args[0][0].replace("\\", "/") and "Exception: Something unexpected happened" in patched_logger.warning.call_args[0][0])
def test__linter__linting_unexpected_error_handled_gracefully( patched_lint_string, patched_logger ): """Test that an unexpected internal error is handled gracefully and returns the issue-surfacing file.""" patched_lint_string.side_effect = Exception("Something unexpected happened") lntr = Linter() lntr.lint_paths(["test/fixtures/linter/passing.sql"]) assert ( "Unable to lint test/fixtures/linter/passing.sql due to an internal error." in patched_logger.warning.call_args[0][0] and "Exception: Something unexpected happened" in patched_logger.warning.call_args[0][0] )
def test__linter__skip_large_bytes(filesize, raises_skip): """Test extracting paths from a file path.""" config = FluffConfig(overrides={ "large_file_skip_byte_limit": filesize, "dialect": "ansi" }) # First check the function directly if raises_skip: with pytest.raises(SQLFluffSkipFile) as excinfo: Linter._load_raw_file_and_config( "test/fixtures/linter/indentation_errors.sql", config) assert "Skipping" in str(excinfo.value) assert f"over the limit of {filesize}" in str(excinfo.value) # If NOT raises, then we'll catch the raise an error and the test will fail. # Then check that it either is or isn't linted appropriately via lint_paths. lntr = Linter(config) result = lntr.lint_paths( ("test/fixtures/linter/indentation_errors.sql", ), ) if raises_skip: assert not result.get_violations() else: assert result.get_violations() # Same again via parse_path, which is the other entry point. result = list( lntr.parse_path("test/fixtures/linter/indentation_errors.sql", )) if raises_skip: assert not result else: assert result
def test__linter__encoding(fname, config_encoding, lexerror): """Test linter deals with files with different encoding.""" lntr = Linter(config=FluffConfig(overrides={ "rules": "L001", "encoding": config_encoding, })) result = lntr.lint_paths([fname]) assert lexerror == (SQLLexError in [type(v) for v in result.get_violations()])
def test__linter__linting_result_check_tuples_by_path(by_path, result_type): """Test that a LintingResult can partition violations by the source files.""" lntr = Linter() result = lntr.lint_paths([ "test/fixtures/linter/comma_errors.sql", "test/fixtures/linter/whitespace_errors.sql", ]) check_tuples = result.check_tuples(by_path=by_path) isinstance(check_tuples, result_type)
def test__linter__linting_result_get_violations(): """Test that we can get violations from a LintingResult.""" lntr = Linter() result = lntr.lint_paths([ "test/fixtures/linter/comma_errors.sql", "test/fixtures/linter/whitespace_errors.sql", ]) all([type(v) == SQLLintError for v in result.get_violations()])
def test__linter__linting_parallel_thread(force_error, monkeypatch): """Run linter in parallel mode using threads. Similar to test__linter__linting_result_get_violations but uses a thread pool of 1 worker to test parallel mode without subprocesses. This lets the tests capture code coverage information for the backend parts of parallel execution without having to jump through hoops. """ if not force_error: monkeypatch.setattr(Linter, "allow_process_parallelism", False) else: def _create_pool(*args, **kwargs): class ErrorPool: def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): pass def imap_unordered(self, *args, **kwargs): yield runner.DelayedException(ValueError()) return ErrorPool() monkeypatch.setattr(runner.MultiProcessRunner, "_create_pool", _create_pool) config = FluffConfig(overrides={"dialect": "ansi"}) output_stream = make_output_stream(config, None, os.devnull) lntr = Linter( formatter=OutputStreamFormatter(output_stream, False, verbosity=0), dialect="ansi", ) result = lntr.lint_paths( ("test/fixtures/linter/comma_errors.sql", ), processes=2, ) all([type(v) == SQLLintError for v in result.get_violations()])
def test__linter__linting_parallel_thread(force_error, monkeypatch): """Run linter in parallel mode using threads. Similar to test__linter__linting_result_get_violations but uses a thread pool of 1 worker to test parallel mode without subprocesses. This lets the tests capture code coverage information for the backend parts of parallel execution without having to jump through hoops. """ monkeypatch.setattr(Linter, "MIN_THRESHOLD_PARALLEL", 1) if not force_error: monkeypatch.setattr(Linter, "PARALLEL_CLS", runner.MultiThreadRunner) else: def _create_pool(*args, **kwargs): class ErrorPool: def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): pass def imap_unordered(self, *args, **kwargs): yield runner.DelayedException(ValueError()) return ErrorPool() monkeypatch.setattr(runner.MultiProcessRunner, "_create_pool", _create_pool) lntr = Linter( formatter=CallbackFormatter(callback=lambda m: None, verbosity=0)) result = lntr.lint_paths( ("test/fixtures/linter/comma_errors.sql", ), parallel=1, ) all([type(v) == SQLLintError for v in result.get_violations()])