use super::*;
use crate::tokenizer::{state::TokenContext, tokens::TokenType};
#[cfg(not(feature = "std"))]
use alloc::{format, vec};
#[test]
fn char_navigator_error_recovery() {
let source = "a";
let mut nav = CharNavigator::new(source, 0, 1, 1);
nav.advance_char().unwrap();
assert!(nav.is_at_end());
assert!(nav.advance_char().is_err());
assert!(nav.peek_char().is_err());
}
#[test]
fn char_navigator_peek_char_caching() {
let source = "hello";
let mut nav = CharNavigator::new(source, 0, 1, 1);
assert_eq!(nav.peek_char().unwrap(), 'h');
assert_eq!(nav.peek_char().unwrap(), 'h');
assert_eq!(nav.peek_char().unwrap(), 'h');
nav.advance_char().unwrap();
assert_eq!(nav.peek_char().unwrap(), 'e');
}
#[test]
fn char_navigator_last_char_tracking() {
let source = "a\r\nb";
let mut nav = CharNavigator::new(source, 0, 1, 1);
nav.advance_char().unwrap(); nav.advance_char().unwrap(); assert_eq!(nav.line(), 2);
nav.advance_char().unwrap(); assert_eq!(nav.line(), 2);
assert_eq!(nav.column(), 1);
}
#[test]
fn token_scanner_hex_value_edge_cases() {
assert!(!TokenScanner::is_hex_value("FF"));
assert!(!TokenScanner::is_hex_value("00"));
assert!(!TokenScanner::is_hex_value("ABCDEF"));
assert!(!TokenScanner::is_hex_value("123456"));
assert!(TokenScanner::is_hex_value("&HFF&"));
assert!(TokenScanner::is_hex_value("&HFF"));
assert!(TokenScanner::is_hex_value("&H00FF00FF&"));
assert!(TokenScanner::is_hex_value("&H00FF00FF"));
assert!(!TokenScanner::is_hex_value("F")); assert!(!TokenScanner::is_hex_value("GG")); assert!(!TokenScanner::is_hex_value("&H&")); assert!(!TokenScanner::is_hex_value("&HG&")); assert!(!TokenScanner::is_hex_value("")); }
#[test]
fn scan_text_classification_verification() {
let source1 = "0:00:30.50";
let mut scanner1 = TokenScanner::new(source1, 0, 1, 1);
let token_type1 = scanner1.scan_text(TokenContext::FieldValue).unwrap();
assert_eq!(token_type1, TokenType::Text);
let source2 = "123abc";
let mut scanner2 = TokenScanner::new(source2, 0, 1, 1);
let token_type2 = scanner2.scan_text(TokenContext::Document).unwrap();
assert_eq!(token_type2, TokenType::Text);
let source3 = "&H00FF00&";
let mut scanner3 = TokenScanner::new(source3, 0, 1, 1);
let token_type3 = scanner3.scan_text(TokenContext::Document).unwrap();
assert_eq!(token_type3, TokenType::HexValue);
}
#[test]
fn token_scanner_delimiter_combinations() {
let source = "text:{}[],more";
let mut scanner = TokenScanner::new(source, 0, 1, 1);
let token_type = scanner.scan_text(TokenContext::Document).unwrap();
assert_eq!(token_type, TokenType::Text);
assert_eq!(scanner.navigator().position(), 4); }
#[test]
fn token_scanner_field_value_delimiter_handling() {
let source = "0:00:30.50";
let mut scanner = TokenScanner::new(source, 0, 1, 1);
let token_type = scanner.scan_text(TokenContext::FieldValue).unwrap();
assert_eq!(token_type, TokenType::Text); assert_eq!(scanner.navigator().position(), source.len()); }
#[test]
fn token_scanner_semicolon_context_sensitivity() {
let source = "text;comment";
let mut scanner1 = TokenScanner::new(source, 0, 1, 1);
let token_type1 = scanner1.scan_text(TokenContext::Document).unwrap();
assert_eq!(token_type1, TokenType::Text);
assert!(scanner1.navigator().position() >= 4);
let mut scanner2 = TokenScanner::new(source, 0, 1, 1);
let token_type2 = scanner2.scan_text(TokenContext::FieldValue).unwrap();
assert_eq!(token_type2, TokenType::Text);
assert_eq!(scanner2.navigator().position(), source.len());
}
#[test]
fn token_scanner_number_detection_edge_cases() {
let test_cases = vec![
("123", true),
("123.45", true),
("-123", true),
("-123.45", true),
("123.", true),
(".45", true),
("-.45", true),
("123abc", false), ("", false), (".", true), ("-", true), ("--123", true), ("12.34.56", true), ];
for (input, expected_is_number) in test_cases {
let source = format!("{input},");
let mut scanner = TokenScanner::new(&source, 0, 1, 1);
let token_type = scanner.scan_text(TokenContext::Document).unwrap();
if expected_is_number && !input.is_empty() {
assert_eq!(token_type, TokenType::Number, "Failed for input: {input}");
} else {
assert_ne!(token_type, TokenType::Number, "Failed for input: {input}");
}
}
}
#[test]
fn token_scanner_style_override_brace_depth() {
let source = "{{{{}}}}";
let mut scanner = TokenScanner::new(source, 0, 1, 1);
let token_type = scanner.scan_style_override().unwrap();
assert_eq!(token_type, TokenType::OverrideBlock);
assert_eq!(scanner.navigator().position(), 7); }
#[test]
fn token_scanner_style_override_unbalanced() {
let source = "{{{}}"; let mut scanner = TokenScanner::new(source, 0, 1, 1);
let token_type = scanner.scan_style_override().unwrap();
assert_eq!(token_type, TokenType::OverrideBlock);
assert_eq!(scanner.navigator().position(), source.len());
}