Coverage for tests/unit/nbutils/test_conversion.py: 96%

47 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2025-04-04 03:33 -0600

1from __future__ import annotations 

2 

3import itertools 

4import subprocess 

5from pathlib import Path 

6import os 

7import sys 

8 

9import pytest 

10 

11from muutils.nbutils.convert_ipynb_to_script import process_dir, process_file 

12from muutils.nbutils.run_notebook_tests import run_notebook_tests 

13 

14notebooks_input_dir: Path = Path("tests/input_data/notebooks") 

15notebooks_converted_input_dir: Path = Path("tests/input_data/notebooks_converted/") 

16nb_test_dir: Path = Path("tests/_temp/run_notebook_tests") 

17nb_conversion_dir: Path = Path("tests/_temp/test_file_conversion") 

18 

19 

20def test_run_notebook_tests(): 

21 os.makedirs(nb_test_dir, exist_ok=True) 

22 print(os.listdir(notebooks_input_dir)) 

23 print(os.listdir(notebooks_converted_input_dir)) 

24 

25 # convert the notebooks 

26 process_dir( 

27 input_dir=notebooks_input_dir, 

28 output_dir=nb_test_dir, 

29 disable_plots=True, 

30 ) 

31 

32 # run the notebooks 

33 run_notebook_tests( 

34 notebooks_dir=notebooks_input_dir, 

35 converted_notebooks_temp_dir=nb_test_dir, 

36 run_python_cmd_fmt="python", 

37 ) 

38 

39 # assert output directory contents are identical 

40 output_files: list = sorted(os.listdir(notebooks_converted_input_dir)) 

41 assert sorted(os.listdir(nb_test_dir)) == output_files 

42 

43 for fname in output_files: 

44 with open(os.path.join(notebooks_converted_input_dir, fname), "r") as f: 

45 expected = f.read() 

46 with open(os.path.join(nb_test_dir, fname), "r") as f: 

47 actual = f.read() 

48 assert expected == actual 

49 

50 

51@pytest.mark.parametrize( 

52 "idx, args", 

53 enumerate( 

54 itertools.product( 

55 [True, False], 

56 [r"#%%", "#" + "=" * 50], 

57 [True, False], 

58 ["%", ("!", "#"), ("import", "return")], 

59 ) 

60 ), 

61) 

62def test_file_conversion(idx, args): 

63 os.makedirs(nb_conversion_dir, exist_ok=True) 

64 process_file( 

65 in_file=os.path.join(notebooks_input_dir, "dummy_notebook.ipynb"), 

66 out_file=os.path.join(nb_conversion_dir, f"dn-test-{idx}.py"), 

67 strip_md_cells=args[0], 

68 header_comment=args[1], 

69 disable_plots=args[2], 

70 filter_out_lines=args[3], 

71 ) 

72 

73 

74def test_cli(): 

75 """Test the CLI interface for run_notebook_tests""" 

76 # Setup 

77 nb_test_cli_dir: Path = Path("tests/_temp/run_notebook_tests_cli") 

78 os.makedirs(nb_test_cli_dir, exist_ok=True) 

79 

80 # First convert notebooks to test with 

81 process_dir( 

82 input_dir=notebooks_input_dir, 

83 output_dir=nb_test_cli_dir, 

84 disable_plots=True, 

85 ) 

86 

87 # Test successful case using sys.executable to ensure we use the right Python 

88 process = subprocess.run( 

89 [ 

90 sys.executable, 

91 "-m", 

92 "muutils.nbutils.run_notebook_tests", 

93 "--notebooks-dir", 

94 notebooks_input_dir, 

95 "--converted-notebooks-temp-dir", 

96 nb_test_cli_dir, 

97 "--run-python-cmd-fmt", 

98 "python", # Override to just use python directly 

99 ], 

100 capture_output=True, 

101 text=True, 

102 ) 

103 

104 if process.returncode != 0: 

105 print("STDOUT:", process.stdout) 

106 print("STDERR:", process.stderr) 

107 assert process.returncode == 0 

108 

109 # Test missing directory error 

110 process = subprocess.run( 

111 [ 

112 sys.executable, 

113 "-m", 

114 "muutils.nbutils.run_notebook_tests", 

115 "--notebooks-dir", 

116 "nonexistent_dir", 

117 "--converted-notebooks-temp-dir", 

118 nb_test_cli_dir, 

119 ], 

120 capture_output=True, 

121 text=True, 

122 ) 

123 assert process.returncode != 0 

124 assert "does not exist" in process.stderr 

125 

126 # Test missing converted notebooks error 

127 os.makedirs("tests/_temp/empty_dir", exist_ok=True) 

128 process = subprocess.run( 

129 [ 

130 sys.executable, 

131 "-m", 

132 "muutils.nbutils.run_notebook_tests", 

133 "--notebooks-dir", 

134 notebooks_input_dir, 

135 "--converted-notebooks-temp-dir", 

136 "tests/_temp/empty_dir", 

137 ], 

138 capture_output=True, 

139 text=True, 

140 ) 

141 assert process.returncode != 0 

142 assert "Did not find converted notebook" in process.stderr