#[cfg(test)] mod parser_tests { use sgf_parser::Action::Move; use sgf_parser::*; #[test] fn errors_on_invalid_root_token_placement() { let sgf = parse("(;KM[6.5];SZ[19])"); match sgf { Err(ref e) => assert_eq!(e.kind, SgfErrorKind::InvalidRootTokenPlacement), _ => assert!(false), } } #[test] fn can_parse_komi() { let sgf = parse("(;KM[6.5])"); assert!(sgf.is_ok()); let sgf = sgf.unwrap(); assert_eq!( sgf, GameTree { nodes: vec![GameNode { tokens: vec![SgfToken::Komi(6.5f32)] }], variations: vec![], } ); } #[test] fn can_ignore_lowercase_characters() { let sgf = parse("(;CopyRight[2017])"); assert!(sgf.is_ok()); let sgf = sgf.unwrap(); assert_eq!( sgf, GameTree { nodes: vec![GameNode { tokens: vec![SgfToken::Copyright("2017".to_string())], }], variations: vec![], } ); } #[test] fn can_parse_game_tree_single_node() { let sgf = parse("(;B[dc]BL[3498])"); assert!(sgf.is_ok()); let sgf = sgf.unwrap(); assert_eq!( sgf, GameTree { nodes: vec![GameNode { tokens: vec![ SgfToken::Move { color: Color::Black, action: Move(4, 3), }, SgfToken::Time { color: Color::Black, time: 3498, } ], }], variations: vec![], } ); } #[test] fn can_parse_game_tree_two_nodes() { let sgf = parse("(;B[dc];W[ef])"); assert!(sgf.is_ok()); let sgf = sgf.unwrap(); assert_eq!( sgf, GameTree { nodes: vec![ GameNode { tokens: vec![SgfToken::Move { color: Color::Black, action: Move(4, 3), }], }, GameNode { tokens: vec![SgfToken::Move { color: Color::White, action: Move(5, 6), }], } ], variations: vec![], } ); } #[test] fn can_parse_game_tree_simple_branch() { let sgf = parse("(;B[aa](;W[bb])(;W[cc]))"); assert!(sgf.is_ok()); let sgf = sgf.unwrap(); assert_eq!( sgf, GameTree { nodes: vec![GameNode { tokens: vec![SgfToken::Move { color: Color::Black, action: Move(1, 1), }], },], variations: vec![ GameTree { nodes: vec![GameNode { tokens: vec![SgfToken::Move { color: Color::White, action: Move(2, 2), }], },], variations: vec![], }, GameTree { nodes: vec![GameNode { tokens: vec![SgfToken::Move { color: Color::White, action: Move(3, 3), }], },], variations: vec![], } ], } ); } #[test] fn can_parse_game_information() { let sgf = parse("(;EV[event]PB[black]PW[white]C[comment];B[aa])"); assert!(sgf.is_ok()); let sgf = sgf.unwrap(); assert_eq!( sgf, GameTree { nodes: vec![ GameNode { tokens: vec![ SgfToken::Event("event".to_string()), SgfToken::PlayerName { color: Color::Black, name: "black".to_string(), }, SgfToken::PlayerName { color: Color::White, name: "white".to_string(), }, SgfToken::Comment("comment".to_string()), ], }, GameNode { tokens: vec![SgfToken::Move { color: Color::Black, action: Move(1, 1), }], } ], variations: vec![], } ); } #[test] fn can_parse_unkown_tags() { let sgf = parse("(;B[dc];FO[asdf];W[ef])"); assert!(sgf.is_ok()); let sgf = sgf.unwrap(); assert_eq!( sgf, GameTree { nodes: vec![ GameNode { tokens: vec![SgfToken::Move { color: Color::Black, action: Move(4, 3), }], }, GameNode { tokens: vec![SgfToken::Unknown(("FO".to_string(), "asdf".to_string())),], }, GameNode { tokens: vec![SgfToken::Move { color: Color::White, action: Move(5, 6), }], } ], variations: vec![], } ); } #[test] fn can_parse_wrapped_comment() { let sgf = parse("(;C[a [wrapped\\] comment])"); assert!(sgf.is_ok()); let sgf = sgf.unwrap(); assert_eq!( sgf, GameTree { nodes: vec![GameNode { tokens: vec![SgfToken::Comment("a [wrapped\\] comment".to_string()),], },], variations: vec![], } ); } #[test] fn can_parse_multiple_property_values_to_one_identifier() { let sgf = parse("(;AB[aa][ab][cc])"); assert!(sgf.is_ok()); let sgf = sgf.unwrap(); assert_eq!( sgf, GameTree { nodes: vec![GameNode { tokens: vec![ SgfToken::Add { color: Color::Black, coordinate: (1, 1) }, SgfToken::Add { color: Color::Black, coordinate: (1, 2) }, SgfToken::Add { color: Color::Black, coordinate: (3, 3) }, ], },], variations: vec![], } ); } }