mutant_kraken/mutation_tool/
mutation.rs1use std::fmt::Display;
2
3use cli_table::Table;
4use uuid::Uuid;
5
6use crate::mutation_tool::MutationOperators;
7
8#[derive(Debug, Clone, serde::Serialize, PartialEq, Eq)]
9pub enum MutationResult {
10 InProgress,
11 Survived,
12 Killed,
13 BuildFailed,
14 Timeout,
15 Failed,
16}
17
18impl Display for MutationResult {
19 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20 match self {
21 MutationResult::InProgress => write!(f, "In Progress"),
22 MutationResult::Survived => write!(f, "Mutant Survived"),
23 MutationResult::Killed => write!(f, "Mutant Killed"),
24 MutationResult::BuildFailed => write!(f, "Build Failed"),
25 MutationResult::Timeout => write!(f, "Timeout"),
26 MutationResult::Failed => write!(f, "Failed"),
27 }
28 }
29}
30
31impl Default for MutationResult {
32 fn default() -> Self {
33 Self::InProgress
34 }
35}
36
37#[derive(Debug, Clone, Table, serde::Serialize)]
38pub struct Mutation {
40 #[table(title = "Id")]
42 #[serde(skip)]
43 pub id: Uuid,
44 #[table(skip)]
46 #[serde(skip)]
47 pub start_byte: usize,
48 #[table(skip)]
50 #[serde(skip)]
51 pub end_byte: usize,
52 #[table(title = "File Name")]
54 pub file_name: String,
55 #[table(title = "Line Number")]
57 pub line_number: usize,
58 #[table(title = "New Operator")]
60 pub new_op: String,
61 #[table(title = "Old Operator")]
63 pub old_op: String,
64 #[table(title = "Mutation Type")]
66 pub mutation_type: MutationOperators,
67 #[table(title = "Result")]
69 pub result: MutationResult,
70}
71
72impl Mutation {
73 pub fn new(
74 start_byte: usize,
75 end_byte: usize,
76 new_op: String,
77 old_op: String,
78 line_number: usize,
79 mutation_type: MutationOperators,
80 file_name: String,
81 ) -> Self {
82 Self {
83 start_byte,
84 end_byte,
85 line_number,
86 new_op,
87 old_op,
88 mutation_type,
89 id: Uuid::new_v4(),
90 result: MutationResult::default(),
91 file_name,
92 }
93 }
94}
95
96impl Display for Mutation {
97 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
98 write!(
99 f,
100 "
101 /**
102 AUTO GENERATED COMMENT
103 Mutation Operator: {}
104 Line number: {}
105 Id: {},
106 Old Operator: {},
107 New Operator: {}
108 */",
109 self.mutation_type,
110 (self.line_number + 9),
111 self.id,
112 self.old_op,
113 self.new_op
114 )
115 }
116}
117
118#[derive(Debug, Clone, serde::Serialize)]
119pub struct FileMutations {
120 pub mutations: Vec<Mutation>,
121}
122#[cfg(test)]
123mod tests {
124 use super::*;
125
126 #[test]
127 fn test_default_mutation_result() {
128 let default_result = MutationResult::default();
129 assert_eq!(default_result, MutationResult::InProgress);
130 }
131
132 #[test]
133 fn test_display_mutation_result() {
134 let result = MutationResult::Timeout;
135 let formatted_result = format!("{}", result);
136 assert_eq!(formatted_result, "Timeout");
137 }
138
139 #[test]
140 fn test_create_mutation() {
141 let mutation = Mutation::new(
142 10, 20, "new_op".to_string(),
145 "old_op".to_string(),
146 42, MutationOperators::ArithmeticReplacementOperator,
148 "example.rs".to_string(),
149 );
150
151 assert_eq!(mutation.start_byte, 10);
152 assert_eq!(mutation.end_byte, 20);
153 assert_eq!(mutation.new_op, "new_op");
154 assert_eq!(mutation.old_op, "old_op");
155 assert_eq!(mutation.line_number, 42);
156 assert_eq!(
157 mutation.mutation_type,
158 MutationOperators::ArithmeticReplacementOperator
159 );
160 assert_eq!(mutation.file_name, "example.rs");
161 assert_ne!(mutation.id, Uuid::nil()); assert_eq!(mutation.result, MutationResult::InProgress);
163 }
164
165 #[test]
166 fn test_display_mutation() {
167 let mutation = Mutation::new(
168 10, 20, "new_op".to_string(),
171 "old_op".to_string(),
172 42, MutationOperators::ArithmeticReplacementOperator,
174 "example.rs".to_string(),
175 );
176
177 let expected_output = format!(
178 "
179 /**
180 AUTO GENERATED COMMENT
181 Mutation Operator: ArithmeticReplacementOperator
182 Line number: {}
183 Id: {},
184 Old Operator: old_op,
185 New Operator: new_op
186 */",
187 (42 + 9),
188 mutation.id
189 );
190
191 assert_eq!(format!("{}", mutation), expected_output);
192 }
193
194 #[test]
195 fn test_create_file_mutations() {
196 let mutations = vec![
197 Mutation::new(
198 10, 20, "new_op1".to_string(),
201 "old_op1".to_string(),
202 42, MutationOperators::ArithmeticReplacementOperator,
204 "example.rs".to_string(),
205 ),
206 Mutation::new(
207 30, 40, "new_op2".to_string(),
210 "old_op2".to_string(),
211 56, MutationOperators::UnaryRemovalOperator,
213 "example.rs".to_string(),
214 ),
215 ];
216
217 let file_mutations = FileMutations { mutations };
218
219 assert_eq!(file_mutations.mutations.len(), 2);
220 }
222}