/ dev / clint / tests / rules / test_no_shebang.py
test_no_shebang.py
 1  from pathlib import Path
 2  
 3  import pytest
 4  from clint.config import Config
 5  from clint.index import SymbolIndex
 6  from clint.linter import Position, Range, lint_file
 7  from clint.rules import NoShebang
 8  
 9  
10  def test_no_shebang(index: SymbolIndex) -> None:
11      config = Config(select={NoShebang.name})
12  
13      # Test file with shebang - should trigger violation
14      code = "#!/usr/bin/env python\nprint('hello')"
15      results = lint_file(Path("test.py"), code, config, index)
16      assert len(results) == 1
17      assert all(isinstance(r.rule, NoShebang) for r in results)
18      assert results[0].range == Range(Position(0, 0))  # First line, first column (0-indexed)
19  
20      # Test file without shebang - should not trigger violation
21      code = "print('hello')"
22      results = lint_file(Path("test.py"), code, config, index)
23      assert len(results) == 0
24  
25  
26  @pytest.mark.parametrize(
27      "shebang",
28      [
29          "#!/usr/bin/env python",
30          "#!/usr/bin/python",
31          "#!/usr/bin/python3",
32          "#!/usr/bin/env python3",
33          "#! /usr/bin/env python",  # With space after #!
34      ],
35  )
36  def test_no_shebang_various_patterns(index: SymbolIndex, shebang: str) -> None:
37      config = Config(select={NoShebang.name})
38  
39      code = f"{shebang}\nprint('hello')\n"
40      results = lint_file(Path("test.py"), code, config, index)
41      assert all(isinstance(r.rule, NoShebang) for r in results)
42      assert results[0].range == Range(Position(0, 0))
43  
44  
45  @pytest.mark.parametrize(
46      "content",
47      [
48          "",
49          "   \n   \n",
50          '\n#!/usr/bin/env python\nprint("hello")\n',
51          "# This is a comment\nimport os\n",
52      ],
53      ids=[
54          "empty_file",
55          "whitespace_only",
56          "shebang_not_on_first_line",
57          "comment_not_shebang",
58      ],
59  )
60  def test_no_shebang_edge_cases(index: SymbolIndex, content: str) -> None:
61      config = Config(select={NoShebang.name})
62  
63      code = content
64      results = lint_file(Path("test.py"), code, config, index)
65      assert len(results) == 0