Coverage for nilearn/_utils/tests/test_logger.py: 0%

75 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-20 10:58 +0200

1"""Test the logger module. 

2 

3This test file is in nilearn/tests because Nosetest, 

4which we historically used, 

5ignores modules whose name starts with an underscore. 

6""" 

7 

8import contextlib 

9import sys 

10from io import StringIO 

11 

12import pytest 

13from sklearn.base import BaseEstimator 

14 

15from nilearn._utils.logger import ( 

16 _has_rich, 

17 find_stack_level, 

18 log, 

19 one_level_deeper, 

20) 

21 

22 

23# Helper functions and classes 

24def run(): 

25 log("function run()", stack_level=1) 

26 

27 

28def other_run(): 

29 # Test too large values for stack_level 

30 # stack_level should exceed testrunner's stack levels as well 

31 log("function other_run()", stack_level=100) 

32 

33 

34class Run3: 

35 def run3(self): 

36 log("method Test3", stack_level=1) 

37 run() 

38 

39 

40class Run2(BaseEstimator): 

41 def run2(self): 

42 log("method Test2", stack_level=1) 

43 t = Run1() 

44 t.run() 

45 

46 

47class Run1(BaseEstimator): 

48 def run(self): 

49 log("method Test", stack_level=1) 

50 run() 

51 

52 

53@pytest.mark.skipif(_has_rich(), reason="Skip test when rich is installed.") 

54def test_log_2_matching_object(capsys): 

55 t = Run2() 

56 t.run2() 

57 captured = capsys.readouterr() 

58 assert ( 

59 captured.out == "[Run2.run2] method Test2\n" 

60 "[Run2.run2] method Test\n" 

61 "[Run2.run2] function run()\n" 

62 ) 

63 

64 

65@pytest.mark.skipif(_has_rich(), reason="Skip test when rich is installed.") 

66def test_log_1_matching_object(capsys): 

67 t = Run1() 

68 t.run() 

69 captured = capsys.readouterr() 

70 assert captured.out == ( 

71 "[Run1.run] method Test\n[Run1.run] function run()\n" 

72 ) 

73 

74 

75@pytest.mark.skipif(_has_rich(), reason="Skip test when rich is installed.") 

76def test_log_no_matching_object(capsys): 

77 run() 

78 captured = capsys.readouterr() 

79 assert captured.out == "[run] function run()\n" 

80 

81 

82@pytest.mark.skipif(_has_rich(), reason="Skip test when rich is installed.") 

83def test_log_1_non_matching_object(capsys): 

84 t = Run3() 

85 t.run3() 

86 captured = capsys.readouterr() 

87 assert captured.out == "[Run3.run3] method Test3\n[run] function run()\n" 

88 

89 

90def test_find_stack_level(): 

91 """Test find_stack_level.""" 

92 assert find_stack_level() == 1 

93 assert one_level_deeper() == 2 

94 

95 

96def test_log_stack_lvl_stack_too_large(capsys): 

97 """Test rich and non rich output.""" 

98 other_run() 

99 captured = capsys.readouterr() 

100 if _has_rich(): 

101 from rich.console import Console 

102 

103 console = Console(file=StringIO(), width=120) 

104 console.print("[blue]\\[<top_level>][/blue] function other_run()") 

105 output = console.file.getvalue() 

106 assert captured.out == output 

107 else: 

108 assert captured.out == "[<top_level>] function other_run()\n" 

109 

110 

111@contextlib.contextmanager 

112def capture_output(): 

113 oldout, olderr = sys.stdout, sys.stderr 

114 try: 

115 out = [StringIO(), StringIO()] 

116 sys.stdout, sys.stderr = out 

117 yield out 

118 finally: 

119 sys.stdout, sys.stderr = oldout, olderr 

120 out[0] = out[0].getvalue() 

121 out[1] = out[1].getvalue() 

122 

123 

124# Will be executed by testrunner upon importing 

125with capture_output() as out: 

126 log("message from no function", stack_level=1) 

127 if _has_rich() is False: 

128 if isinstance(out[0], StringIO): 

129 assert out[0].getvalue() == "[<module>] message from no function\n" 

130 else: 

131 assert out[0] == "[<module>] message from no function\n"