github.com/go-maxhub/gremlins@v1.0.1-0.20231227222204-b03a6a1e3e09/core/mutator/mutator.go (about)

     1  /*
     2   * Copyright 2022 The Gremlins Authors
     3   *
     4   *    Licensed under the Apache License, Version 2.0 (the "License");
     5   *    you may not use this file except in compliance with the License.
     6   *    You may obtain a copy of the License at
     7   *
     8   *        http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   *    Unless required by applicable law or agreed to in writing, software
    11   *    distributed under the License is distributed on an "AS IS" BASIS,
    12   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   *    See the License for the specific language governing permissions and
    14   *    limitations under the License.
    15   */
    16  
    17  package mutator
    18  
    19  import "go/token"
    20  
    21  // Status represents the status of a given TokenMutant.
    22  //
    23  //   - NotCovered means that a TokenMutant has been identified, but is not covered
    24  //     by tests.
    25  //   - Runnable means that a TokenMutant has been identified and is covered by tests,
    26  //     which means it can be executed.
    27  //   - Lived means that the TokenMutant has been tested, but the tests did pass, which
    28  //     means the test suite is not effective in catching it.
    29  //   - Killed means that the TokenMutant has been tested and the tests failed, which
    30  //     means they are effective in covering this regression.
    31  type Status int
    32  
    33  // Currently supported MutantStatus.
    34  const (
    35  	NotCovered Status = iota
    36  	Runnable
    37  	Skipped
    38  	Lived
    39  	Killed
    40  	NotViable
    41  	TimedOut
    42  )
    43  
    44  func (ms Status) String() string {
    45  	switch ms {
    46  	case NotCovered:
    47  		return "NOT COVERED"
    48  	case Runnable:
    49  		return "RUNNABLE"
    50  	case Skipped:
    51  		return "SKIPPED"
    52  	case Lived:
    53  		return "LIVED"
    54  	case Killed:
    55  		return "KILLED"
    56  	case NotViable:
    57  		return "NOT VIABLE"
    58  	case TimedOut:
    59  		return "TIMED OUT"
    60  	default:
    61  		panic("this should not happen")
    62  	}
    63  }
    64  
    65  // Type represents the category of the TokenMutant.
    66  //
    67  // A single token.Token can be mutated in various ways depending on the
    68  // specific mutation being tested.
    69  // For example `<` can be mutated to `<=` in case of ConditionalsBoundary
    70  // or `>=` in case of ConditionalsNegation.
    71  type Type int
    72  
    73  // The currently supported Type in Gremlins.
    74  const (
    75  	ArithmeticBase Type = iota
    76  	ConditionalsBoundary
    77  	ConditionalsNegation
    78  	IncrementDecrement
    79  	InvertAssignments
    80  	InvertBitwise
    81  	InvertBitwiseAssignments
    82  	InvertLogical
    83  	InvertLoopCtrl
    84  	InvertNegatives
    85  	RemoveSelfAssignments
    86  )
    87  
    88  // Types allows to iterate over Type.
    89  var Types = []Type{
    90  	ArithmeticBase,
    91  	ConditionalsBoundary,
    92  	ConditionalsNegation,
    93  	InvertAssignments,
    94  	InvertBitwise,
    95  	InvertBitwiseAssignments,
    96  	IncrementDecrement,
    97  	InvertLogical,
    98  	InvertLoopCtrl,
    99  	InvertNegatives,
   100  	RemoveSelfAssignments,
   101  }
   102  
   103  func (mt Type) String() string {
   104  	switch mt {
   105  	case ConditionalsBoundary:
   106  		return "CONDITIONALS_BOUNDARY"
   107  	case ConditionalsNegation:
   108  		return "CONDITIONALS_NEGATION"
   109  	case IncrementDecrement:
   110  		return "INCREMENT_DECREMENT"
   111  	case InvertLogical:
   112  		return "INVERT_LOGICAL"
   113  	case InvertNegatives:
   114  		return "INVERT_NEGATIVES"
   115  	case ArithmeticBase:
   116  		return "ARITHMETIC_BASE"
   117  	case InvertLoopCtrl:
   118  		return "INVERT_LOOPCTRL"
   119  	case InvertAssignments:
   120  		return "INVERT_ASSIGNMENTS"
   121  	case InvertBitwise:
   122  		return "INVERT_BITWISE"
   123  	case InvertBitwiseAssignments:
   124  		return "INVERT_BWASSIGN"
   125  	case RemoveSelfAssignments:
   126  		return "REMOVE_SELF_ASSIGNMENTS"
   127  
   128  	default:
   129  		panic("this should not happen")
   130  	}
   131  }
   132  
   133  // Mutator represents a possible mutation of the source code.
   134  type Mutator interface {
   135  	// Type returns the Type of the Mutator.
   136  	Type() Type
   137  
   138  	// SetType sets the Type of the Mutator.
   139  	SetType(mt Type)
   140  
   141  	// Status returns the Status of the Mutator.
   142  	Status() Status
   143  
   144  	// SetStatus sets the Status of the Mutator.
   145  	SetStatus(s Status)
   146  
   147  	// Position returns the token.Position for the Mutator.
   148  	// token.Position consumes more space than token.Pos, and in the future
   149  	// we can consider a refactoring to remove its use and only use Mutator.Pos.
   150  	Position() token.Position
   151  
   152  	// Pos returns the token.Pos of the Mutator.
   153  	Pos() token.Pos
   154  
   155  	// Pkg returns the package where the Mutator is fount.
   156  	Pkg() string
   157  
   158  	// SetWorkdir sets the working directory which contains the source code on
   159  	// which the Mutator will apply its mutations.
   160  	SetWorkdir(p string)
   161  
   162  	// Workdir returns the current working dir in which the Mutator will apply its mutations
   163  	Workdir() string
   164  
   165  	// Apply applies the mutation on the actual source code.
   166  	Apply() error
   167  
   168  	// Rollback removes the mutation from the source code and sets it back to
   169  	// its original status.
   170  	Rollback() error
   171  }