use kish::{ActionPath, Square};
#[test]
fn square_notation_format() {
let a1 = ActionPath::new_move(Square::A1, Square::A2, false);
assert!(a1.to_notation().starts_with("a1"));
let h1 = ActionPath::new_move(Square::H1, Square::H2, false);
assert!(h1.to_notation().starts_with("h1"));
let a8 = ActionPath::new_move(Square::A7, Square::A8, false);
assert!(a8.to_notation().starts_with("a7"));
let h8 = ActionPath::new_move(Square::H7, Square::H8, false);
assert!(h8.to_notation().starts_with("h7"));
}
#[test]
fn files_are_lowercase() {
for col in 0..8 {
let square = Square::try_from_u8(col).unwrap(); let notation = ActionPath::new_move(square, Square::A2, false);
let notation_str = notation.to_notation();
let first_char = notation_str.chars().next().unwrap();
assert!(first_char.is_ascii_lowercase(), "File should be lowercase");
assert!(('a'..='h').contains(&first_char), "File should be a-h");
}
}
#[test]
fn ranks_are_1_to_8() {
for row in 0..8 {
let square = Square::try_from_u8(row * 8).unwrap(); let notation = ActionPath::new_move(square, Square::H8, false);
let notation_str = notation.to_notation();
let second_char = notation_str.chars().nth(1).unwrap();
assert!(second_char.is_ascii_digit(), "Rank should be a digit");
assert!(('1'..='8').contains(&second_char), "Rank should be 1-8");
}
}
#[test]
fn non_capturing_move_format() {
let notation = ActionPath::new_move(Square::E3, Square::E4, false);
assert_eq!(notation.to_notation(), "e3-e4");
}
#[test]
fn sideways_move_format() {
let notation = ActionPath::new_move(Square::D4, Square::E4, false);
assert_eq!(notation.to_notation(), "d4-e4");
}
#[test]
fn single_capture_format() {
let notation = ActionPath::new_capture(Square::D4, &[Square::D6], false);
assert_eq!(notation.to_notation(), "d4xd6");
}
#[test]
fn multi_capture_format() {
let notation = ActionPath::new_capture(Square::B3, &[Square::D3, Square::D5], false);
assert_eq!(notation.to_notation(), "b3xd3xd5");
}
#[test]
fn promotion_format() {
let notation = ActionPath::new_move(Square::C7, Square::C8, true);
assert_eq!(notation.to_notation(), "c7-c8=K");
}
#[test]
fn capture_with_promotion_format() {
let notation = ActionPath::new_capture(Square::C6, &[Square::C8], true);
assert_eq!(notation.to_notation(), "c6xc8=K");
}
#[test]
fn example_simple_move() {
let notation = ActionPath::new_move(Square::E3, Square::E4, false);
assert_eq!(notation.to_notation(), "e3-e4");
}
#[test]
fn example_sideways_move() {
let notation = ActionPath::new_move(Square::D4, Square::E4, false);
assert_eq!(notation.to_notation(), "d4-e4");
}
#[test]
fn example_single_capture() {
let notation = ActionPath::new_capture(Square::D4, &[Square::D6], false);
assert_eq!(notation.to_notation(), "d4xd6");
}
#[test]
fn example_multi_capture() {
let notation = ActionPath::new_capture(Square::B3, &[Square::D3, Square::D5], false);
assert_eq!(notation.to_notation(), "b3xd3xd5");
}
#[test]
fn example_king_long_move() {
let notation = ActionPath::new_move(Square::A1, Square::A7, false);
assert_eq!(notation.to_notation(), "a1-a7");
}
#[test]
fn example_promotion() {
let notation = ActionPath::new_move(Square::C7, Square::C8, true);
assert_eq!(notation.to_notation(), "c7-c8=K");
}
#[test]
fn complex_multi_capture() {
let notation = ActionPath::new_capture(
Square::A1,
&[Square::A3, Square::C3, Square::C5, Square::E5],
false,
);
assert_eq!(notation.to_notation(), "a1xa3xc3xc5xe5");
assert_eq!(notation.path_len(), 5);
}
#[test]
fn complex_multi_capture_with_promotion() {
let notation = ActionPath::new_capture(Square::A5, &[Square::A7, Square::C7, Square::C8], true);
assert_eq!(notation.to_notation(), "a5xa7xc7xc8=K");
}
#[test]
fn notation_accessors() {
let notation = ActionPath::new_capture(Square::B3, &[Square::D3, Square::D5], false);
assert_eq!(notation.source(), Square::B3);
assert_eq!(notation.destination(), Square::D5);
assert!(notation.is_capture());
assert!(!notation.is_promotion());
assert_eq!(notation.path(), &[Square::B3, Square::D3, Square::D5]);
}
#[test]
fn notation_accessors_promotion() {
let notation = ActionPath::new_move(Square::C7, Square::C8, true);
assert_eq!(notation.source(), Square::C7);
assert_eq!(notation.destination(), Square::C8);
assert!(!notation.is_capture());
assert!(notation.is_promotion());
assert_eq!(notation.path_len(), 2);
}
#[test]
fn notation_display() {
let notation = ActionPath::new_capture(Square::D4, &[Square::D6], false);
assert_eq!(format!("{notation}"), "d4xd6");
}
#[test]
fn notation_write_to_buffer() {
let notation = ActionPath::new_capture(Square::B3, &[Square::D3, Square::D5], false);
let mut buf = [0u8; 52];
let len = notation.write_notation(&mut buf);
let result = std::str::from_utf8(&buf[..len]).unwrap();
assert_eq!(result, "b3xd3xd5");
}
#[test]
fn all_files_correct() {
let expected_files = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
for (col, expected_file) in expected_files.iter().enumerate() {
let square = Square::try_from_u8(col as u8).unwrap();
let notation = ActionPath::new_move(square, Square::A8, false);
let file = notation.to_notation().chars().next().unwrap();
assert_eq!(
file, *expected_file,
"File {col} should be '{expected_file}'"
);
}
}
#[test]
fn all_ranks_correct() {
let expected_ranks = ['1', '2', '3', '4', '5', '6', '7', '8'];
for (row, expected_rank) in expected_ranks.iter().enumerate() {
let square = Square::try_from_u8((row * 8) as u8).unwrap(); let notation = ActionPath::new_move(square, Square::H8, false);
let rank = notation.to_notation().chars().nth(1).unwrap();
assert_eq!(
rank, *expected_rank,
"Rank {row} should be '{expected_rank}'"
);
}
}
#[test]
fn notation_equality() {
let notation1 = ActionPath::new_move(Square::E3, Square::E4, false);
let notation2 = ActionPath::new_move(Square::E3, Square::E4, false);
let notation3 = ActionPath::new_move(Square::E3, Square::E5, false);
assert_eq!(notation1, notation2);
assert_ne!(notation1, notation3);
}
#[test]
fn notation_clone() {
let notation1 = ActionPath::new_capture(Square::D4, &[Square::D6], false);
let notation2 = notation1;
assert_eq!(notation1, notation2);
assert_eq!(notation1.to_notation(), notation2.to_notation());
}