/ dev / clint / tests / rules / test_os_chdir_in_test.py
test_os_chdir_in_test.py
  1  from pathlib import Path
  2  
  3  from clint.config import Config
  4  from clint.index import SymbolIndex
  5  from clint.linter import Position, Range, lint_file
  6  from clint.rules.os_chdir_in_test import OsChdirInTest
  7  
  8  
  9  def test_os_chdir_in_test(index: SymbolIndex) -> None:
 10      code = """
 11  import os
 12  
 13  # Bad
 14  def test_func():
 15      os.chdir("/tmp")
 16  
 17  # Good
 18  def non_test_func():
 19      os.chdir("/tmp")
 20  """
 21      config = Config(select={OsChdirInTest.name})
 22      violations = lint_file(Path("test_file.py"), code, config, index)
 23      assert len(violations) == 1
 24      assert all(isinstance(v.rule, OsChdirInTest) for v in violations)
 25      assert violations[0].range == Range(Position(5, 4))
 26  
 27  
 28  def test_os_chdir_in_test_with_from_import(index: SymbolIndex) -> None:
 29      code = """
 30  from os import chdir
 31  
 32  # Bad
 33  def test_func():
 34      chdir("/tmp")
 35  
 36  # Good
 37  def non_test_func():
 38      chdir("/tmp")
 39  """
 40      config = Config(select={OsChdirInTest.name})
 41      violations = lint_file(Path("test_file.py"), code, config, index)
 42      assert len(violations) == 1
 43      assert all(isinstance(v.rule, OsChdirInTest) for v in violations)
 44      assert violations[0].range == Range(Position(5, 4))
 45  
 46  
 47  def test_os_chdir_in_test_no_violation_outside_test(index: SymbolIndex) -> None:
 48      code = """
 49  import os
 50  
 51  def normal_function():
 52      os.chdir("/tmp")
 53  """
 54      config = Config(select={OsChdirInTest.name})
 55      violations = lint_file(Path("non_test_file.py"), code, config, index)
 56      assert len(violations) == 0
 57  
 58  
 59  def test_os_chdir_in_test_with_alias(index: SymbolIndex) -> None:
 60      code = """
 61  import os as operating_system
 62  
 63  # Bad - should still catch aliased import
 64  def test_func():
 65      operating_system.chdir("/tmp")
 66  """
 67      config = Config(select={OsChdirInTest.name})
 68      violations = lint_file(Path("test_file.py"), code, config, index)
 69      assert len(violations) == 1
 70      assert all(isinstance(v.rule, OsChdirInTest) for v in violations)
 71      assert violations[0].range == Range(Position(5, 4))
 72  
 73  
 74  def test_os_chdir_in_test_nested_functions_not_caught(index: SymbolIndex) -> None:
 75      """
 76      Nested functions are not considered to be "in test" - this matches
 77      the behavior of other test-specific rules like os.environ.
 78      """
 79      code = """
 80  import os
 81  
 82  def test_outer():
 83      def inner_function():
 84          os.chdir("/tmp")  # Not caught since inner_function is not a test function
 85      inner_function()
 86  """
 87      config = Config(select={OsChdirInTest.name})
 88      violations = lint_file(Path("test_file.py"), code, config, index)
 89      assert len(violations) == 0
 90  
 91  
 92  def test_os_chdir_not_os_module(index: SymbolIndex) -> None:
 93      code = """
 94  class FakeOs:
 95      @staticmethod
 96      def chdir(path):
 97          pass
 98  
 99  fake_os = FakeOs()
100  
101  def test_func():
102      fake_os.chdir("/tmp")  # Should not trigger since it's not os.chdir
103  """
104      config = Config(select={OsChdirInTest.name})
105      violations = lint_file(Path("test_file.py"), code, config, index)
106      assert len(violations) == 0