diff --git a/src/lib.rs b/src/lib.rs index ec2bc62..9896c49 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -184,9 +184,8 @@ impl Matrix { return Err(MatrixError::InvalidDataSize); } - for i in 0..self.columns { - self.data.insert((i * self.columns) + i, data[i]); - } + let pos = index * self.columns; + self.data.splice(pos..pos, data); self.rows += 1; @@ -202,7 +201,7 @@ impl Matrix { return Err(MatrixError::IndexOutOfRange); } - if end.0 >= self.rows || end.1 >= self.columns { + if end.0 > self.rows || end.1 > self.columns { return Err(MatrixError::IndexOutOfRange); } @@ -219,8 +218,8 @@ impl Matrix { } let new_matrix = Matrix { - rows: (end.0 + 1) - start.0, - columns: (end.1 + 1) - start.1, + rows: end.0 - start.0, + columns: end.1 - start.1, data: new_data, }; @@ -1870,4 +1869,263 @@ mod tests { vec![Fraction::from(1), Fraction::from(9), Fraction::from(2),] ); } + + #[test] + fn test_insert_row_basic_middle() { + let mut m = Matrix { + rows: 2, + columns: 2, + data: vec![ + Fraction::from(1), + Fraction::from(2), + Fraction::from(3), + Fraction::from(4), + ], + }; + + let new_row = vec![Fraction::from(9), Fraction::from(9)]; + + m.insert_rows(1, new_row.clone()).unwrap(); + + assert_eq!(m.rows, 3); + + assert_eq!(m.get_row(1).unwrap().cloned().collect::>(), new_row); + } + + #[test] + fn test_insert_row_at_start() { + let mut m = Matrix::new(2, 2, Fraction::from(1)).unwrap(); + + let new_row = vec![Fraction::from(5), Fraction::from(6)]; + + m.insert_rows(0, new_row.clone()).unwrap(); + + assert_eq!(m.get_row(0).unwrap().cloned().collect::>(), new_row); + } + + #[test] + fn test_insert_row_invalid_index() { + let mut m = Matrix::new(2, 2, Fraction::from(0)).unwrap(); + + let data = vec![Fraction::from(1), Fraction::from(2)]; + + let result = m.insert_rows(2, data); + + assert!(matches!(result, Err(MatrixError::RowOutOfRange))); + } + + #[test] + fn test_insert_row_invalid_size() { + let mut m = Matrix::new(2, 3, Fraction::from(0)).unwrap(); + + let data = vec![Fraction::from(1), Fraction::from(2)]; + + let result = m.insert_rows(1, data); + + assert!(matches!(result, Err(MatrixError::InvalidDataSize))); + } + + #[test] + fn test_insert_row_preserves_other_rows() { + let mut m = Matrix { + rows: 2, + columns: 2, + data: vec![ + Fraction::from(1), + Fraction::from(2), + Fraction::from(3), + Fraction::from(4), + ], + }; + + let new_row = vec![Fraction::from(9), Fraction::from(9)]; + + m.insert_rows(1, new_row).unwrap(); + + assert_eq!( + m.get_row(0).unwrap().cloned().collect::>(), + vec![Fraction::from(1), Fraction::from(2)] + ); + + assert_eq!( + m.get_row(2).unwrap().cloned().collect::>(), + vec![Fraction::from(3), Fraction::from(4)] + ); + } + + #[test] + fn test_insert_row_multiple_times() { + let mut m = Matrix::new(2, 2, Fraction::from(0)).unwrap(); + + let r1 = vec![Fraction::from(1), Fraction::from(1)]; + let r2 = vec![Fraction::from(2), Fraction::from(2)]; + + m.insert_rows(1, r1).unwrap(); + m.insert_rows(2, r2.clone()).unwrap(); + + assert_eq!(m.get_row(2).unwrap().cloned().collect::>(), r2); + } + + #[test] + fn test_insert_row_consistency_with_get() { + let mut m = Matrix::new(2, 3, Fraction::from(0)).unwrap(); + + let new_row = vec![Fraction::from(10), Fraction::from(20), Fraction::from(30)]; + + m.insert_rows(1, new_row.clone()).unwrap(); + + for (i, val) in new_row.iter().enumerate() { + assert_eq!(*m.get(1, i).unwrap(), *val); + } + } + + #[test] + fn test_insert_row_single_column() { + let mut m = Matrix { + rows: 2, + columns: 1, + data: vec![Fraction::from(1), Fraction::from(2)], + }; + + let new_row = vec![Fraction::from(9)]; + + m.insert_rows(1, new_row).unwrap(); + + assert_eq!( + m.data, + vec![Fraction::from(1), Fraction::from(9), Fraction::from(2),] + ); + } + + #[test] + fn test_sub_matrix_basic() { + let m = Matrix { + rows: 3, + columns: 3, + data: vec![ + Fraction::from(1), + Fraction::from(2), + Fraction::from(3), + Fraction::from(4), + Fraction::from(5), + Fraction::from(6), + Fraction::from(7), + Fraction::from(8), + Fraction::from(9), + ], + }; + + let sub = m.sub_matrix((0, 0), (2, 2)).unwrap(); + + // Esperado (end exclusivo): + assert_eq!(sub.rows, 2); + assert_eq!(sub.columns, 2); + + assert_eq!( + sub.data, + vec![ + Fraction::from(1), + Fraction::from(2), + Fraction::from(4), + Fraction::from(5), + ] + ); + } + + #[test] + fn test_sub_matrix_middle() { + let m = Matrix { + rows: 4, + columns: 4, + data: (1..=16).map(Fraction::from).collect(), + }; + + let sub = m.sub_matrix((1, 1), (3, 3)).unwrap(); + + assert_eq!(sub.rows, 2); + assert_eq!(sub.columns, 2); + + assert_eq!( + sub.data, + vec![ + Fraction::from(6), + Fraction::from(7), + Fraction::from(10), + Fraction::from(11), + ] + ); + } + + #[test] + fn test_sub_matrix_single_element() { + let m = Matrix::new(3, 3, Fraction::from(5)).unwrap(); + + let sub = m.sub_matrix((1, 1), (2, 2)).unwrap(); + + assert_eq!(sub.rows, 1); + assert_eq!(sub.columns, 1); + assert_eq!(sub.data, vec![Fraction::from(5)]); + } + + #[test] + fn test_sub_matrix_invalid_start() { + let m = Matrix::new(2, 2, Fraction::from(0)).unwrap(); + + let result = m.sub_matrix((2, 0), (3, 1)); + + assert!(matches!(result, Err(MatrixError::IndexOutOfRange))); + } + + #[test] + fn test_sub_matrix_invalid_end() { + let m = Matrix::new(2, 2, Fraction::from(0)).unwrap(); + + let result = m.sub_matrix((0, 0), (3, 3)); + + assert!(matches!(result, Err(MatrixError::IndexOutOfRange))); + } + + #[test] + fn test_sub_matrix_invalid_range() { + let m = Matrix::new(3, 3, Fraction::from(0)).unwrap(); + + let result = m.sub_matrix((2, 2), (1, 1)); + + assert!(matches!(result, Err(MatrixError::IndexOutOfRange))); + } + + #[test] + fn test_sub_matrix_full_copy() { + let m = Matrix { + rows: 2, + columns: 2, + data: vec![ + Fraction::from(1), + Fraction::from(2), + Fraction::from(3), + Fraction::from(4), + ], + }; + + let sub = m.sub_matrix((0, 0), (2, 2)).unwrap(); + + assert_eq!(sub.data, m.data); + } + + #[test] + fn test_sub_matrix_consistency_with_get() { + let m = Matrix { + rows: 3, + columns: 3, + data: (0..9).map(Fraction::from).collect(), + }; + + let sub = m.sub_matrix((0, 0), (3, 3)).unwrap(); + + for r in 0..sub.rows { + for c in 0..sub.columns { + assert_eq!(*sub.get(r, c).unwrap(), *m.get(r, c).unwrap()); + } + } + } }