5 Pre-defined mutators
Two sets of pre-defined mutators are provided in a seperate package, mutate-mutators, documented in the following sections.
5.1 Mutators that inject bugs in Racket code
All of these mutators operate on the basis of datums, i.e. surface syntax, not binding information. This is intentional, to allow them to be used on unexpanded #lang racket code read from files.
(require mutate/mutators/code) | package: mutate-mutators |
mutator
mutator
mutator
> (arithmetic-op-swap #'+ 0) (mutated #<syntax:eval:1:0 -> 1)
> (arithmetic-op-swap #'- 0) (mutated #<syntax:eval:2:0 +> 1)
> (arithmetic-op-swap #'* 0) (mutated #<syntax:eval:3:0 /> 1)
> (arithmetic-op-swap #'quotient 0) (mutated #<syntax:eval:4:0 /> 1)
> (arithmetic-op-swap #'modulo 0) (mutated #<syntax:eval:5:0 /> 1)
> (arithmetic-op-swap #'add1 0) (mutated #<syntax:eval:6:0 sub1> 1)
> (arithmetic-op-swap #'sub1 0) (mutated #<syntax:eval:7:0 add1> 1)
> (boolean-op-swap #'and 0) (mutated #<syntax:eval:8:0 or> 1)
> (boolean-op-swap #'or 0) (mutated #<syntax:eval:9:0 and> 1)
> (comparison-op-swap #'< 0) (mutated #<syntax:eval:10:0 <=> 1)
> (comparison-op-swap #'<= 0) (mutated #<syntax:eval:11:0 <> 1)
> (comparison-op-swap #'<= 1) (mutated #<syntax:eval:12:0 => 2)
> (comparison-op-swap #'> 0) (mutated #<syntax:eval:13:0 >=> 1)
> (comparison-op-swap #'>= 0) (mutated #<syntax:eval:14:0 >> 1)
> (comparison-op-swap #'>= 1) (mutated #<syntax:eval:15:0 => 2)
> (comparison-op-swap #'= 0) (mutated #<syntax:eval:16:0 <=> 1)
> (comparison-op-swap #'= 1) (mutated #<syntax:eval:17:0 >=> 2)
mutator
mutator
> (negate-conditionals #'(if (yes?) 0 1) 0) (mutated #<syntax:eval:1:0 (if (not (yes?)) 0 1)> 1)
> (force-conditionals #'(if (yes?) 0 1) 0) (mutated #<syntax:eval:2:0 (if #t 0 1)> 1)
mutator
mutator
Since these two mutators overlap, they most likely shouldn’t be used together (which would lead to duplicate mutants).
(define-constant-mutator (replace-constants/type-level value) [(? boolean?) #:-> (not value)] [(? number?) #:-> (- value)] [(? integer?) #:-> (exact->inexact value)] [(and (? number?) (? zero?)) #:-> 1] [(and (? number?) (? (negate zero?))) #:-> 0] [(? real?) #:-> (* 1.0+0.0i value)] [(? boolean?) #:-> (if value 1 0)] [(? number?) #:-> #f] [(? string?) #:-> (string->bytes/utf-8 value)]) (define-constant-mutator (replace-constants/similar v) [1 #:-> 0] [(? integer?) #:-> (add1 v)] [(? number?) #:-> (- v)] [(? number?) #:-> (- -1 v)])
mutator
> (swap-arguments #'(f x 2 #t) 0) (mutated #<syntax:eval:1:0 (f 2 x #t)> 1)
> (swap-arguments #'(f x 2 #t) 1) (mutated #<syntax:eval:2:0 (f #t 2 x)> 2)
> (swap-arguments #'(f x 2 #t) 2) (mutated #<syntax:eval:3:0 (f x #t 2)> 3)
mutator
mutator
Since these two mutators overlap, they most likely shouldn’t be used together (which would lead to duplicate mutants).
> (delete-begin-result-expr #'(begin (first!) (second!) 'ok) 0) (mutated #<syntax:eval:1:0 (begin (first!) (second!))> 1)
> (begin-drop #'(begin (first!) (second!) 'ok) 0) (mutated #<syntax:eval:2:0 (begin (second!) (quote ok))> 1)
> (begin-drop #'(begin (first!) (second!) 'ok) 1) (mutated #<syntax:eval:3:0 (begin (first!) (quote ok))> 2)
> (begin-drop #'(begin (first!) (second!) 'ok) 2) (mutated #<syntax:eval:4:0 (begin (first!) (second!))> 3)
mutator
mutator
mutator
mutator
mutator
mutator
mutator
> (class-method-publicity-swap #'define/public 0) (mutated #<syntax:eval:1:0 define/private> 1)
> (delete-super-new #'super-new 0) (mutated #<syntax:eval:2:0 void> 1)
> (add-extra-class-method #'(class object% (super-new) (define/public (m x) x)) 0)
(mutated
#<syntax:eval:3:0 (class object% (define/public (a-nonexistant-method x) x) (super-new) (define/public (m x) x))>
1)
> (replace-class-parent #'(class button% (super-new) (define/public (m x) x)) 0)
(mutated
#<syntax:eval:4:0 (class object% (super-new) (define/public (m x) x))>
1)
> > (swap-class-initializers #'(instantiate my-class (42 'x) [a 5] [b "hi"]) 0)
(mutated
#<syntax:eval:5:0 (instantiate my-class ((quote x) 42) (a 5) (b "hi"))>
1)
> (swap-class-initializers #'(instantiate my-class (42 'x) [a 5] [b "hi"]) 1)
(mutated
#<syntax:eval:6:0 (instantiate my-class (42 (quote x)) (a "hi") (b 5))>
2)
> (swap-class-initializers #'(new my-class [a 5] [b "hi"] [c 'x]) 0) (mutated #<syntax:eval:7:0 (new my-class (a "hi") (b 5) (c (quote x)))> 1)
> (swap-class-initializers #'(new my-class [a 5] [b "hi"] [c 'x]) 1) (mutated #<syntax:eval:8:0 (new my-class (a (quote x)) (b "hi") (c 5))> 2)
> (swap-class-initializers #'(new my-class [a 5] [b "hi"] [c 'x]) 2) (mutated #<syntax:eval:9:0 (new my-class (a 5) (b (quote x)) (c "hi"))> 3)
mutator
make-top-level-id-swap-mutator : (dependent-mutator/c syntax?)
mutator
mutator
> (define tl-id-swap (make-top-level-id-swap-mutator #'(module test racket (#%module-begin (define x 5) (define y 10))))) > (tl-id-swap #'x 0) (mutated #<syntax:eval:1:0 y> 1)
> (tl-id-swap #'y 0) (mutated #<syntax:eval:1:0 x> 2)
> (tl-id-swap #'not-x-or-y 0) (mutated #<syntax:eval:4:0 not-x-or-y> 0)
>
> (define mtd-id-swap (make-method-id-swap-mutator #'(module test racket (#%module-begin (define c% (class object% (super-new) (define/public (foo x) x) (define/public (bar y) 42) (define/public (m z) 0))))))) > (mtd-id-swap #'foo 0) (mutated #<syntax:eval:5:0 bar> 3)
> (mtd-id-swap #'foo 1) (mutated #<syntax:eval:5:0 m> 2)
> (mtd-id-swap #'bar 0) (mutated #<syntax:eval:5:0 foo> 2)
> (mtd-id-swap #'m 0) (mutated #<syntax:eval:5:0 bar> 3)
> (mtd-id-swap #'not-a-method-id 0) (mutated #<syntax:eval:10:0 not-a-method-id> 0)
>
> (define field-id-swap (make-field-id-swap-mutator #'(module test racket (#%module-begin (define c% (class object% (super-new) (field [x 5] [y 42]))))))) > (field-id-swap #'x 0) (mutated #<syntax:eval:11:0 y> 1)
> (field-id-swap #'y 0) (mutated #<syntax:eval:11:0 x> 2)
> (field-id-swap #'not-x-or-y 0) (mutated #<syntax:eval:14:0 not-x-or-y> 0)
5.2 Mutators that inject bugs in Typed Racket types
(require mutate/mutators/type) | package: mutate-mutators |
mutator
> (complex-type->Any #'(List Number) 0)
(mutated
#<syntax:/home/root/user/.local/share/racket/8.16.0.4/pkgs/mutate-mutators/mutators/type.rkt:53:4 Any>
1)
> (complex-type->Any #'(-> String Integer) 0)
(mutated
#<syntax:/home/root/user/.local/share/racket/8.16.0.4/pkgs/mutate-mutators/mutators/type.rkt:53:4 Any>
1)
> (complex-type->Any #'Number 0) (mutated #<syntax:eval:3:0 Number> 0)
mutator
mutator
> (function-arg-swap #'(-> A B C D) 0)
(mutated
#<syntax:/home/root/user/.local/share/racket/8.16.0.4/pkgs/mutate-mutators/mutators/type.rkt:78:2 (-> B A C D)>
1)
> (function-arg-swap #'(-> A B C D) 1)
(mutated
#<syntax:/home/root/user/.local/share/racket/8.16.0.4/pkgs/mutate-mutators/mutators/type.rkt:78:2 (-> C B A D)>
2)
> (function-arg-swap #'(-> A B C D) 2)
(mutated
#<syntax:/home/root/user/.local/share/racket/8.16.0.4/pkgs/mutate-mutators/mutators/type.rkt:78:2 (-> A C B D)>
3)
> (function-arg-swap #'(->* (A B) (C) D) 0)
(mutated
#<syntax:/home/root/user/.local/share/racket/8.16.0.4/pkgs/mutate-mutators/mutators/type.rkt:82:2 (->* (B A) (C) D)>
1)
> (function-arg-swap #'(->* (A B) (C) D) 1) (mutated #<syntax:eval:5:0 (->* (A B) (C) D)> 1)
> (function-result-swap #'(-> A B C (values D E)) 0)
(mutated
#<syntax:/home/root/user/.local/share/racket/8.16.0.4/pkgs/mutate-mutators/mutators/type.rkt:99:2 (-> A B C (values E D))>
1)
mutator
mutator
> (struct-field-swap #'(struct s ([x : Integer] [y : String])) 0)
(mutated
#<syntax:/home/root/user/.local/share/racket/8.16.0.4/pkgs/mutate-mutators/mutators/type.rkt:108:2 (struct s ((x : String) (y : Integer)))>
1)
> (class-field-swap #'(init-field [x Integer] [y String]) 0)
(mutated
#<syntax:/home/root/user/.local/share/racket/8.16.0.4/pkgs/mutate-mutators/mutators/type.rkt:118:2 (init-field (x String) (y Integer))>
1)