mutators/conditionalsBoundaryMutator.js

  1. const walk = require('babylon-walk')
  2. const debug = require('debug')('mutode:conditionalsBoundaryMutator')
  3. const mutantRunner = require('../mutantRunner')
  4. const lineDiff = require('../util/lineDiff')
  5. const operators = [
  6. ['<', '<='],
  7. ['<=', '<'],
  8. ['>', '>='],
  9. ['>=', '>']
  10. ]
  11. /**
  12. * @description The conditionals boundary mutator replaces the relational operators `<, <=, >, >=` with their boundary counterpart.
  13. * @function conditionalsBoundaryMutator
  14. * @memberOf module:Mutators
  15. */
  16. module.exports = async function conditionalsBoundaryMutator ({mutodeInstance, filePath, lines, queue, ast}) {
  17. debug('Running conditionals boundary mutator on %s', filePath)
  18. walk.simple(ast, {
  19. BinaryExpression (node) {
  20. for (const pair of operators) {
  21. if (node.operator !== pair[0]) {
  22. continue
  23. }
  24. const line = node.loc.start.line
  25. const lineContent = lines[line - 1]
  26. const mutantLineContent = lineContent.substr(0, node.loc.start.column) +
  27. lineContent.substr(node.loc.start.column, node.loc.end.column - node.loc.start.column).replace(pair[0], pair[1]) +
  28. lineContent.substr(node.loc.end.column)
  29. const mutantId = ++mutodeInstance.mutants
  30. const diff = lineDiff(lineContent, mutantLineContent)
  31. const log = `MUTANT ${mutantId}:\tCBM Line ${line}:\t${diff}`
  32. debug(log)
  33. mutodeInstance.mutantLog(`MUTANT ${mutantId}:\tCBM ${filePath} Line ${line}:\t\`${lineContent.trim()}\` > \`${mutantLineContent.trim()}'\``)
  34. const linesCopy = lines.slice()
  35. linesCopy[line - 1] = mutantLineContent
  36. const contentToWrite = linesCopy.join('\n')
  37. queue.push(mutantRunner({mutodeInstance, filePath, contentToWrite, log}))
  38. }
  39. }
  40. })
  41. }