Skip to content

Commit c0ffeea

Browse files
feat: test gen mut ident
1 parent c0ffeef commit c0ffeea

File tree

2 files changed

+123
-25
lines changed

2 files changed

+123
-25
lines changed

crates/forge/src/mutation/mutators/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub trait Mutator {
1919
fn is_applicable(&self, ctxt: &MutationContext<'_>) -> bool;
2020
}
2121

22+
#[derive(Debug)]
2223
pub struct MutationContext<'a> {
2324
pub span: Span,
2425
/// The expression to mutate

crates/forge/src/mutation/mutators/tests/assignement_mutator_test.rs

+122-25
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::mutation::{
22
mutant::{Mutant, MutationType},
33
mutators::{assignement_mutator::AssignmentMutator, MutationContext, Mutator},
44
visitor::AssignVarTypes,
5+
Session,
56
};
67
use solar_parse::{
78
ast::{
@@ -11,43 +12,35 @@ use solar_parse::{
1112
interface::BytePos,
1213
};
1314

14-
use num_bigint::BigInt;
15-
use std::path::PathBuf;
16-
17-
use crate::mutation::Session;
15+
use super::*;
1816

1917
fn create_span(start: u32, end: u32) -> Span {
2018
Span::new(BytePos(start), BytePos(end))
2119
}
2220

23-
fn create_ident<'ident>(ident: String) -> ExprKind<'ident> {
24-
ExprKind::Ident(Ident::from_str(&ident))
25-
}
26-
2721
#[test]
2822
fn test_is_applicable_for_assign_expr() {
29-
let sess = Session::builder().with_silent_emitter(None).build();
30-
31-
let _ = sess.enter(|| -> solar_parse::interface::Result<()> {
32-
let arena = Arena::new();
33-
let span = create_span(10, 20);
34-
35-
// x = 23
36-
let left = arena.alloc(Expr { kind: create_ident("x".into()), span });
23+
let arena = Arena::new();
24+
let span = create_span(10, 20);
3725

38-
let mut val = Lit { span, symbol: Symbol::DUMMY, kind: LitKind::Number(23.into()) };
26+
// x = 23
27+
let left = arena.alloc(Expr {
28+
kind: ExprKind::Ident(Ident { name: Symbol::DUMMY, span }), /* we use dummy symbol to
29+
* avoid having to enter a
30+
* session */
31+
span,
32+
});
3933

40-
let right = arena.alloc(Expr { kind: ExprKind::Lit(&mut val, None), span });
34+
let mut val = Lit { span, symbol: Symbol::DUMMY, kind: LitKind::Number(23.into()) };
4135

42-
let expr = arena.alloc(Expr { kind: ExprKind::Assign(left, None, right), span });
36+
let right = arena.alloc(Expr { kind: ExprKind::Lit(&mut val, None), span });
4337

44-
let context = MutationContext { expr: Some(expr), var_definition: None, span };
38+
let expr = arena.alloc(Expr { kind: ExprKind::Assign(left, None, right), span });
4539

46-
let mutator = AssignmentMutator;
47-
assert!(mutator.is_applicable(&context));
40+
let context = MutationContext { expr: Some(expr), var_definition: None, span };
4841

49-
Ok(())
50-
});
42+
let mutator = AssignmentMutator;
43+
assert!(mutator.is_applicable(&context));
5144
}
5245

5346
#[test]
@@ -79,7 +72,6 @@ fn test_is_applicable_for_var_definition() {
7972

8073
#[test]
8174
fn test_is_not_applicable_no_initializer() {
82-
let arena = Arena::new();
8375
let span = create_span(10, 20);
8476

8577
let var_def = VariableDefinition {
@@ -99,3 +91,108 @@ fn test_is_not_applicable_no_initializer() {
9991
let mutator = AssignmentMutator;
10092
assert!(!mutator.is_applicable(&context));
10193
}
94+
95+
#[test]
96+
fn test_generate_bool_mutants() {
97+
let arena = Arena::new();
98+
let span = create_span(10, 20);
99+
100+
let sess = Session::builder().with_silent_emitter(None).build();
101+
102+
let _ = sess.enter(|| -> solar_parse::interface::Result<()> {
103+
let mut val = Lit { span, symbol: Symbol::default(), kind: LitKind::Bool(true) };
104+
105+
let lit = arena.alloc(Expr { kind: ExprKind::Lit(&mut val, None), span });
106+
107+
let context = MutationContext { expr: Some(lit), var_definition: None, span };
108+
109+
let mutator = AssignmentMutator;
110+
let mutants = mutator.generate_mutants(&context).unwrap();
111+
112+
assert_eq!(mutants.len(), 1);
113+
114+
if let MutationType::Assignment(AssignVarTypes::Literal(LitKind::Bool(val))) =
115+
&mutants[0].mutation
116+
{
117+
assert_eq!(*val, false);
118+
} else {
119+
panic!("Expected boolean mutation");
120+
}
121+
Ok(())
122+
});
123+
}
124+
125+
#[test]
126+
fn test_generate_number_mutants() {
127+
let arena = Arena::new();
128+
let span = create_span(10, 20);
129+
130+
let mut val = Lit { span, symbol: Symbol::default(), kind: LitKind::Number(42.into()) };
131+
132+
let lit = arena.alloc(Expr { kind: ExprKind::Lit(&mut val, None), span });
133+
134+
let context = MutationContext { expr: Some(lit), var_definition: None, span };
135+
136+
let mutator = AssignmentMutator;
137+
let mutants = mutator.generate_mutants(&context).unwrap();
138+
139+
assert_eq!(mutants.len(), 2);
140+
141+
// First mutant should set to zero
142+
if let MutationType::Assignment(AssignVarTypes::Literal(LitKind::Number(val))) =
143+
&mutants[0].mutation
144+
{
145+
assert_eq!(*val, num_bigint::BigInt::ZERO);
146+
} else {
147+
panic!("Expected number mutation to zero");
148+
}
149+
150+
// Second mutant should negate the value
151+
if let MutationType::Assignment(AssignVarTypes::Literal(LitKind::Number(val))) =
152+
&mutants[1].mutation
153+
{
154+
assert_eq!(*val, -num_bigint::BigInt::from(42));
155+
} else {
156+
panic!("Expected negated number mutation");
157+
}
158+
}
159+
160+
#[test]
161+
fn test_generate_identifier_mutants() {
162+
let arena = Arena::new();
163+
let span = create_span(10, 20);
164+
165+
let sess = Session::builder().with_silent_emitter(None).build();
166+
167+
let _ = sess.enter(|| -> solar_parse::interface::Result<()> {
168+
let expr = arena.alloc(Expr {
169+
kind: ExprKind::Ident(Ident { name: Symbol::intern("varia"), span }),
170+
span,
171+
});
172+
173+
let context = MutationContext { expr: Some(expr), var_definition: None, span };
174+
175+
let mutator = AssignmentMutator;
176+
let mutants = mutator.generate_mutants(&context).unwrap();
177+
178+
assert_eq!(mutants.len(), 2);
179+
180+
// First mutant should set to zero
181+
if let MutationType::Assignment(AssignVarTypes::Literal(LitKind::Number(val))) =
182+
&mutants[0].mutation
183+
{
184+
assert_eq!(*val, num_bigint::BigInt::ZERO);
185+
} else {
186+
panic!("Expected number mutation to zero");
187+
}
188+
189+
// Second mutant should negate the identifier
190+
if let MutationType::Assignment(AssignVarTypes::Identifier(val)) = &mutants[1].mutation {
191+
assert_eq!(val, "-variable");
192+
} else {
193+
panic!("Expected negated identifier mutation");
194+
}
195+
196+
Ok(())
197+
});
198+
}

0 commit comments

Comments
 (0)