Code coverage report for api/services/graphUtils.js

Statements: 96.72% (59 / 61)      Branches: 93.02% (40 / 43)      Functions: 100% (16 / 16)      Lines: 100% (53 / 53)      Ignored: 4 statements, 3 branches     

All files » api/services/ » graphUtils.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 941     1     2 1 1   2 2 13   2 2   2 2 1   1         1 16 16 16     2   8   8 8 8 8 23 27   8 7 2 2   5 7 1     4 14 1     3 20     1       2 2   8 7 7 1   7   1         1       1 1 1 1 1        
var tsort = require('tsort');
 
 
module.exports = {
  tsortGraph: function tsortGraph(graph, newConnection, cb){
    /* istanbul ignore next: just a function check */
    Iif(typeof newConnection == "function"){
      cb = newConnection
      newConnection = null;
    }
    var tgraph = tsort();
    graph.connections.forEach(function(c){
      tgraph.add(c.startNode, c.endNode)
    });
    Eif(newConnection){
      tgraph.add(newConnection.startNode, newConnection.endNode)
    }
    try{
      var result = tgraph.sort()
      return cb(null, result)
    } catch(err){
      return cb(err)
    }
  },
 
  ValidateConnection: function(graph, newConnection, callback){
    function portType(c,p){
      Iif(c.data.type == "input") return true;
      else Iif(c.data.type == "output") return false;
      else return (p == "output" || p == "error" || p == "retcode");
    }
 
    function portTypeName(c,p){return portType(c,p) ? "output" : "input"}
 
    async.series([
      function(cb){
        var sNode = newConnection.startNode 
        var sPort = newConnection.startPort 
        var eNode = newConnection.endNode 
        var ePort = newConnection.endPort
        var sComponent = _.find(graph.components, function(comp){return comp.id == sNode})
        var eComponent = _.find(graph.components, function(comp){return comp.id == eNode})
 
        if(sNode == eNode){return cb({message:"Trying to connect the same node"})}
        else if(portType(sComponent,sPort) == portType(eComponent,ePort)){
          var portName = portTypeName(sComponent,sPort)
          return cb({message:"Trying to connect an "+ portName +" with another " + portName})
        }
        if(sComponent.data.type == "file" &&
           _.some(graph.connections, function(conn){return conn.endNode == sComponent.id})){
         return cb({message: "Trying to read a file used to write"})
        }
 
        if(eComponent.data.type == "file" &&
           _.some(graph.connections, function(conn){return conn.startNode == eComponent.id})){
         return cb({message: "Trying to write a file used to read"})
        }
 
        if(_.some(graph.connections, function(conn){
          return conn.startNode == sNode && conn.endNode == eNode
              && conn.startPort == sPort && conn.endPort == ePort
        })){
         return cb({message: "Connection already exists"});
        }
 
 
        return cb(null, true);
      }, function(cb){graphUtils.tsortGraph(graph, newConnection,cb)}
    ], function(err, res){
      if(err){
        var msg = err.message;
        if(_.contains(msg, 'There is a cycle in the graph')){
          msg = "Connection creates a cycle"
        }
        return callback(msg);
      }
      return callback(err, res);
    })
  },
 
  connect: function(graph, newConnection, cb){
    Graph.findOne(graph)
    .populate('components')
    .populate('connections')
    .exec(function(err,result){
      /* istanbul ignore next */ Iif(err || !result) return cb(err);
      graphUtils.ValidateConnection(result, newConnection, function(err, res){
        /* istanbul ignore next */  Iif(err || !res) return cb(err);
        newConnection.graph = graph;
        Connection.create(newConnection).exec(cb);
      })
    });
  }
}