use std::sync::Arc;
use monty::MontyRun;
use monty_types::{CompileOptions, ExcType, PrintWriter, ResourceLimits, ResourceTracker};
#[test]
fn non_ascii_earlier_line_does_not_shift_column() {
let code = "x = 'é'\nundefined_name".to_string();
let run = MontyRun::new(code, "test.py", vec![], CompileOptions::default()).expect("should parse");
let err = run.run_no_limits(vec![]).expect_err("should raise NameError");
assert_eq!(err.exc_type(), ExcType::NameError);
let frame = err.traceback().last().expect("traceback has at least one frame");
assert_eq!(frame.start.line, 2);
assert_eq!(frame.start.column, 1);
assert_eq!(frame.end.column, 15);
}
#[test]
fn non_ascii_char_column_location() {
let code = "'é' + undefined_name".to_string();
let run = MontyRun::new(code, "test.py", vec![], CompileOptions::default()).expect("should parse");
let err = run.run_no_limits(vec![]).expect_err("should raise NameError");
assert_eq!(err.exc_type(), ExcType::NameError);
let frame = err.traceback().last().expect("traceback has at least one frame");
assert_eq!(frame.start.line, 1);
assert_eq!(frame.start.column, 7);
assert_eq!(frame.end.column, 21);
}
#[test]
fn recursive_frames_share_preview_line_allocation() {
let code = r"
def recurse(n):
return recurse(n - 1)
recurse(50)
";
let run = MontyRun::new(code.to_string(), "test.py", vec![], CompileOptions::default()).expect("should parse");
let limits = ResourceLimits::default().max_recursion_depth(10);
let err = run
.run(vec![], ResourceTracker::new(limits), PrintWriter::Stdout)
.expect_err("should exceed recursion depth");
assert_eq!(err.exc_type(), ExcType::RecursionError);
let recurse_frames: Vec<_> = err
.traceback()
.iter()
.filter(|f| f.frame_name.as_deref() == Some("recurse"))
.collect();
assert!(
recurse_frames.len() >= 5,
"expected several recursive frames, got {}",
recurse_frames.len()
);
let first = recurse_frames[0].preview_line.as_ref().expect("preview line present");
for frame in &recurse_frames[1..] {
let other = frame.preview_line.as_ref().expect("preview line present");
assert!(
Arc::ptr_eq(first, other),
"frames at the same source line should share a single Arc<str> allocation",
);
}
}