use pasta_dsl::parser::{FileItem, GlobalSceneScope, Span, SpanError, parse_str};
fn get_global_scene_scopes(file: &pasta_dsl::parser::PastaFile) -> Vec<&GlobalSceneScope> {
file.items
.iter()
.filter_map(|item| {
if let FileItem::GlobalSceneScope(scene) = item {
Some(scene)
} else {
None
}
})
.collect()
}
#[test]
fn test_span_new_with_6_arguments() {
let span = Span::new(1, 5, 2, 10, 4, 20);
assert_eq!(span.start_line, 1);
assert_eq!(span.start_col, 5);
assert_eq!(span.end_line, 2);
assert_eq!(span.end_col, 10);
assert_eq!(span.start_byte, 4);
assert_eq!(span.end_byte, 20);
}
#[test]
fn test_span_default_initializes_all_to_zero() {
let span = Span::default();
assert_eq!(span.start_line, 0);
assert_eq!(span.start_col, 0);
assert_eq!(span.end_line, 0);
assert_eq!(span.end_col, 0);
assert_eq!(span.start_byte, 0);
assert_eq!(span.end_byte, 0);
}
#[test]
fn test_span_extract_source_returns_correct_slice() {
let source = "Hello, World!";
let span = Span::new(1, 1, 1, 6, 0, 5);
let result = span.extract_source(source);
assert!(result.is_ok());
assert_eq!(result.unwrap(), "Hello");
}
#[test]
fn test_span_extract_source_utf8_multibyte() {
let source = "こんにちは、世界!";
let span = Span::new(1, 1, 1, 3, 0, 6);
let result = span.extract_source(source);
assert!(result.is_ok());
assert_eq!(result.unwrap(), "こん");
}
#[test]
fn test_span_extract_source_out_of_bounds_error() {
let source = "Hello";
let span = Span::new(1, 1, 1, 20, 0, 100);
let result = span.extract_source(source);
assert!(result.is_err());
match result.unwrap_err() {
SpanError::OutOfBounds { .. } => {}
_ => panic!("Expected OutOfBounds error"),
}
}
#[test]
fn test_span_extract_source_reversed_offsets_error() {
let source = "こんにちは";
let span = Span::new(1, 4, 1, 2, 9, 3);
let result = span.extract_source(source);
assert!(result.is_err());
match result.unwrap_err() {
SpanError::OutOfBounds { start, end, .. } => {
assert_eq!(start, 9);
assert_eq!(end, 3);
}
_ => panic!("Expected OutOfBounds error"),
}
}
#[test]
fn test_span_extract_source_invalid_utf8_boundary() {
let source = "こんにちは";
let span = Span::new(1, 1, 1, 2, 1, 4);
let result = span.extract_source(source);
assert!(result.is_err());
match result.unwrap_err() {
SpanError::InvalidUtf8Boundary { .. } => {}
_ => panic!("Expected InvalidUtf8Boundary error"),
}
}
#[test]
fn test_span_extract_source_invalid_span() {
let source = "Hello";
let span = Span::default();
let result = span.extract_source(source);
assert!(result.is_err());
match result.unwrap_err() {
SpanError::InvalidSpan => {}
_ => panic!("Expected InvalidSpan error"),
}
}
#[test]
fn test_span_is_valid() {
let default_span = Span::default();
assert!(!default_span.is_valid());
let valid_span = Span::new(1, 1, 1, 5, 0, 5);
assert!(valid_span.is_valid());
let partial_span = Span::new(1, 1, 1, 5, 0, 0);
assert!(!partial_span.is_valid());
}
#[test]
fn test_span_byte_len() {
let span = Span::new(1, 1, 2, 10, 5, 25);
assert_eq!(span.byte_len(), 20);
let empty_span = Span::default();
assert_eq!(empty_span.byte_len(), 0);
}
#[test]
fn test_parser_span_has_byte_offsets_ascii() {
let source = "*挨拶\n Alice:Hello\n";
let ast = parse_str(source, "test.pasta").unwrap();
assert!(ast.span.start_byte < ast.span.end_byte);
assert_eq!(ast.span.start_byte, 0);
assert!(ast.span.end_byte > 0);
}
#[test]
fn test_parser_span_byte_offset_utf8() {
let source = "*挨拶\n 太郎:こんにちは\n";
let ast = parse_str(source, "test.pasta").unwrap();
let scenes = get_global_scene_scopes(&ast);
assert!(!scenes.is_empty());
let scene = &scenes[0];
assert!(scene.span.start_byte < scene.span.end_byte);
}
#[test]
fn test_parser_span_extract_source_matches_original() {
let source = "*挨拶\n Alice:Hello\n";
let ast = parse_str(source, "test.pasta").unwrap();
let extracted = ast.span.extract_source(source);
assert!(extracted.is_ok());
assert_eq!(extracted.unwrap(), source);
}