use sashite_feen::{Feen, ParseError, Side};
fn summary(s: &str) -> Result<(Vec<u8>, u32, u32, Side, char), ParseError> {
let f = Feen::parse(s)?;
Ok((
f.shape().dimensions().to_vec(),
f.square_count(),
f.piece_count(),
f.active_side(),
f.active_style().to_char(),
))
}
fn err(s: &str) -> ParseError {
Feen::parse(s).unwrap_err()
}
#[test]
fn chess_start() {
let s = "-rnbqk^bn-r/+p+p+p+p+p+p+p+p/8/8/8/8/+P+P+P+P+P+P+P+P/-RNBQK^BN-R / W/w";
assert_eq!(summary(s).unwrap(), (vec![8, 8], 64, 32, Side::First, 'W'));
}
#[test]
fn shogi_start() {
let s = "lnsgk^gsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGK^GSNL / J/j";
assert_eq!(summary(s).unwrap(), (vec![9, 9], 81, 40, Side::First, 'J'));
}
#[test]
fn xiangqi_start() {
let s = "rheag^aehr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RHEAG^AEHR / C/c";
assert_eq!(summary(s).unwrap(), (vec![10, 9], 90, 32, Side::First, 'C'));
}
#[test]
fn empty_board() {
let s = "8/8/8/8/8/8/8/8 / W/w";
assert_eq!(summary(s).unwrap(), (vec![8, 8], 64, 0, Side::First, 'W'));
}
#[test]
fn with_hands() {
let s = "8/8/8/8/8/8/8/8 3P2B/3p2b W/w";
assert_eq!(summary(s).unwrap(), (vec![8, 8], 64, 10, Side::First, 'W'));
}
#[test]
fn one_dimensional() {
let s = "k^+p4+PK^ / C/c";
assert_eq!(summary(s).unwrap(), (vec![8], 8, 4, Side::First, 'C'));
}
#[test]
fn second_to_move() {
let s = "8/8/8/8/8/8/8/8 / w/W";
assert_eq!(summary(s).unwrap(), (vec![8, 8], 64, 0, Side::Second, 'w'));
}
#[test]
fn too_many_pieces() {
let s = "K^k^ 2K^/2k^ J/j"; assert_eq!(err(s), ParseError::TooManyPieces);
}
#[test]
fn exactly_full_board_is_ok() {
let s = "k^ / J/j"; assert_eq!(summary(s).unwrap(), (vec![1], 1, 1, Side::First, 'J'));
}
#[test]
fn empty_input() {
assert_eq!(err(""), ParseError::FieldCount);
}
#[test]
fn two_fields() {
assert_eq!(err("8/8 /"), ParseError::FieldCount);
}
#[test]
fn four_fields() {
assert_eq!(err("8 / W/w extra"), ParseError::FieldCount);
}
#[test]
fn leading_space() {
assert_eq!(err(" 8/8/8/8/8/8/8/8 / W/w"), ParseError::FieldCount);
}
#[test]
fn trailing_space() {
assert_eq!(err("8/8/8/8/8/8/8/8 / W/w "), ParseError::FieldCount);
}
#[test]
fn double_space() {
assert_eq!(err("8/8/8/8/8/8/8/8 / W/w"), ParseError::FieldCount);
}
#[test]
fn non_ascii() {
assert_eq!(err("8/8/8/8/8/8/8/8 / W/é"), ParseError::NonAscii);
}
#[test]
fn too_long() {
let big = "1".repeat(5000);
let s = format!("{big} / W/w");
assert_eq!(err(&s), ParseError::InputTooLong);
}
#[test]
fn placement_error_propagates() {
assert_eq!(err("rkr//PPPP / W/w"), ParseError::DimensionalCoherence);
}
#[test]
fn hands_error_propagates() {
assert_eq!(err("1 PP/ W/w"), ParseError::HandNotAggregated);
}
#[test]
fn style_error_propagates() {
assert_eq!(err("1 / W/W"), ParseError::StylesSameCase);
}
#[test]
fn newline_in_field_rejected() {
assert_eq!(
err("8/8/8/8/8/8/8/8 / W/w\n"),
ParseError::InvalidStyleToken
);
}