Stryker

MutatorOrchestrator.js - Stryker report

Summary

File Based on all code Based on code coverage
MutatorOrchestrator.js
100%
47/47 100% 47/47

Code

"use strict";
var _ = require('lodash');
var BlockStatementMutator_1 = require('./mutators/BlockStatementMutator');
var ConditionalBoundaryMutator_1 = require('./mutators/ConditionalBoundaryMutator');
var MathMutator_1 = require('./mutators/MathMutator');
var RemoveConditionalsMutator_1 = require('./mutators/RemoveConditionalsMutator');
var ReverseConditionalMutator_1 = require('./mutators/ReverseConditionalMutator');
var UnaryOperatorMutator_1 = require('./mutators/UnaryOperatorMutator');
var mutant_1 = require('stryker-api/mutant');
var fileUtils = require('./utils/fileUtils');
var Mutant_1 = require('./Mutant');
var parserUtils = require('./utils/parserUtils');
var log4js = require('log4js');
var objectUtils_1 = require('./utils/objectUtils');
var log = log4js.getLogger('Mutator');
/**
 * Class capable of finding spots to mutate in files.
 */
var MutatorOrchestrator = (function () 0{
    /**
     * @param reporter - The reporter to report read input files to
     */
    function MutatorOrchestrator(reporter) 1{
        var _this = this;
        this.reporter = reporter;
        this.mutators = [];
        this.registerDefaultMutators();
        var mutatorFactory = mutant_1.MutatorFactory.instance();
        mutatorFactory.knownNames().forEach(function (name) 2{ return _this.mutators.push(mutatorFactory.create(name, null)); });
    }

    /**
     * Mutates source files. Mutated code is not writen to disk.
     * @function
     * @param sourceFiles - The list of files which should be mutated.
     * @returns {Mutant[]} The generated Mutants.
     */
    MutatorOrchestrator.prototype.generateMutants = function (sourceFiles) 3{
        var _this = this;
        var mutants = [];
        this.sourceFiles = [];
        sourceFiles.forEach(function (sourceFile) 4{
            try 5{
                var fileContent = fileUtils.readFile(sourceFile);
                _this.reportFileRead(sourceFile, fileContent);
                var abstractSyntaxTree = parserUtils.parse(fileContent);
                var nodes = parserUtils.collectFrozenNodes(abstractSyntaxTree);
                var newMutants = _this.findMutants(sourceFile, fileContent, abstractSyntaxTree, nodes);
                mutants = mutants.concat(newMutants);
            }

            catch (err) 6{
                switch (err.code) {
                    case 'ENOENT':
                        log.info(78"Skipping file " + err.path + " because it does not exist");
                        break;
                    default:
                        console.log(err);
                        throw err;
                }
            }

        });
        this.reportAllFilesRead();
        return mutants;
    };
    ;
    MutatorOrchestrator.prototype.reportFileRead = function (path, content) 9{
        var fileToReport = { path: path, content: content };
        objectUtils_1.freezeRecursively(fileToReport);
        this.sourceFiles.push(fileToReport);
        this.reporter.onSourceFileRead(fileToReport);
    };
    MutatorOrchestrator.prototype.reportAllFilesRead = function () 10{
        objectUtils_1.freezeRecursively(this.sourceFiles);
        this.reporter.onAllSourceFilesRead(this.sourceFiles);
    };
    MutatorOrchestrator.prototype.registerDefaultMutators = function () 11{
        var mutatorFactory = mutant_1.MutatorFactory.instance();
        mutatorFactory.register('BlockStatement', BlockStatementMutator_1.default);
        mutatorFactory.register('ConditionalBoundary', ConditionalBoundaryMutator_1.default);
        mutatorFactory.register('Math', MathMutator_1.default);
        mutatorFactory.register('RemoveConditionals', RemoveConditionalsMutator_1.default);
        mutatorFactory.register('ReverseConditional', ReverseConditionalMutator_1.default);
        mutatorFactory.register('UnaryOperator', UnaryOperatorMutator_1.default);
    };
    /**
     * Finds all mutants for a given set of nodes.
     * @function
     * @param {String} sourceFile - The name source file.
     * @param {String} originalCode - The original content of the file which has not been mutated.
     * @param {Object} ast - The original abstract syntax tree which is used for reference when generating code.
     * @param {AbstractSyntaxTreeNode[]} nodes - The nodes which could be used by mutations to generate mutants.
     * @returns {Mutant[]} All possible Mutants for the given set of nodes.
     */
    MutatorOrchestrator.prototype.findMutants = function (sourceFile, originalCode, ast, nodes) 12{
        var _this = this;
        var mutants = [];
        nodes.forEach(function (astnode) 13{
            if (1415astnode.type) 16{
                Object.freeze(astnode);
                _this.mutators.forEach(function (mutator) 17{
                    try 18{
                        var mutatedNodes = mutator.applyMutations(astnode, function (node, deepClone) 19{
                            return deepClone ? _.cloneDeep(node) : _.clone(node);
                        });
                        if (20212223mutatedNodes.length > 0) 24{
                            log.debug(252627282930313233343536373839"The mutator '" + mutator.name + "' mutated " + mutatedNodes.length + " node" + (4041mutatedNodes.length > 1 ? 's' : '') + " between (Ln " + astnode.loc.start.line + ", Col " + astnode.loc.start.column + ") and (Ln " + astnode.loc.end.line + ", Col " + astnode.loc.end.column + ") in file " + sourceFile);
                        }

                        mutatedNodes.forEach(function (mutatedNode) 42{
                            var mutatedCode = parserUtils.generate(mutatedNode);
                            var originalNode = nodes[mutatedNode.nodeID];
                            mutants.push(new Mutant_1.default(mutator.name, sourceFile, originalCode, mutatedCode, originalNode.loc, originalNode.range));
                        });
                    }

                    catch (error) 43{
                        throw new Error(444546"The mutator named '" + mutator.name + "' caused an error: " + error);
                    }

                });
            }

        });
        return mutants;
    };
    ;
    return MutatorOrchestrator;
}());
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = MutatorOrchestrator;
//# sourceMappingURL=MutatorOrchestrator.js.map