@@ -209,6 +209,44 @@ def test_extract_hist_ranges_empty_str():
209209 assert actual == expected
210210
211211
212+ @pytest .mark .parametrize (
213+ "instr,expected,description" ,
214+ [
215+ ("~4/" , [(- 4 , 1 , None )], "with trailing slash" ),
216+ ("~4" , [(- 4 , 1 , None )], "without trailing slash" ),
217+ ("~4/1-5" , [(- 4 , 1 , 6 )], "with line ranges and trailing slash" ),
218+ (
219+ "~4 ~5/ ~6/1-3" ,
220+ [(- 4 , 1 , None ), (- 5 , 1 , None ), (- 6 , 1 , 4 )],
221+ "multiple sessions with mixed syntax" ,
222+ ),
223+ ("~10 ~20/" , [(- 10 , 1 , None ), (- 20 , 1 , None )], "larger session numbers" ),
224+ ("~1" , [(- 1 , 1 , None )], "single digit session without slash" ),
225+ ("~1/" , [(- 1 , 1 , None )], "single digit session with slash" ),
226+ ("~2" , [(- 2 , 1 , None )], "backward compatibility without slash" ),
227+ ("~2/" , [(- 2 , 1 , None )], "backward compatibility with slash" ),
228+ ],
229+ )
230+ def test_extract_hist_ranges_without_trailing_slash (instr , expected , description ):
231+ """Test that ~N (without trailing slash) works and is backward compatible with ~N/"""
232+ actual = list (extract_hist_ranges (instr ))
233+ assert (
234+ actual == expected
235+ ), f"Failed for '{ instr } ' ({ description } ): expected { expected } , got { actual } "
236+
237+
238+ def test_extract_hist_ranges_backward_compatibility ():
239+ """Test that ~N and ~N/ produce identical results (backward compatibility)"""
240+ test_cases = ["~4" , "~5" , "~10" , "~20" ]
241+ for case in test_cases :
242+ result_no_slash = list (extract_hist_ranges (case ))
243+ result_with_slash = list (extract_hist_ranges (case + "/" ))
244+ assert result_no_slash == result_with_slash , (
245+ f"{ case } and { case } / should produce the same result, "
246+ f"got { result_no_slash } vs { result_with_slash } "
247+ )
248+
249+
212250def test_magic_rerun ():
213251 """Simple test for %rerun (no args -> rerun last line)"""
214252 ip = get_ipython ()
0 commit comments