|
1 | 1 | use libc::c_char;
|
2 |
| -use minesweeper::{FieldType, FlagResult, Game, GameLevel, OpenResult}; |
| 2 | +use minesweeper::{FieldInfo, FieldState, FieldType, FlagResult, Game, GameLevel, OpenResult}; |
3 | 3 | use std::cmp;
|
4 | 4 | use std::convert::TryFrom;
|
5 | 5 | use std::ptr;
|
@@ -307,6 +307,21 @@ pub extern "C" fn minesweeper_game_get_elapsed_seconds(
|
307 | 307 | *elapsed_seconds = elapsed_duration.as_secs();
|
308 | 308 | }
|
309 | 309 |
|
| 310 | +#[no_mangle] |
| 311 | +pub extern "C" fn minesweeper_game_get_field_info( |
| 312 | + game_ptr: *mut Game, |
| 313 | + row: GameSizeType, |
| 314 | + column: GameSizeType, |
| 315 | + field_info_ptr: *mut FieldInfo, |
| 316 | + c_ei_ptr: *mut CErrorInfo, |
| 317 | +) { |
| 318 | + initialize_to_ok!(c_ei_ptr); |
| 319 | + let game = get_ref_from_ptr!(game_ptr, c_ei_ptr); |
| 320 | + let field_info = get_mut_ref_from_ptr!(field_info_ptr, c_ei_ptr); |
| 321 | + |
| 322 | + *field_info = return_or_assign!(game.get_field_info(row, column), c_ei_ptr); |
| 323 | +} |
| 324 | + |
310 | 325 | #[cfg(test)]
|
311 | 326 | mod test {
|
312 | 327 | use super::*;
|
@@ -754,6 +769,22 @@ mod test {
|
754 | 769 | assert_eq!(FlagResult::AlreadyOpened, flag_result);
|
755 | 770 | destroy_game(&mut game_ptr);
|
756 | 771 | }
|
| 772 | + #[test] |
| 773 | + fn flag_with_too_big_indices() { |
| 774 | + let mut game_ptr = create_game(GameLevel::Beginner); |
| 775 | + let mut error_info = create_empty_error_info(); |
| 776 | + let mut flag_result = FlagResult::Flagged; |
| 777 | + |
| 778 | + let width = get_width(game_ptr); |
| 779 | + minesweeper_game_toggle_flag(game_ptr, 0, width, &mut flag_result, &mut error_info); |
| 780 | + assert_eq!(CError::UnexpectedError, error_info.error_code); |
| 781 | + |
| 782 | + error_info = create_empty_error_info(); |
| 783 | + let height = get_width(game_ptr); |
| 784 | + minesweeper_game_toggle_flag(game_ptr, height, 0, &mut flag_result, &mut error_info); |
| 785 | + assert_eq!(CError::UnexpectedError, error_info.error_code); |
| 786 | + destroy_game(&mut game_ptr); |
| 787 | + } |
757 | 788 |
|
758 | 789 | #[test]
|
759 | 790 | fn get_width_with_nullptr_as_game() {
|
@@ -966,4 +997,103 @@ mod test {
|
966 | 997 | assert_eq!(CError::UnexpectedError, error_info.error_code);
|
967 | 998 | destroy_game(&mut game_ptr);
|
968 | 999 | }
|
| 1000 | + |
| 1001 | + #[test] |
| 1002 | + fn get_field_info_opened() { |
| 1003 | + let mut error_info = create_empty_error_info(); |
| 1004 | + let mut game_ptr = create_game(GameLevel::Beginner); |
| 1005 | + let row = 0; |
| 1006 | + let col = 0; |
| 1007 | + let mut buffered_open_info = create_open_info_for(game_ptr); |
| 1008 | + |
| 1009 | + minesweeper_game_open( |
| 1010 | + game_ptr, |
| 1011 | + row, |
| 1012 | + col, |
| 1013 | + &mut buffered_open_info.data, |
| 1014 | + &mut error_info, |
| 1015 | + ); |
| 1016 | + assert_eq!(OpenResult::Ok, buffered_open_info.data.result); |
| 1017 | + |
| 1018 | + let mut field_info = FieldInfo { |
| 1019 | + state: FieldState::Flagged, |
| 1020 | + field_type: FieldType::Mine, |
| 1021 | + }; |
| 1022 | + |
| 1023 | + minesweeper_game_get_field_info(game_ptr, row, col, &mut field_info, &mut error_info); |
| 1024 | + |
| 1025 | + let expected_field_state = FieldState::Opened; |
| 1026 | + let mut expected_field_type = FieldType::Mine; |
| 1027 | + |
| 1028 | + let newly_opened_fields_length = |
| 1029 | + usize::try_from(buffered_open_info.data.newly_opened_fields_length).unwrap(); |
| 1030 | + |
| 1031 | + for newly_opened_field in buffered_open_info.buffer[0..newly_opened_fields_length].iter() { |
| 1032 | + if newly_opened_field.row == row && newly_opened_field.column == col { |
| 1033 | + expected_field_type = newly_opened_field.field_type.clone(); |
| 1034 | + break; |
| 1035 | + } |
| 1036 | + } |
| 1037 | + |
| 1038 | + assert_eq!(expected_field_state, field_info.state); |
| 1039 | + assert_eq!(expected_field_type, field_info.field_type); |
| 1040 | + destroy_game(&mut game_ptr); |
| 1041 | + } |
| 1042 | + |
| 1043 | + #[test] |
| 1044 | + fn get_field_info_with_nullptr_as_game() { |
| 1045 | + let mut field_info = FieldInfo { |
| 1046 | + state: FieldState::Closed, |
| 1047 | + field_type: FieldType::Empty, |
| 1048 | + }; |
| 1049 | + let mut error_info = create_empty_error_info(); |
| 1050 | + minesweeper_game_get_field_info( |
| 1051 | + std::ptr::null_mut(), |
| 1052 | + 0, |
| 1053 | + 0, |
| 1054 | + &mut field_info, |
| 1055 | + &mut error_info, |
| 1056 | + ); |
| 1057 | + assert_eq!(CError::NullPointerAsInput, error_info.error_code); |
| 1058 | + } |
| 1059 | + |
| 1060 | + #[test] |
| 1061 | + fn get_field_info_with_nullptr_as_flag_result() { |
| 1062 | + let mut game_ptr = create_game(GameLevel::Beginner); |
| 1063 | + let mut error_info = create_empty_error_info(); |
| 1064 | + minesweeper_game_get_field_info(game_ptr, 0, 0, std::ptr::null_mut(), &mut error_info); |
| 1065 | + assert_eq!(CError::NullPointerAsInput, error_info.error_code); |
| 1066 | + destroy_game(&mut game_ptr); |
| 1067 | + } |
| 1068 | + |
| 1069 | + #[test] |
| 1070 | + #[should_panic(expected = "Error info ptr is null!")] |
| 1071 | + fn get_field_info_with_nullptr_as_error_info_ptr() { |
| 1072 | + let game_ptr = create_game(GameLevel::Beginner); |
| 1073 | + let mut field_info = FieldInfo { |
| 1074 | + state: FieldState::Closed, |
| 1075 | + field_type: FieldType::Empty, |
| 1076 | + }; |
| 1077 | + minesweeper_game_get_field_info(game_ptr, 0, 0, &mut field_info, std::ptr::null_mut()); |
| 1078 | + } |
| 1079 | + |
| 1080 | + #[test] |
| 1081 | + fn get_field_info_with_too_big_indices() { |
| 1082 | + let mut game_ptr = create_game(GameLevel::Beginner); |
| 1083 | + let mut error_info = create_empty_error_info(); |
| 1084 | + let mut field_info = FieldInfo { |
| 1085 | + state: FieldState::Closed, |
| 1086 | + field_type: FieldType::Empty, |
| 1087 | + }; |
| 1088 | + |
| 1089 | + let width = get_width(game_ptr); |
| 1090 | + minesweeper_game_get_field_info(game_ptr, 0, width, &mut field_info, &mut error_info); |
| 1091 | + assert_eq!(CError::UnexpectedError, error_info.error_code); |
| 1092 | + |
| 1093 | + error_info = create_empty_error_info(); |
| 1094 | + let height = get_width(game_ptr); |
| 1095 | + minesweeper_game_get_field_info(game_ptr, height, 0, &mut field_info, &mut error_info); |
| 1096 | + assert_eq!(CError::UnexpectedError, error_info.error_code); |
| 1097 | + destroy_game(&mut game_ptr); |
| 1098 | + } |
969 | 1099 | }
|
0 commit comments