On this page:
5.1 Mutators that inject bugs in Racket code
arithmetic-op-swap
boolean-op-swap
comparison-op-swap
negate-conditionals
force-conditionals
replace-constants/  type-level
replace-constants/  similar
swap-arguments
delete-begin-result-expr
begin-drop
data-accessor-swap
nested-list-construction-swap
class-method-publicity-swap
delete-super-new
add-extra-class-method
replace-class-parent
swap-class-initializers
make-top-level-id-swap-mutator
make-method-id-swap-mutator
make-field-id-swap-mutator
5.2 Mutators that inject bugs in Typed Racket types
complex-type->Any
function-arg-swap
function-result-swap
struct-field-swap
class-field-swap

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.

Swaps arithmetic, boolean, and comparison operators.

Examples:
> (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)

Examples:
> (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)

replace-constants/type-level swaps constants with other constants that may have a different type, potentially causing type errors. In contrast, replace-constants/similar replaces constants with more similar constants, in order to minimize possible type errors.

Since these two mutators overlap, they most likely shouldn’t be used together (which would lead to duplicate mutants).

They are defined as:
(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)])

Swaps pairs of argument-position s-expressions (i.e. all subexpressions after the first).

Examples:
> (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)

delete-begin-result-expr deletes only the result expression from a begin, while begin-drop sequentially deletes every expression in a begin.

Since these two mutators overlap, they most likely shouldn’t be used together (which would lead to duplicate mutants).

Examples:
> (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)

Swap car and cdr with each other, or replace append with cons, respectively.

Several class-related mutators. The examples illustrate what they do.

Examples:
> (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)

Identifier-swapping dependent mutators, which swap identifiers defined within the module supplied to create the mutator.

Examples:
> (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🔗ℹ

Replaces a compound type with Any.

Examples:
> (complex-type->Any #'(List Number) 0)

(mutated

 #<syntax:/home/root/user/.local/share/racket/8.12/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.12/pkgs/mutate-mutators/mutators/type.rkt:53:4 Any>

 1)

> (complex-type->Any #'Number 0)

(mutated #<syntax:eval:3:0 Number> 0)

Swap argument- and result-position types under an arrow type. Optional and mandatory argument types are only swapped within each category for ->* types.

Examples:
> (function-arg-swap #'(-> A B C D) 0)

(mutated

 #<syntax:/home/root/user/.local/share/racket/8.12/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.12/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.12/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.12/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.12/pkgs/mutate-mutators/mutators/type.rkt:99:2 (-> A B C (values E D))>

 1)

Swap struct and class field types.

Examples:
> (struct-field-swap #'(struct s ([x : Integer] [y : String])) 0)

(mutated

 #<syntax:/home/root/user/.local/share/racket/8.12/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.12/pkgs/mutate-mutators/mutators/type.rkt:118:2 (init-field (x String) (y Integer))>

 1)