<commit_before>AggressiveMode.prototype = new Mode();
AggressiveMode.prototype.constructor = AggressiveMode;

// if an enemy unit is in sight, attack the enemy.
// Move towards the enemy position
// Build units to reinforce the army
function AggressiveMode(battle) {
  this.battle = battle;
  this.enemyHQPos = this._getEnemyHQPos();
  this.usedPositionsThisTurn = [];
  this.currentSelectedUnit = null;
  this.buildPhase = false;
};

// AggressiveMode.prototype.execute = function() {
//   var nextMode = "aggressive";
//   this._moveEachUnit();
//   this._buildPhase();
//   return nextMode;
// };

// AggressiveMode.prototype._moveEachUnit = function() {
//   var that = this;
//   // this.battle.players[1].army.units.forEach(function(unit) {
//   //   that._moveUnit(unit);
//   // });
//   // var unit = this.battle.players[1].army.units[0];
//   // this._moveUnit(unit);
//   // unit = this.battle.players[1].army.units[0];
//   // this._moveUnit(unit);
//   var units = this.battle.players[1].army.units;
//   this._moveAllUnits(units);
//   sleep(500);
//   window.setTimeout(this._endTurn, 1500);
// };

// AggressiveMode.prototype._moveAllUnits = function(unitsArray) {
//   // Recursive Move function
//   // Base Case
//   if (unitsArray.length === 0) {
//     return;
//   } else {
//     this._moveUnit(unitsArray.pop(), function() {
//       this._moveAllUnits(unitsArray);
//     });
//   };
// }

// AggressiveMode.prototype._moveUnit = function(unit, callback) {
//   // var mousePos = unit.pos
//   // this.battle.currentSelectedTile = battle.map.getTileAtPos(mousePos);
//   this.battle.currentSelectedUnit = unit;
//   var possibleMoves = unit.getPossibleMoves(unit.pos, this.battle.map, this.battle.enemyPositions())
//   possibleMoves = this._filterPossibleMoves(possibleMoves)
//   this.battle.currentSelectedMovement = possibleMoves;
//   this.battle.turnState = "selectingMove";
//   this.battle.renderMoveHighlights();
//   // // mousePos = this._getClosestMove(possibleMoves);
//   var squareToMoveTo = this._getClosestMove(possibleMoves);
//   // this.usedPositionsThisTurn.push(squareToMoveTo);
//   this.battle.turnState = "animatingMovement";
//   unit.walkPath = squareToMoveTo.getPath();
// };

// AggressiveMode.prototype._keepAnimatingUnit = function(unit) {
//   if (unit.walkPath.length === 0) {
//     return false;
//   } else {
//     return true;
//   }
// };

AggressiveMode.prototype._endTurn = function() {
  battle.players[1].endTurn();
  battle.currentPlayer = 1;
  var prevGold = battle.getCurrentPlayer().gold;
  battle.addGold();
  if (prevGold !== battle.getCurrentPlayer().gold) {
      game.add.audio('coin').play();
  };
  battle.getCurrentPlayer().onTurnStart(battle.map, battle.currentPlayer);
  var style = { font: "65px Arial", fill: "#ff0044", align: "center", stroke: "white", strokeThickness: 5 };
  var text = game.add.text(game.world.centerX - 210 , game.world.centerY - 300, "Player 1 Turn", style);
  text.anchor.set(0.5);
  text.alpha = 1;
  var tween = game.add.tween(text).to( { alpha: 0 }, 2000, "Linear", true);
  battle.turn ++;
  turnCount.setText("Turn: " + battle.turn);
  currentPlayerText.setText("Player " + this.battle.currentPlayer);
  currentPlayerGold.setText("Gold: " + this.battle.players[battle.currentPlayer - 1].gold);
};

AggressiveMode.prototype._getEnemyHQPos = function() {
  pos = this.battle.players[0].hqPos;
  return pos;
};

AggressiveMode.prototype._getDistanceBetween = function(pos1, pos2) {
  // Currently using pythagorean theorem to find distance, but can use some distance function which takes account terrain.
  return Math.sqrt(Math.pow(Math.abs(pos1.x - pos2.x), 2) + Math.pow(Math.abs(pos1.y - pos2.y), 2));
};

AggressiveMode.prototype.arrayIncludesPosition = function(array, pos) {
  var included = false;
  array.forEach(function(item) {
    if(pos.equals(item)) {
      included = true;
      return;
    }
  });
  return included;
}

AggressiveMode.prototype.handleComputerMove = function() {
  // Returns mousePos to position computer desires to click.
  // Sets battle.computerCanClick to true once a selection is made.
  var mousePos;
  if (this.buildPhase === true) {
    if (this.battle.turnState !== "buildUnit") {
      this._runBuildPhase;
    }
    // move to ._runBuildPhase;
    this.buildPhase = false;
    this._endTurn();
  }
  else if(this.battle.turnState === "selectingUnit") {
    mousePos = this._selectNextUnit();
  }
  else if(this.battle.turnState === "selectingMove") {
    mousePos = this._selectNextMove();
  }
  else if(this.battle.turnState === "selectingAttack") {
    mousePos = this._selectNextAttack();
  }
  else if (this.battle.turnState === "capturePrompt") {
    mousePos = this._selectNextCapture();
  }
  else {
    mousePos = new Pos (1,1);
  }
  return mousePos;
};

AggressiveMode.prototype._selectNextUnit = function() {
  var nextUnitPos = null;
  var that = this;
  this.battle.players[1].army.units.forEach(function(unit) {
    if (!nextUnitPos && !unit.movedThisTurn) {
      that.currentSelectedUnit = unit;
      nextUnitPos = unit.pos;
    };
  });
  // Logic for when to end turn
  if (nextUnitPos === null) {
    this.buildPhase = true;
  }
  return nextUnitPos
}

AggressiveMode.prototype._selectNextMove = function() {
  var that = this;
  var nextMovePos = null;
  var possibleMoves = this.currentSelectedUnit.getPossibleMoves(this.currentSelectedUnit.pos, this.battle.map, this.battle.enemyPositions());
  var filteredPossibleMoves = this._filterPossibleMoves(possibleMoves);
  if (this.currentSelectedUnit instanceof UnitArtillery) {
    nextMovePos = that._handleArtilleryMovement(filteredPossibleMoves);
  } else {
    // nextMovePos = this._getClosestMoveToEnemyHQ(filteredPossibleMoves);
    // nextMovePos = this._getClosestMoveToEnemyUnit(filteredPossibleMoves);
    nextMovePos = this._randomizeUnitMovement(filteredPossibleMoves);
  }
  return nextMovePos;
}

AggressiveMode.prototype._selectNextAttack = function() {
  var nextAttackPos = null;
  var possibleAttackMoves = this.currentSelectedUnit.getPossibleAttacks(this.battle.map);
  var filteredAttackMoves = this._filterPossibleAttackMoves(possibleAttackMoves);
  return filteredAttackMoves[0];
}

AggressiveMode.prototype._selectNextCapture = function() {

};

// Battle.prototype.clickOnBarracks = function(mousePos) {
//   if (this.currentSelectedTile) {
//     if (this.currentSelectedTile.name === "barracks" && this.currentSelectedTile.owner === this.currentPlayer) {
//       this.turnState = "buildUnit";
//       this.buildScreen = new BuildScreen(this.getCurrentPlayer().army.armyList, this, mousePos);
//     }
//   }
// }

AggressiveMode.prototype._runBuildPhase = function() {
  // fix so won't reset
    var unusedBarracks = this._getAllBarracks;
    this._selectNextBarracks(unusedBarracks.pop());
}

AggressiveMode.prototype._selectNextBarracks = function(barracks) {
  var mousePos = this._getBarracksPosition(barracks)
  this.battle.clickOnBarracks(mousePos);
};

AggressiveMode.prototype._getAllBarracks = function() {
  var barracks = [];
  this.battle.map.getAllBuildings(true).forEach(function(buildingArray) {
    if (buildingArray[0].name === "barracks" && buildingArray[0].owner === this.battle.currentPlayer) {
      barracks.push(buildingArray);
    }
  });
  return barracks;
};

AggressiveMode.prototype._getBarracksPosition = function(barracks) {
  var barracksTileCoordinates = [];
  barracksTileCoordinates.push(barracks[1]);
  barracksTileCoordinates.push(barracks[2]);
  return barracksTileCoordinates;
};

AggressiveMode.prototype._chooseUnit = function() {
  var armyList = this.battle.getCurrentPlayer().army.armyList;
}

AggressiveMode.prototype._evaluateUnits = function (armyList) {

}

AggressiveMode.prototype._filterPossibleMoves = function(possibleMoves) {
  // Takes in list of possible moves and filters out positions in which friendly units already exist
  // for each possible move
    // Call unitAtPos and check if null
  var that = this;
  result = [];
  possibleMoves.forEach(function(movePos) {
    var unitAtPos = that.battle.getUnitAtPos(movePos);
    if (!unitAtPos) {
      result.push(movePos);
    };
  });
  return result;
}

AggressiveMode.prototype._filterPossibleAttackMoves = function(possibleAttackMoves) {
  var that = this;
  result = [];
  possibleAttackMoves.forEach(function(attackPos) {
    var unitAtPos = that.battle.getUnitAtPos(attackPos);
    if (unitAtPos && unitAtPos.player !== that.currentSelectedUnit.player) {
      result.push(attackPos);
    };
  });
  return result;
}

AggressiveMode.prototype._getClosestMoveToEnemyHQ = function(possibleMoves) {
  var that = this;
  bestMove = null;
  bestMoveDistance = 100;
  possibleMoves.forEach(function(movePos) {
    var distanceBetween = that._getDistanceBetween(that.enemyHQPos, movePos);
    if (distanceBetween < bestMoveDistance) {
      bestMove = movePos;
      bestMoveDistance = distanceBetween;
    };
  });
  return bestMove;
};

AggressiveMode.prototype._getClosestMoveToEnemyUnit = function(possibleMoves) {
  var that = this;
  // this.battle.enemyPositions()
  bestMove = null;
  bestMoveDistance = 100;
  this.battle.enemyPositions().forEach(function(enemyPos) {
    possibleMoves.forEach(function(movePos) {

    var distanceBetween = that._getDistanceBetween(enemyPos, movePos);
    if (distanceBetween < bestMoveDistance) {
      bestMove = movePos;
      bestMoveDistance = distanceBetween;
    };
  });
  });
  return bestMove;
};

AggressiveMode.prototype._randomizeUnitMovement = function(possibleMoves) {
  var move = null;
  if (Math.random() > .50) {
    move = this._getClosestMoveToEnemyHQ(possibleMoves)
  } else {
    move = this._getClosestMoveToEnemyUnit(possibleMoves)
  }
  return move
};

AggressiveMode.prototype._handleArtilleryMovement = function(possibleMoves) {
  var that = this;
  var nextMove = null;
  var rand = Math.random();
  if (rand > .50) {
    nextMove = this.currentSelectedUnit.pos;
  } else {
    nextMove = this._randomizeUnitMovement(possibleMoves);
  }
  return nextMove;
};

<commit_msg>Add smarter artillery movement<commit_after>AggressiveMode.prototype = new Mode();
AggressiveMode.prototype.constructor = AggressiveMode;

// if an enemy unit is in sight, attack the enemy.
// Move towards the enemy position
// Build units to reinforce the army
function AggressiveMode(battle) {
  this.battle = battle;
  this.enemyHQPos = this._getEnemyHQPos();
  this.usedPositionsThisTurn = [];
  this.currentSelectedUnit = null;
  this.buildPhase = false;
};

// AggressiveMode.prototype.execute = function() {
//   var nextMode = "aggressive";
//   this._moveEachUnit();
//   this._buildPhase();
//   return nextMode;
// };

// AggressiveMode.prototype._moveEachUnit = function() {
//   var that = this;
//   // this.battle.players[1].army.units.forEach(function(unit) {
//   //   that._moveUnit(unit);
//   // });
//   // var unit = this.battle.players[1].army.units[0];
//   // this._moveUnit(unit);
//   // unit = this.battle.players[1].army.units[0];
//   // this._moveUnit(unit);
//   var units = this.battle.players[1].army.units;
//   this._moveAllUnits(units);
//   sleep(500);
//   window.setTimeout(this._endTurn, 1500);
// };

// AggressiveMode.prototype._moveAllUnits = function(unitsArray) {
//   // Recursive Move function
//   // Base Case
//   if (unitsArray.length === 0) {
//     return;
//   } else {
//     this._moveUnit(unitsArray.pop(), function() {
//       this._moveAllUnits(unitsArray);
//     });
//   };
// }

// AggressiveMode.prototype._moveUnit = function(unit, callback) {
//   // var mousePos = unit.pos
//   // this.battle.currentSelectedTile = battle.map.getTileAtPos(mousePos);
//   this.battle.currentSelectedUnit = unit;
//   var possibleMoves = unit.getPossibleMoves(unit.pos, this.battle.map, this.battle.enemyPositions())
//   possibleMoves = this._filterPossibleMoves(possibleMoves)
//   this.battle.currentSelectedMovement = possibleMoves;
//   this.battle.turnState = "selectingMove";
//   this.battle.renderMoveHighlights();
//   // // mousePos = this._getClosestMove(possibleMoves);
//   var squareToMoveTo = this._getClosestMove(possibleMoves);
//   // this.usedPositionsThisTurn.push(squareToMoveTo);
//   this.battle.turnState = "animatingMovement";
//   unit.walkPath = squareToMoveTo.getPath();
// };

// AggressiveMode.prototype._keepAnimatingUnit = function(unit) {
//   if (unit.walkPath.length === 0) {
//     return false;
//   } else {
//     return true;
//   }
// };

AggressiveMode.prototype._endTurn = function() {
  battle.players[1].endTurn();
  battle.currentPlayer = 1;
  var prevGold = battle.getCurrentPlayer().gold;
  battle.addGold();
  if (prevGold !== battle.getCurrentPlayer().gold) {
      game.add.audio('coin').play();
  };
  battle.getCurrentPlayer().onTurnStart(battle.map, battle.currentPlayer);
  var style = { font: "65px Arial", fill: "#ff0044", align: "center", stroke: "white", strokeThickness: 5 };
  var text = game.add.text(game.world.centerX - 210 , game.world.centerY - 300, "Player 1 Turn", style);
  text.anchor.set(0.5);
  text.alpha = 1;
  var tween = game.add.tween(text).to( { alpha: 0 }, 2000, "Linear", true);
  battle.turn ++;
  turnCount.setText("Turn: " + battle.turn);
  currentPlayerText.setText("Player " + this.battle.currentPlayer);
  currentPlayerGold.setText("Gold: " + this.battle.players[battle.currentPlayer - 1].gold);
};

AggressiveMode.prototype._getEnemyHQPos = function() {
  pos = this.battle.players[0].hqPos;
  return pos;
};

AggressiveMode.prototype._getDistanceBetween = function(pos1, pos2) {
  // Currently using pythagorean theorem to find distance, but can use some distance function which takes account terrain.
  return Math.sqrt(Math.pow(Math.abs(pos1.x - pos2.x), 2) + Math.pow(Math.abs(pos1.y - pos2.y), 2));
};

AggressiveMode.prototype.arrayIncludesPosition = function(array, pos) {
  var included = false;
  array.forEach(function(item) {
    if(pos.equals(item)) {
      included = true;
      return;
    }
  });
  return included;
}

AggressiveMode.prototype.handleComputerMove = function() {
  // Returns mousePos to position computer desires to click.
  // Sets battle.computerCanClick to true once a selection is made.
  var mousePos;
  if (this.buildPhase === true) {
    if (this.battle.turnState !== "buildUnit") {
      this._runBuildPhase;
    }
    // move to ._runBuildPhase;
    this.buildPhase = false;
    this._endTurn();
  }
  else if(this.battle.turnState === "selectingUnit") {
    mousePos = this._selectNextUnit();
  }
  else if(this.battle.turnState === "selectingMove") {
    mousePos = this._selectNextMove();
  }
  else if(this.battle.turnState === "selectingAttack") {
    mousePos = this._selectNextAttack();
  }
  else if (this.battle.turnState === "capturePrompt") {
    mousePos = this._selectNextCapture();
  }
  else {
    mousePos = new Pos (1,1);
  }
  return mousePos;
};

AggressiveMode.prototype._selectNextUnit = function() {
  var nextUnitPos = null;
  var that = this;
  this.battle.players[1].army.units.forEach(function(unit) {
    if (!nextUnitPos && !unit.movedThisTurn) {
      that.currentSelectedUnit = unit;
      nextUnitPos = unit.pos;
    };
  });
  // Logic for when to end turn
  if (nextUnitPos === null) {
    this.buildPhase = true;
  }
  return nextUnitPos
}

AggressiveMode.prototype._selectNextMove = function() {
  var that = this;
  var nextMovePos = null;
  var possibleMoves = this.currentSelectedUnit.getPossibleMoves(this.currentSelectedUnit.pos, this.battle.map, this.battle.enemyPositions());
  var filteredPossibleMoves = this._filterPossibleMoves(possibleMoves);
  if (this.currentSelectedUnit instanceof UnitArtillery) {
    nextMovePos = that._handleArtilleryMovement(filteredPossibleMoves);
  } else {
    // nextMovePos = this._getClosestMoveToEnemyHQ(filteredPossibleMoves);
    // nextMovePos = this._getClosestMoveToEnemyUnit(filteredPossibleMoves);
    nextMovePos = this._randomizeUnitMovement(filteredPossibleMoves);
  }
  return nextMovePos;
}

AggressiveMode.prototype._selectNextAttack = function() {
  var nextAttackPos = null;
  var possibleAttackMoves = this.currentSelectedUnit.getPossibleAttacks(this.battle.map);
  var filteredAttackMoves = this._filterPossibleAttackMoves(possibleAttackMoves);
  return filteredAttackMoves[0];
}

AggressiveMode.prototype._selectNextCapture = function() {

};

// Battle.prototype.clickOnBarracks = function(mousePos) {
//   if (this.currentSelectedTile) {
//     if (this.currentSelectedTile.name === "barracks" && this.currentSelectedTile.owner === this.currentPlayer) {
//       this.turnState = "buildUnit";
//       this.buildScreen = new BuildScreen(this.getCurrentPlayer().army.armyList, this, mousePos);
//     }
//   }
// }

AggressiveMode.prototype._runBuildPhase = function() {
  // fix so won't reset
    var unusedBarracks = this._getAllBarracks;
    this._selectNextBarracks(unusedBarracks.pop());
}

AggressiveMode.prototype._selectNextBarracks = function(barracks) {
  var mousePos = this._getBarracksPosition(barracks)
  this.battle.clickOnBarracks(mousePos);
};

AggressiveMode.prototype._getAllBarracks = function() {
  var barracks = [];
  this.battle.map.getAllBuildings(true).forEach(function(buildingArray) {
    if (buildingArray[0].name === "barracks" && buildingArray[0].owner === this.battle.currentPlayer) {
      barracks.push(buildingArray);
    }
  });
  return barracks;
};

AggressiveMode.prototype._getBarracksPosition = function(barracks) {
  var barracksTileCoordinates = [];
  barracksTileCoordinates.push(barracks[1]);
  barracksTileCoordinates.push(barracks[2]);
  return barracksTileCoordinates;
};

AggressiveMode.prototype._chooseUnit = function() {
  var armyList = this.battle.getCurrentPlayer().army.armyList;
}

AggressiveMode.prototype._evaluateUnits = function (armyList) {

}

AggressiveMode.prototype._filterPossibleMoves = function(possibleMoves) {
  // Takes in list of possible moves and filters out positions in which friendly units already exist
  // for each possible move
    // Call unitAtPos and check if null
  var that = this;
  result = [];
  possibleMoves.forEach(function(movePos) {
    var unitAtPos = that.battle.getUnitAtPos(movePos);
    if (!unitAtPos) {
      result.push(movePos);
    };
  });
  return result;
}

AggressiveMode.prototype._filterPossibleAttackMoves = function(possibleAttackMoves) {
  var that = this;
  result = [];
  possibleAttackMoves.forEach(function(attackPos) {
    var unitAtPos = that.battle.getUnitAtPos(attackPos);
    if (unitAtPos && unitAtPos.player !== that.currentSelectedUnit.player) {
      result.push(attackPos);
    };
  });
  return result;
}

AggressiveMode.prototype._getClosestMoveToEnemyHQ = function(possibleMoves) {
  var that = this;
  bestMove = null;
  bestMoveDistance = 100;
  possibleMoves.forEach(function(movePos) {
    var distanceBetween = that._getDistanceBetween(that.enemyHQPos, movePos);
    if (distanceBetween < bestMoveDistance) {
      bestMove = movePos;
      bestMoveDistance = distanceBetween;
    };
  });
  return bestMove;
};

AggressiveMode.prototype._getClosestMoveToEnemyUnit = function(possibleMoves) {
  var that = this;
  // this.battle.enemyPositions()
  bestMove = null;
  bestMoveDistance = 100;
  this.battle.enemyPositions().forEach(function(enemyPos) {
    possibleMoves.forEach(function(movePos) {

    var distanceBetween = that._getDistanceBetween(enemyPos, movePos);
    if (distanceBetween < bestMoveDistance) {
      bestMove = movePos;
      bestMoveDistance = distanceBetween;
    };
  });
  });
  return bestMove;
};

AggressiveMode.prototype._randomizeUnitMovement = function(possibleMoves) {
  var move = null;
  if (Math.random() > .50) {
    move = this._getClosestMoveToEnemyHQ(possibleMoves)
  } else {
    move = this._getClosestMoveToEnemyUnit(possibleMoves)
  }
  return move
};

AggressiveMode.prototype._handleArtilleryMovement = function(possibleMoves) {
  var that = this;
  var nextMove = null;
  var rand = Math.random();
  if (rand > .50) {
    nextMove = this.currentSelectedUnit.pos;
  } else {
    nextMove = this._randomizeUnitMovement(possibleMoves);
  }
  return nextMove;
};
<|endoftext|>


<commit_before>var should = require('should');
var db = require('../helper/db');
var Project = require('../../model/project');
var User = require('../../model/user');

var config = {
    projectName: 'TestProject',
    user: 'snakazawa'
};

describe('model', function () {
    describe('project', function () {
        var share = {
            user: null,
            project: null
        };

        before(function (done) {
            db.before(function () {
                // プロジェクト作成用ユーザを作っておく
                User.create({userName: config.user}, function (err, doc) {
                    if (err) { throw new Error(err); }
                    share.user = doc;
                    done();
                });
            });
        });

        after(db.after);

        it('インスタンスを作れるか', function () {
            var project = new Project();
            project.should.is.instanceof(Project);
            project.created_at.should.is.instanceof(Date);
        });

        it('プロジェクトを作ってみる', function (done) {
            var name = config.projectName;
            Project.create({name: name, create_user: share.user}, function (err, project) {
                if (err) { throw new Error(err); }
                share.project = project;
                project.name.should.be.equal(name);
                done();
            });
        });

        it('Issuesを追加する', function (done) {
            var name = 'TestProjectB';
            var project = share.project;

            project.issues.length.should.be.equal(0);

            project.issues.push({
                title: 'taskA'
            });

            project.save(function (err, project) {
                if (err) { throw new Error(err); }
                project.issues.length.should.be.equal(1);

                Project.findOne({name: config.projectName}, function (err, project) {
                    if (err) { throw new Error(err); }
                    project.issues.length.should.be.equal(1);
                    share.project = project;
                    done();
                });
            });
        });

        it('Memberを追加する', function (done) {
            var project = share.project;
            project.members.length.should.be.equal(0);

            project.members.push({
                user: share.user
            });
            project.members.push({
                user: share.user
            });
            project.members.push({
                user: share.user
            });

            project.save(function (err, project) {
                if (err) { throw new Error(err); }
                project.members.length.should.be.equal(3);

                Project.findOne({name: config.projectName}, function (err, project) {
                    if (err) { throw new Error(err); }
                    project.members.length.should.be.equal(3);
                    done();
                });
            });
        });

        it('Memberを削除する', function (done) {
            Project.findOne({name: config.projectName}, function (err, project) {
                if (err) { throw new Error(err); }

                project.members.length.should.be.equal(3);
                project.members.pull(project.members[0]);

                project.save(function (err, project) {
                    if (err) { throw new Error(err); }
                    project.members.length.should.be.equal(2);

                    Project.findOne({name: config.projectName}, function (err, project) {
                        if (err) { throw new Error(err); }
                        project.members.length.should.be.equal(2);
                        done();
                    });
                });
            });
        });

        it('removeMemberメソッドでMemberを削除する', function (done) {
            Project.findOne({name: config.projectName}, function (err, project) {
                if (err) { throw new Error(err); }

                project.members.length.should.be.equal(2);

                project.removeMember(config.user, function (err, project, member) {
                    if (err) { throw new Error(err); }
                    project.members.length.should.be.equal(1);

                    Project.findOne({name: config.projectName}, function (err, project) {
                        if (err) { throw new Error(err); }
                        project.members.length.should.be.equal(1);
                        done();
                    });
                });
            });
        });

        it('removeMemberスタティックメソッドでMemberを削除する', function (done) {
            Project.removeMember({name: config.projectName}, config.user, function (err, project, member) {
                if (err) { throw new Error(err); }
                project.members.length.should.be.equal(0);

                Project.findOne({name: config.projectName}, function (err, project) {
                    if (err) { throw new Error(err); }
                    project.members.length.should.be.equal(0);
                    done();
                });
            });
        });

        it('addMemberメソッドでMemberを追加する', function (done) {
            Project.findOne({name: config.projectName}, function (err, project) {
                if (err) { throw new Error(err); }

                project.members.length.should.be.equal(0);

                project.addMember(config.user + 'hoge123', function (err, project, member) {
                    if (err) { throw new Error(err); }
                    project.members.length.should.be.equal(1);

                    Project.findOne({name: config.projectName}, function (err, project) {
                        if (err) { throw new Error(err); }
                        project.members.length.should.be.equal(1);
                        done();
                    });
                });
            });
        });

        it('addMemberスタティックメソッドでMemberを追加する', function (done) {
            Project.addMember({name: config.projectName}, config.use + 'piyohoge', function (err, project, member) {
                if (err) { throw new Error(err); }
                project.members.length.should.be.equal(2);

                Project.findOne({name: config.projectName}, function (err, project) {
                    if (err) { throw new Error(err); }
                    project.members.length.should.be.equal(2);
                    done();
                });
            });
        });

        it('existsメソッド', function (done) {
            Project.exists({name: config.projectName}, function (err, isExists) {
                if (err) { throw new Error(err); }

                isExists.should.be.equal(true);
                done();
            });
        });

        it('existsメソッドfalse', function (done) {
            Project.exists({name: config.projectName + 'asdf'}, function (err, isExists) {
                if (err) { throw new Error(err); }

                isExists.should.be.equal(false);
                done();
            });
        });
    });
});<commit_msg>project model spec のリファクタリング<commit_after>var should = require('should');
var db = require('../helper/db');
var Project = require('../../model/project');
var User = require('../../model/user');

var config = {
    projectName: 'TestProject',
    userName: 'snakazawa'
};

describe('model', function () {
    describe('project', function () {
        var user;
        var error;

        beforeEach(function (done) {
            db.before(function () {
                // プロジェクト作成用ユーザを作っておく
                User.findOrCreate(config.userName, function (err, doc) {
                    if (err) { throw new Error(err); }
                    user = doc;
                    done();
                });
            });
        });

        after(db.after);

        it('インスタンスを作れる', function () {
            var project = new Project();
            project.should.is.instanceof(Project);
            project.created_at.should.is.instanceof(Date);
        });

        describe('constructor', function () {
            var project;

            beforeEach(function (done) {
                // create project
                Project.create({name: config.projectName, create_user: user}, function (err, doc) {
                    error = err;
                    project = doc;
                    done();
                });
            });

            it('エラーがない', function () { should.not.exists(error); });
            it('プロジェクトを作れる', function () { should.exists(project); });
            it('名前が設定されている', function () { project.name.should.be.equal(config.projectName); });

            describe('exists', function () {
                var isExists;
                describe('is eixsts', function () {
                    before(function (done) {
                        Project.exists({name: config.projectName}, function (err, result) {
                            error = err;
                            isExists = result;
                            done();
                        });
                    });

                    it('エラーがない', function () { should.not.exists(error); });
                    it('存在する', function () { isExists.should.be.true; });
                });

                describe('is not exists', function () {
                    before(function (done) {
                        Project.exists({name: config.projectName + 'asdf'}, function (err, result) {
                            error = err;
                            isExists = result;
                            done();
                        });
                    });

                    it('エラーがない', function () { should.not.exists(error); });
                    it('存在しない', function () { isExists.should.be.false; });
                });
            });

            describe('issue', function () {
                it('初めはIssueを持っていない', function () { project.issues.length.should.be.equal(0); });

                describe('create', function () {
                    beforeEach(function (done) {
                        // create issue
                        project.issues.push({ title: 'taskA' });
                        project.save(function (err, doc) {
                            error = err;
                            project = doc;
                            done();
                        });
                    });

                    it('エラーがない', function () { should.not.exists(error); });
                    it('Issueを追加できる', function () { should.exists(project); });
                    it('Issuesを追加したらIssue数が1つ増える', function () { project.issues.length.should.be.equal(1); });
                });
            });

            describe('member', function () {
                it('初めはメンバーはいない', function () { project.members.length.should.be.equal(0); });

                describe('push', function () {
                    beforeEach(function (done) {
                        // create member
                        project.members.push({ user: user });
                        project.save(function (err, doc) {
                            error = err;
                            project = doc;
                            done();
                        });
                    });

                    it('エラーがない', function () { should.not.exists(error); });
                    it('メンバー数が一人増える', function () { project.members.length.should.be.equal(1); });

                    describe('pull', function () {
                        beforeEach(function (done) {
                            project.members.pull(project.members[0]);
                            project.save(function (err, doc) {
                                error = err;
                                project = doc;
                                done();
                            });
                        });

                        it('エラーがない', function () { should.not.exists(error); });
                        it('メンバーが一人減る', function () { project.members.length.should.be.equal(0); });
                    });

                    describe('removeMember', function () {
                        beforeEach(function (done) {
                            project.removeMember(config.userName, function (err, doc, member) {
                                error = err;
                                project = doc;
                                done();
                            });
                        });

                        it('エラーがない', function () { should.not.exists(error); });
                        it('メンバーが一人減る', function () { project.members.length.should.be.equal(0); });
                    });

                    describe('addMember', function () {
                        beforeEach(function (done) {
                            project.addMember(config.user + 'hoge123', function (err, doc, member) {
                                error = err;
                                project = doc;
                                done();
                            });
                        });

                        it('エラーがない', function () { should.not.exists(error); });
                        it('メンバーが一人増える', function () { project.members.length.should.be.equal(2); });
                    });
                });
            });
        });
        //
        //it('updateStageでIssueを更新できる', function (done) {
        //
        //});
    });
});<|endoftext|>


<commit_before>/* ©Copyright Utrecht University (Department of Information and Computing Sciences) */

var Clipboard;

(function()
{
    Clipboard =
    {
        copyElement: copyElement,
        cutElement: cutElement,
        pasteElement: pasteElement
    };

    //Public Variables

    //Private Variables
    var copiedElement = null,
        copiedElements = [],
        copiedTrees = false;

    $(document).ready(function()
    {
        $("#copyNode").on('click', function()
        {
            copyElement();
        });
        $("#cutNode").on('click', function ()
        {
            cutElement();
        });
        $("#pasteNode").on('click', function()
        {
            pasteElement();
        });
    });

    function copyElement()
    {
        //Check if we're saving tree(s) or node(s)
        copiedTrees = !Zoom.isZoomed();

        //Save element(s) in memory
        if (Main.selectedElement !== null && Main.selectedElement !==
            undefined)
        {
            if (copiedTrees)
            {
                copiedElement = copyTree(Main.selectedElement);
            }
            else
            {
                copiedElement = copyNode(Main.selectedElement);
            }
            copiedElements = null;
        }
        else if (Main.selectedElements !== null && Main.selectedElements !==
            undefined)
        {
            copiedElements = [];
            if (copiedTrees)
            {
                $.each(Main.selectedElements, function(index, treeId)
                {
                    copiedElements.push(copyTree(treeId));
                });
            }
            else
            {
                $.each(Main.selectedElements, function(index, nodeId)
                {
                    copiedElements.push(copyNode(nodeId));
                });
            }
            copiedElement = null;
        }
    }

    function copyTree(treeId)
    {
        //Save tree data
        var toCopy = Utils.clone(Main.trees[treeId]),
        nodes = [];
        //Save all node data in tree
        $.each(Main.trees[treeId].nodes, function(index, nodeId)
        {
            nodes.push(copyNode(nodeId));
        });
        toCopy.nodes = nodes;

        return toCopy;
    }

    function copyNode(nodeId)
    {
        // Delete the properties from node that are used for arranging all nodes within a tree
        // This is done here, because doing it after an arrange operation will make it even slower
        delete Main.nodes[nodeId].topologicalChildren;
        delete Main.nodes[nodeId].topologicalOrderingVisited;
        delete Main.nodes[nodeId].topologicalParent;

        toCopy = Utils.clone(Main.nodes[nodeId]);
        var plumbInstance = Main.trees[Main.nodes[nodeId].parent].plumbInstance;

        //Get node connections
        var connections = plumbInstance.getConnections(
                    {
                        target: nodeId
                    });
        //Get node position
        var position = $('#' + nodeId).position();

        //Save extra node info
        toCopy.connections = connections;
        toCopy.position = position;

        return toCopy;
    }

    function cutElement()
    {
        copyElement();
        Main.deleteAllSelected();
    }

    function pasteElement()
    {
        if (copiedElement !== null && copiedElement !== undefined)
        {
            if (copiedTrees && !Zoom.isZoomed())
            {
                pasteTree(copiedElement, 0, 0);
            }
            else if (Zoom.isZoomed() && !copiedTrees)
            {
                var newNode = pasteNode(copiedElement);
                Main.selectElement(newNode.id);
            }
        }
        else if (copiedElements !== null && copiedElements !== undefined)
        {
            if (copiedTrees && !Zoom.isZoomed())
            {
                // In grid positions
                var minY = Number.MAX_VALUE;
                var minX = Number.MAX_VALUE;
                var offSetY = [];
                var offSetX = [];

                $.each(copiedElements, function(index, tree)
                {
                    if(tree.leftPos < minX)
                        minX = tree.leftPos;
                    if(tree.topPos < minY)
                        minY = tree.topPos;
                });

                $.each(copiedElements, function(index, tree)
                {
                    offSetY[index] = tree.topPos-minY;
                    offSetX[index] = tree.leftPos-minX;
                });

                // Paste trees relative to top left of smallest bounding box
                $.each(copiedElements, function(index, tree)
                {
                    pasteTree(tree, offSetX[index], offSetY[index]);
                });
            }
            else if (Zoom.isZoomed() && !copiedTrees)
            {
                //Needed to save jsPlumb connections
                var idMappings = {};
                $.each(copiedElements, function(index, node)
                {
                    newNode = pasteNode(node);
                    idMappings[node.id] = newNode.id;
                });

                var plumbInstance = Zoom.getZoomed().plumbInstance;
                //Copy jsPlumb connections
                $.each(copiedElements, function(index, node)
                {
                    if (!node) //due to deleting from arrays in js leaving values undefined
                        return true;

                    var connections = node.connections;

                    $.each(connections, function(index,
                        connection)
                    {
                        var target = idMappings[
                            connection.targetId]; //map original target to copied target
                        if (!target)
                            return true;
                        var source = idMappings[
                            connection.sourceId]; //map original source to copied source
                        if (!source)
                            return true;
                        plumbInstance.connect(
                        {
                            "source": source,
                            "target": target
                        });
                    });
                });
                // select all nodes just copied
                for (var key in idMappings)
                {
                    // function that allows for more than one selected node at a time
                    KeyControl.selectExtraElement(idMappings[key]);
                }
            }
        }
    }

    function pasteNode(copiedNode)
    {
        var node = Utils.clone(copiedNode); //no dom action just yet. this just copies the object in the nodes object
        var newNode = Main.addNewNode(node.type); //to do dom manipulations and create the id. no data now present in nodes[newNode.id] is kept

        Main.selectElement(null);

        node.id = newNode.id;
        delete node.position;
        delete node.connections;

        Main.nodes[newNode.id] = node;

        // set nodeposition relatively to the positions off the original node(s)
        var left = copiedNode.position.left + 50;
        var top = copiedNode.position.top + 50;

        var nodeElem = $('#' + newNode.id);
        //Set position
        nodeElem.css(
        {
            "top": top,
            "left": left
        });
        //Save node text
        nodeElem.find("textarea.nodestatement").val(copiedNode.text);

        Main.changeNodeText(newNode.id);

        return node;
    }

    function pasteTree(toCopy, offSetX, offSetY)
    {
        var idMappings = {}; //record wich original node id was copied to which id
        //idmappings[originalID] = copyID
        //all other information like dom elements and position should not be copied

        var newTree = Main.addNewTree(null, true, offSetX, offSetY);

        newTree.subject = LanguageManager.fLang("edt_clipboard_copy_of", [toCopy.subject]);
        newTree.optional = toCopy.optional;

        var treeDiv = $("#" + newTree.id);
        treeDiv.find(".subjectName").text(newTree.subject);
        treeDiv.find(".subjectNameInput").val(newTree.subject);

        Main.selectElement(newTree.id); //tree needs to be selected when copied nodes are created

        $.each(toCopy.nodes, function(index, node)
        {
            if (!node) //due to deleting from arrays in js leaving values undefined
                return true; //$.each version of continue

            var newNode = pasteNode(node);

            Main.selectElement(newTree.id); //after creation a new node is immediately selected. so we need to reselect the tree

            idMappings[node.id] = newNode.id; //needed to also copy over jsplumb connectors.

            var newNodeDiv = $("#" + newNode.id);

            newNodeDiv.css(
            {
                "top": node.position.top,
                "left": node.position.left
            }); //position is relative to dom parent, so can be copied directly
        });

        //all nodes have been created. now copy connectors
        $.each(toCopy.nodes, function(index, node)
        {
            if (!node) //due to deleting from arrays in js leaving values undefined
                return true;

            var connections = node.connections;

            $.each(connections, function(index, connection)
            {
                var target = idMappings[connection.targetId]; //map original target to copied target
                var source = idMappings[connection.sourceId]; //map original source to copied source
                newTree.plumbInstance.connect(
                {
                    "source": source,
                    "target": target
                });
            });
        });
    }

}());
<commit_msg>Fixed bug where the node was still referring to the old parent tree<commit_after>/* ©Copyright Utrecht University (Department of Information and Computing Sciences) */

var Clipboard;

(function()
{
    Clipboard =
    {
        copyElement: copyElement,
        cutElement: cutElement,
        pasteElement: pasteElement
    };

    //Public Variables

    //Private Variables
    var copiedElement = null,
        copiedElements = [],
        copiedTrees = false;

    $(document).ready(function()
    {
        $("#copyNode").on('click', function()
        {
            copyElement();
        });
        $("#cutNode").on('click', function ()
        {
            cutElement();
        });
        $("#pasteNode").on('click', function()
        {
            pasteElement();
        });
    });

    function copyElement()
    {
        //Check if we're saving tree(s) or node(s)
        copiedTrees = !Zoom.isZoomed();

        //Save element(s) in memory
        if (Main.selectedElement !== null && Main.selectedElement !==
            undefined)
        {
            if (copiedTrees)
            {
                copiedElement = copyTree(Main.selectedElement);
            }
            else
            {
                copiedElement = copyNode(Main.selectedElement);
            }
            copiedElements = null;
        }
        else if (Main.selectedElements !== null && Main.selectedElements !==
            undefined)
        {
            copiedElements = [];
            if (copiedTrees)
            {
                $.each(Main.selectedElements, function(index, treeId)
                {
                    copiedElements.push(copyTree(treeId));
                });
            }
            else
            {
                $.each(Main.selectedElements, function(index, nodeId)
                {
                    copiedElements.push(copyNode(nodeId));
                });
            }
            copiedElement = null;
        }
    }

    function copyTree(treeId)
    {
        //Save tree data
        var toCopy = Utils.clone(Main.trees[treeId]),
        nodes = [];
        //Save all node data in tree
        $.each(Main.trees[treeId].nodes, function(index, nodeId)
        {
            nodes.push(copyNode(nodeId));
        });
        toCopy.nodes = nodes;

        return toCopy;
    }

    function copyNode(nodeId)
    {
        // Delete the properties from node that are used for arranging all nodes within a tree
        // This is done here, because doing it after an arrange operation will make it even slower
        delete Main.nodes[nodeId].topologicalChildren;
        delete Main.nodes[nodeId].topologicalOrderingVisited;
        delete Main.nodes[nodeId].topologicalParent;

        toCopy = Utils.clone(Main.nodes[nodeId]);
        var plumbInstance = Main.trees[Main.nodes[nodeId].parent].plumbInstance;

        //Get node connections
        var connections = plumbInstance.getConnections(
                    {
                        target: nodeId
                    });
        //Get node position
        var position = $('#' + nodeId).position();

        //Save extra node info
        toCopy.connections = connections;
        toCopy.position = position;

        return toCopy;
    }

    function cutElement()
    {
        copyElement();
        Main.deleteAllSelected();
    }

    function pasteElement()
    {
        if (copiedElement !== null && copiedElement !== undefined)
        {
            if (copiedTrees && !Zoom.isZoomed())
            {
                pasteTree(copiedElement, 0, 0);
            }
            else if (Zoom.isZoomed() && !copiedTrees)
            {
                var newNode = pasteNode(copiedElement);
                Main.selectElement(newNode.id);
            }
        }
        else if (copiedElements !== null && copiedElements !== undefined)
        {
            if (copiedTrees && !Zoom.isZoomed())
            {
                // In grid positions
                var minY = Number.MAX_VALUE;
                var minX = Number.MAX_VALUE;
                var offSetY = [];
                var offSetX = [];

                $.each(copiedElements, function(index, tree)
                {
                    if(tree.leftPos < minX)
                        minX = tree.leftPos;
                    if(tree.topPos < minY)
                        minY = tree.topPos;
                });

                $.each(copiedElements, function(index, tree)
                {
                    offSetY[index] = tree.topPos-minY;
                    offSetX[index] = tree.leftPos-minX;
                });

                // Paste trees relative to top left of smallest bounding box
                $.each(copiedElements, function(index, tree)
                {
                    pasteTree(tree, offSetX[index], offSetY[index]);
                });
            }
            else if (Zoom.isZoomed() && !copiedTrees)
            {
                //Needed to save jsPlumb connections
                var idMappings = {};
                $.each(copiedElements, function(index, node)
                {
                    newNode = pasteNode(node);
                    idMappings[node.id] = newNode.id;
                });

                var plumbInstance = Zoom.getZoomed().plumbInstance;
                //Copy jsPlumb connections
                $.each(copiedElements, function(index, node)
                {
                    if (!node) //due to deleting from arrays in js leaving values undefined
                        return true;

                    var connections = node.connections;

                    $.each(connections, function(index,
                        connection)
                    {
                        var target = idMappings[
                            connection.targetId]; //map original target to copied target
                        if (!target)
                            return true;
                        var source = idMappings[
                            connection.sourceId]; //map original source to copied source
                        if (!source)
                            return true;
                        plumbInstance.connect(
                        {
                            "source": source,
                            "target": target
                        });
                    });
                });
                // select all nodes just copied
                for (var key in idMappings)
                {
                    // function that allows for more than one selected node at a time
                    KeyControl.selectExtraElement(idMappings[key]);
                }
            }
        }
    }

    function pasteNode(copiedNode)
    {
        var node = Utils.clone(copiedNode); //no dom action just yet. this just copies the object in the nodes object
        var newNode = Main.addNewNode(node.type); //to do dom manipulations and create the id. no data now present in nodes[newNode.id] is kept

        Main.selectElement(null);

        node.id = newNode.id;
        node.parent = newNode.parent;
        delete node.position;
        delete node.connections;

        Main.nodes[newNode.id] = node;

        // set nodeposition relatively to the positions off the original node(s)
        var left = copiedNode.position.left + 50;
        var top = copiedNode.position.top + 50;

        var nodeElem = $('#' + newNode.id);
        //Set position
        nodeElem.css(
        {
            "top": top,
            "left": left
        });
        //Save node text
        nodeElem.find("textarea.nodestatement").val(copiedNode.text);

        Main.changeNodeText(newNode.id);

        return node;
    }

    function pasteTree(toCopy, offSetX, offSetY)
    {
        var idMappings = {}; //record wich original node id was copied to which id
        //idmappings[originalID] = copyID
        //all other information like dom elements and position should not be copied

        var newTree = Main.addNewTree(null, true, offSetX, offSetY);

        newTree.subject = LanguageManager.fLang("edt_clipboard_copy_of", [toCopy.subject]);
        newTree.optional = toCopy.optional;

        var treeDiv = $("#" + newTree.id);
        treeDiv.find(".subjectName").text(newTree.subject);
        treeDiv.find(".subjectNameInput").val(newTree.subject);

        Main.selectElement(newTree.id); //tree needs to be selected when copied nodes are created

        $.each(toCopy.nodes, function(index, node)
        {
            if (!node) //due to deleting from arrays in js leaving values undefined
                return true; //$.each version of continue

            var newNode = pasteNode(node);

            Main.selectElement(newTree.id); //after creation a new node is immediately selected. so we need to reselect the tree

            idMappings[node.id] = newNode.id; //needed to also copy over jsplumb connectors.

            var newNodeDiv = $("#" + newNode.id);

            newNodeDiv.css(
            {
                "top": node.position.top,
                "left": node.position.left
            }); //position is relative to dom parent, so can be copied directly
        });

        //all nodes have been created. now copy connectors
        $.each(toCopy.nodes, function(index, node)
        {
            if (!node) //due to deleting from arrays in js leaving values undefined
                return true;

            var connections = node.connections;

            $.each(connections, function(index, connection)
            {
                var target = idMappings[connection.targetId]; //map original target to copied target
                var source = idMappings[connection.sourceId]; //map original source to copied source
                newTree.plumbInstance.connect(
                {
                    "source": source,
                    "target": target
                });
            });
        });
    }

}());
<|endoftext|>


<commit_before>/**
 * Copyright 2014 Solinea, Inc.
 *
 * Licensed under the Solinea Software License Agreement (goldstone),
 * Version 1.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *     http://www.solinea.com/goldstone/LICENSE.pdf
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
to invoke:
1. include goldstoneColors.js in the template script tags
2. assign the palatte as a variable: var colorArray = new GoldstoneColors().get('colorSets');
3. invoke via colorArray, a subset, and an index corresponding to the size of the array desired

colorArray.distinct[3] (Range of 3 colorBlindFriendly colors)
colorArray.distinct[5] (Range of 5 colorBlindFriendly colors)
etc...

*/

var GoldstoneColors = GoldstoneBaseModel.extend({
    defaults: {
        colorSets: {
            // distinct = colorBlindFriendly
            distinct: {
                1: ['#4477AA'],
                2: ['#4477AA', '#CC6677'],
                3: ['#4477AA', '#DDCC77', '#CC6677'],
                4: ['#4477AA', '#117733', '#DDCC77', '#CC6677'],
                5: ['#332288', '#88CCEE', '#117733', '#DDCC77', '#CC6677'],
                6: ['#332288', '#88CCEE', '#117733', '#DDCC77', '#CC6677', '#AA4499'],
                7: ['#332288', '#88CCEE', '#44AA99', '#117733', '#DDCC77', '#CC6677', '#AA4499'],
                8: ['#332288', '#88CCEE', '#44AA99', '#117733', '#999933', '#DDCC77', '#CC6677', '#AA4499'],
                9: ['#332288', '#88CCEE', '#44AA99', '#117733', '#999933', '#DDCC77', '#CC6677', '#882255', '#AA4499'],
                10: ['#332288', '#88CCEE', '#44AA99', '#117733', '#999933', '#DDCC77', '#661100', '#CC6677', '#882255', '#AA4499'],
                11: ['#332288', '#6699CC', '#88CCEE', '#44AA99', '#117733', '#999933', '#DDCC77', '#661100', '#CC6677', '#882255', '#AA4499'],
                12: ['#332288', '#6699CC', '#88CCEE', '#44AA99', '#117733', '#999933', '#DDCC77', '#661100', '#CC6677', '#AA4466', '#882255', '#AA4499'],
                0: ['#332288', '#44AA99', '#88CCEE', '#DDCC77', '#AA4466', '#117733', '#6699CC', '#661100', '#999933', '#CC6677', '#882255', '#AA4499'],
                openStackSeverity8: ['#CC6677', '#AA4499', '#332288', '#DDCC77', '#999933', '#88CCEE', '#44AA99', '#117733']

            },
            grey: {
                0: ['#bdbdbd']
            }
        }
    }
});
<commit_msg>Assigns error as red and warning as yellow in goldstoneColors model.<commit_after>/**
 * Copyright 2014 Solinea, Inc.
 *
 * Licensed under the Solinea Software License Agreement (goldstone),
 * Version 1.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *     http://www.solinea.com/goldstone/LICENSE.pdf
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
to invoke:
1. include goldstoneColors.js in the template script tags
2. assign the palatte as a variable: var colorArray = new GoldstoneColors().get('colorSets');
3. invoke via colorArray, a subset, and an index corresponding to the size of the array desired

colorArray.distinct[3] (Range of 3 colorBlindFriendly colors)
colorArray.distinct[5] (Range of 5 colorBlindFriendly colors)
etc...

*/

var GoldstoneColors = GoldstoneBaseModel.extend({
    defaults: {
        colorSets: {
            // distinct = colorBlindFriendly
            distinct: {
                1: ['#4477AA'],
                2: ['#4477AA', '#CC6677'],
                3: ['#4477AA', '#DDCC77', '#CC6677'],
                4: ['#4477AA', '#117733', '#DDCC77', '#CC6677'],
                5: ['#332288', '#88CCEE', '#117733', '#DDCC77', '#CC6677'],
                6: ['#332288', '#88CCEE', '#117733', '#DDCC77', '#CC6677', '#AA4499'],
                7: ['#332288', '#88CCEE', '#44AA99', '#117733', '#DDCC77', '#CC6677', '#AA4499'],
                8: ['#332288', '#88CCEE', '#44AA99', '#117733', '#999933', '#DDCC77', '#CC6677', '#AA4499'],
                9: ['#332288', '#88CCEE', '#44AA99', '#117733', '#999933', '#DDCC77', '#CC6677', '#882255', '#AA4499'],
                10: ['#332288', '#88CCEE', '#44AA99', '#117733', '#999933', '#DDCC77', '#661100', '#CC6677', '#882255', '#AA4499'],
                11: ['#332288', '#6699CC', '#88CCEE', '#44AA99', '#117733', '#999933', '#DDCC77', '#661100', '#CC6677', '#882255', '#AA4499'],
                12: ['#332288', '#6699CC', '#88CCEE', '#44AA99', '#117733', '#999933', '#DDCC77', '#661100', '#CC6677', '#AA4466', '#882255', '#AA4499'],
                0: ['#332288', '#44AA99', '#88CCEE', '#DDCC77', '#AA4466', '#117733', '#6699CC', '#661100', '#999933', '#CC6677', '#882255', '#AA4499'],
                openStackSeverity8: ['#AA4499', '#332288', '#999933', '#CC6677', '#DDCC77', '#88CCEE', '#44AA99', '#117733']

                // EMERGENCY: system is unusable
                // ALERT: action must be taken immediately
                // CRITICAL: critical conditions
                // ERROR: error conditions
                // WARNING: warning conditions
                // NOTICE: normal but significant condition
                // INFO: informational messages
                // DEBUG: debug-level messages

            },
            grey: {
                0: ['#bdbdbd']
            }
        }
    }
});
<|endoftext|>


<commit_before>/**
 * Copyright 2014 Solinea, Inc.
 *
 * Licensed under the Solinea Software License Agreement (goldstone),
 * Version 1.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *     http://www.solinea.com/goldstone/LICENSE.pdf
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Author: Alex Jacobs
 */

var EventsReportView = Backbone.View.extend({

    defaults: {},

    urlGen: function() {

        // urlGen is instantiated inside the beforeSend AJAX hook
        // which means it is run again before every dataTables server query

        var now = +new Date();
        var oneDayAgo = (+new Date()) - (1000 * 60 * 60 * 24);
        var oneHourAgo = (+new Date()) - (1000 * 60 * 60);
        var oneWeekAgo = (+new Date()) - (1000 * 60 * 60 * 24 * 7);

        // default to 24 hour lookback
        var urlRouteConstruction = '/core/events?source_name=' +
            this.defaults.hostName + '&created__lte=' + now + '&created__gte=' +
            oneDayAgo;

        this.defaults.url = urlRouteConstruction;

    },

    initialize: function(options) {
        this.options = options || {};
        this.defaults = _.clone(this.defaults);
        this.el = options.el;
        this.defaults.width = options.width;
        this.defaults.hostName = options.nodeName;

        var ns = this.defaults;
        var self = this;

        // required in case spinner loading takes
        // longer than chart loading
        ns.spinnerDisplay = 'inline';

        var spinnerLocation = this.el;
        $('').load(function() {
            $(this).appendTo(spinnerLocation).css({
                'position': 'relative',
                'margin-top': -20,
                'margin-left': (ns.width / 2),
                'display': ns.spinnerDisplay
            });
        });

        // appends display and modal html elements to this.el
        this.render();
    },

    dataPrep: function(data) {
        var ns = this.defaults;
        var self = this;

        // initial result is stringified JSON
        var tableData = JSON.parse(data);

        var finalResults = [];

        _.each(tableData.results, function(item) {

            // if any field is undefined, dataTables throws an alert
            item.id = item.id || '';
            item.event_type = item.event_type || '';
            item.source_id = item.source_id || '';
            item.source_name = item.source_name || '';
            item.message = item.message || '';
            item.created = item.created || '';

            finalResults.push([item.created, item.event_type, item.message, item.id, item.source_id, item.source_name]);
        });

        return {
            recordsTotal: tableData.count,
            recordsFiltered: tableData.count,
            result: finalResults
        };
    },

    drawSearchTable: function(location) {

        var ns = this.defaults;
        var self = this;

        ns.spinnerDisplay = 'none';
        $(this.el).find('#spinner').hide();

        var oTable;
        var oTableParams = {
            "info": false,
            "processing": true,
            "lengthChange": true,
            "paging": true,
            "searching": true,
            "order": [
                [0, 'desc']
            ],
            "ordering": true,
            "serverSide": true,
            "ajax": {
                beforeSend: function(obj, settings) {

                    // warning: as dataTable features are enabled/
                    // disabled , check if the structure of settings.
                    // url changes significantly. Be sure to
                    // reference the correct array indices when
                    // comparing, or scraping data

                    self.urlGen();

                    console.log(decodeURIComponent(settings.url));

                    var pageSize = $('select.form-control').val();
                    var searchQuery = $('input.form-control').val();
                    var paginationStart = settings.url.match(/start=\d{1,}&/gi);
                    paginationStart = paginationStart[0].slice(paginationStart[0].indexOf('=') + 1, paginationStart[0].lastIndexOf('&'));
                    var computeStartPage = Math.floor(paginationStart / pageSize) + 1;

                    var urlColumnOrdering = decodeURIComponent(settings.url).match(/order\[0\]\[column\]=\d*/gi);

                    // capture which column was clicked
                    // and which direction the sort is called for

                    var urlOrderingDirection = decodeURIComponent(settings.url).match(/order\[0\]\[dir\]=(asc|desc)/gi);

                    console.log(urlColumnOrdering, urlOrderingDirection);

                    settings.url = self.defaults.url + "&page_size=" + pageSize + "&page=" + computeStartPage;

                    if (searchQuery) {
                        settings.url = settings.url + "&message__prefix=" + searchQuery;
                    }

                    // if no interesting sort, ignore it

                    console.log('interesting sort?', urlColumnOrdering[0], urlOrderingDirection[0]);

                    if (urlColumnOrdering[0] !== "order[0][column]=0" || urlOrderingDirection[0] !== "order[0][dir]=desc") {
                        // or, if something is different, capture the
                        // column to sort by, and the sort direction

                        var columnLabelHash = {
                            0: 'created',
                            1: 'event_type',
                            2: 'message'
                        };

                        var orderByColumn = urlColumnOrdering[0].slice(urlColumnOrdering[0].indexOf('=') + 1);

                        var orderByDirection = urlOrderingDirection[0].slice(urlOrderingDirection[0].indexOf('=') + 1);

                        var ascDec;
                        if (orderByDirection === 'desc') {
                            ascDec = '';
                        } else {
                            ascDec = '-';
                        }

                        settings.url = settings.url + "&ordering=" +
                            ascDec + columnLabelHash[orderByColumn];
                    }

                    console.log('final url: ', settings.url);

                },
                dataFilter: function(data) {

                    // runs result through this.dataPrep
                    var result = self.dataPrep(data);

                    // dataTables expects JSON encoded result
                    return JSON.stringify(result);
                },
                // tells dataTable to look for 'result' param of result object
                dataSrc: "result"
            },
            "columnDefs": [{
                "name": "created",
                "type": "date",
                "targets": 0,
                "render": function(data, type, full, meta) {
                    return moment(data).format();
                }
            }, {
                "name": "event_type",
                "targets": 1
            }, {
                "name": "message",
                "targets": 2
            }, {
                "name": "id",
                "targets": 3
            }, {
                "name": "source_id",
                "targets": 4
            }, {
                "name": "source_name",
                "targets": 5
            }, {
                "visible": false,
                "targets": [3, 4, 5]
            }]
        };

        oTable = $(location).DataTable(oTableParams);
    },

    render: function() {
        $(this.el).append(this.template());
        this.drawSearchTable('#events-report-table');
        return this;
    },

    template: _.template(

        '
' +
        '
' +
        '
' +
        '
' +
        '
 Events Report' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
' +
        'Created	' +
        'Event Type	' +
        'Message	' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
')
});
<commit_msg>Corrects misinterpretation of asc -vs - desc in column sort.<commit_after>/**
 * Copyright 2014 Solinea, Inc.
 *
 * Licensed under the Solinea Software License Agreement (goldstone),
 * Version 1.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *     http://www.solinea.com/goldstone/LICENSE.pdf
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Author: Alex Jacobs
 */

var EventsReportView = Backbone.View.extend({

    defaults: {},

    urlGen: function() {

        // urlGen is instantiated inside the beforeSend AJAX hook
        // which means it is run again before every dataTables server query

        var now = +new Date();
        var oneDayAgo = (+new Date()) - (1000 * 60 * 60 * 24);
        var oneHourAgo = (+new Date()) - (1000 * 60 * 60);
        var oneWeekAgo = (+new Date()) - (1000 * 60 * 60 * 24 * 7);

        // default to 24 hour lookback
        var urlRouteConstruction = '/core/events?source_name=' +
            this.defaults.hostName + '&created__lte=' + now + '&created__gte=' +
            oneDayAgo;

        this.defaults.url = urlRouteConstruction;

    },

    initialize: function(options) {
        this.options = options || {};
        this.defaults = _.clone(this.defaults);
        this.el = options.el;
        this.defaults.width = options.width;
        this.defaults.hostName = options.nodeName;

        var ns = this.defaults;
        var self = this;

        // required in case spinner loading takes
        // longer than chart loading
        ns.spinnerDisplay = 'inline';

        var spinnerLocation = this.el;
        $('').load(function() {
            $(this).appendTo(spinnerLocation).css({
                'position': 'relative',
                'margin-top': -20,
                'margin-left': (ns.width / 2),
                'display': ns.spinnerDisplay
            });
        });

        // appends display and modal html elements to this.el
        this.render();
    },

    dataPrep: function(data) {
        var ns = this.defaults;
        var self = this;

        // initial result is stringified JSON
        var tableData = JSON.parse(data);

        var finalResults = [];

        _.each(tableData.results, function(item) {

            // if any field is undefined, dataTables throws an alert
            item.id = item.id || '';
            item.event_type = item.event_type || '';
            item.source_id = item.source_id || '';
            item.source_name = item.source_name || '';
            item.message = item.message || '';
            item.created = item.created || '';

            finalResults.push([item.created, item.event_type, item.message, item.id, item.source_id, item.source_name]);
        });

        return {
            recordsTotal: tableData.count,
            recordsFiltered: tableData.count,
            result: finalResults
        };
    },

    drawSearchTable: function(location) {

        var ns = this.defaults;
        var self = this;

        ns.spinnerDisplay = 'none';
        $(this.el).find('#spinner').hide();

        var oTable;
        var oTableParams = {
            "info": false,
            "processing": true,
            "lengthChange": true,
            "paging": true,
            "searching": true,
            "order": [
                [0, 'desc']
            ],
            "ordering": true,
            "serverSide": true,
            "ajax": {
                beforeSend: function(obj, settings) {

                    // warning: as dataTable features are enabled/
                    // disabled , check if the structure of settings.
                    // url changes significantly. Be sure to
                    // reference the correct array indices when
                    // comparing, or scraping data

                    self.urlGen();

                    console.log(decodeURIComponent(settings.url));

                    var pageSize = $('select.form-control').val();
                    var searchQuery = $('input.form-control').val();
                    var paginationStart = settings.url.match(/start=\d{1,}&/gi);
                    paginationStart = paginationStart[0].slice(paginationStart[0].indexOf('=') + 1, paginationStart[0].lastIndexOf('&'));
                    var computeStartPage = Math.floor(paginationStart / pageSize) + 1;

                    var urlColumnOrdering = decodeURIComponent(settings.url).match(/order\[0\]\[column\]=\d*/gi);

                    // capture which column was clicked
                    // and which direction the sort is called for

                    var urlOrderingDirection = decodeURIComponent(settings.url).match(/order\[0\]\[dir\]=(asc|desc)/gi);

                    console.log(urlColumnOrdering, urlOrderingDirection);

                    settings.url = self.defaults.url + "&page_size=" + pageSize + "&page=" + computeStartPage;

                    if (searchQuery) {
                        settings.url = settings.url + "&message__prefix=" + searchQuery;
                    }

                    // if no interesting sort, ignore it

                    console.log('interesting sort?', urlColumnOrdering[0], urlOrderingDirection[0]);

                    if (urlColumnOrdering[0] !== "order[0][column]=0" || urlOrderingDirection[0] !== "order[0][dir]=desc") {
                        // or, if something is different, capture the
                        // column to sort by, and the sort direction

                        var columnLabelHash = {
                            0: 'created',
                            1: 'event_type',
                            2: 'message'
                        };

                        var orderByColumn = urlColumnOrdering[0].slice(urlColumnOrdering[0].indexOf('=') + 1);

                        var orderByDirection = urlOrderingDirection[0].slice(urlOrderingDirection[0].indexOf('=') + 1);

                        var ascDec;
                        if (orderByDirection === 'asc') {
                            ascDec = '';
                        } else {
                            ascDec = '-';
                        }

                        settings.url = settings.url + "&ordering=" +
                            ascDec + columnLabelHash[orderByColumn];
                    }

                    console.log('final url: ', settings.url);

                },
                dataFilter: function(data) {

                    // runs result through this.dataPrep
                    var result = self.dataPrep(data);

                    // dataTables expects JSON encoded result
                    return JSON.stringify(result);
                },
                // tells dataTable to look for 'result' param of result object
                dataSrc: "result"
            },
            "columnDefs": [{
                "name": "created",
                "type": "date",
                "targets": 0,
                "render": function(data, type, full, meta) {
                    return moment(data).format();
                }
            }, {
                "name": "event_type",
                "targets": 1
            }, {
                "name": "message",
                "targets": 2
            }, {
                "name": "id",
                "targets": 3
            }, {
                "name": "source_id",
                "targets": 4
            }, {
                "name": "source_name",
                "targets": 5
            }, {
                "visible": false,
                "targets": [3, 4, 5]
            }]
        };

        oTable = $(location).DataTable(oTableParams);
    },

    render: function() {
        $(this.el).append(this.template());
        this.drawSearchTable('#events-report-table');
        return this;
    },

    template: _.template(

        '
' +
        '
' +
        '
' +
        '
' +
        '
 Events Report' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
' +
        'Created	' +
        'Event Type	' +
        'Message	' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
')
});
<|endoftext|>


<commit_before>var vow = require('vow'),
    path = require('path'),
    cp = require('child_process');

module.exports = require('enb/lib/build-flow').create()
    .name('jsdoc-json-jsdoc3')
    .target('target', '?.jsdoc.json')
    .useFileList(['js'])
    .builder(function (files) {
        var isWinOS = path.sep === '\\';

        if (files.length === 0) {
            return '{}';
        }

        var jsdoc = cp.spawn(
                path.resolve(__dirname, '../../node_modules/.bin/jsdoc' + (isWinOS ? '.cmd' : '')), [
                    '-c', path.resolve(__dirname, '../jsdoc3/jsdoc.conf.json'),
                    '-t', path.resolve(__dirname, '../../node_modules/jsdoc-bem/templates/docjson')
                ].concat(files.map(function (file) {
                    return file.fullname;
                }))
            ),

            content = '',
            err = '',
            d = vow.defer();

        jsdoc.stdout.on('data', function (data) {
            content += data;
        });

        jsdoc.stderr.on('data', function (data) {
            err += data;
        });

        jsdoc.on('close', function (code) {
            if (code !== 0) {
                throw new Error(err);
            }
            d.resolve(content);
        });

        return d.promise();
    })
    .createTech();
<commit_msg>Do not fail on JSDoc3 errors<commit_after>var vow = require('vow'),
    path = require('path'),
    cp = require('child_process');

module.exports = require('enb/lib/build-flow').create()
    .name('jsdoc-json-jsdoc3')
    .target('target', '?.jsdoc.json')
    .useFileList(['js'])
    .builder(function (files) {
        var isWinOS = path.sep === '\\',
            logger = this.node.getLogger(),
            target = this._target;

        if (files.length === 0) {
            return '{}';
        }

        var jsdoc = cp.spawn(
                path.resolve(__dirname, '../../node_modules/.bin/jsdoc' + (isWinOS ? '.cmd' : '')), [
                    '-c', path.resolve(__dirname, '../jsdoc3/jsdoc.conf.json'),
                    '-t', path.resolve(__dirname, '../../node_modules/jsdoc-bem/templates/docjson')
                ].concat(files.map(function (file) {
                    return file.fullname;
                }))
            ),

            content = '',
            err = '',
            d = vow.defer();

        jsdoc.stdout.on('data', function (data) {
            content += data;
        });

        jsdoc.stderr.on('data', function (data) {
            err += data;
        });

        jsdoc.on('close', function (code) {
            if (code !== 0) {
                logger.logWarningAction('js-doc', target, err);
                return d.resolve('{}');
            }

            d.resolve(content);
        });

        return d.promise();
    })
    .createTech();
<|endoftext|>


<commit_before>
/*!
 * socket.io-node
 * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

/**
 * Module requirements.
 */

var HTTPTransport = require('./http');

/**
 * Exports the constructor.
 */

exports = module.exports = HTTPPolling;

/**
 * HTTP polling constructor.
 *
 * @api public.
 */

function HTTPPolling (mng, data, req) {
  HTTPTransport.call(this, mng, data, req);
};

/**
 * Inherits from HTTPTransport.
 *
 * @api public.
 */

HTTPPolling.prototype.__proto__ = HTTPTransport.prototype;

/**
 * Transport name
 *
 * @api public
 */

HTTPPolling.prototype.name = 'httppolling';

/**
 * Removes heartbeat timeouts for polling.
 */

HTTPPolling.prototype.setHeartbeatInterval = function () {
  return this;
};

/**
 * Handles a request
 *
 * @api private
 */

HTTPPolling.prototype.handleRequest = function (req) {
  HTTPTransport.prototype.handleRequest.call(this, req);

  if (req.method == 'GET') {
    var self = this;

    this.pollTimeout = setTimeout(function () {
      self.packet({ type: 'noop' });
      self.log.debug(self.name + ' closed due to exceeded duration');
    }, this.manager.get('polling duration') * 1000);

    this.log.debug('setting poll timeout');
  }
};

/**
 * Clears polling timeout
 *
 * @api private
 */

HTTPPolling.prototype.clearPollTimeout = function () {
  if (this.pollTimeout) {
    clearTimeout(this.pollTimeout);
    this.pollTimeout = null;
    this.log.debug('clearing poll timeout');
  }

  return this;
};

/**
 * Override clear timeouts to clear the poll timeout
 *
 * @api private
 */

HTTPPolling.prototype.clearTimeouts = function () {
  HTTPTransport.prototype.clearTimeouts.call(this);

  this.clearPollTimeout();
};

/**
 * doWrite to clear poll timeout
 *
 * @api private
 */

HTTPPolling.prototype.doWrite = function () {
  this.clearPollTimeout();
};

/**
 * Performs a write.
 *
 * @api private.
 */

HTTPPolling.prototype.write = function (data, close) {
  this.doWrite(data);
  this.response.end();
  this.onClose();
};

/**
 * Override end.
 *
 * @api private
 */

HTTPPolling.prototype.end = function () {
  this.clearPollTimeout();
  return HTTPTransport.prototype.end.call(this);
};

<commit_msg>Ensure that polling transports work with Connection: close<commit_after>
/*!
 * socket.io-node
 * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

/**
 * Module requirements.
 */

var HTTPTransport = require('./http');

/**
 * Exports the constructor.
 */

exports = module.exports = HTTPPolling;

/**
 * HTTP polling constructor.
 *
 * @api public.
 */

function HTTPPolling (mng, data, req) {
  HTTPTransport.call(this, mng, data, req);
};

/**
 * Inherits from HTTPTransport.
 *
 * @api public.
 */

HTTPPolling.prototype.__proto__ = HTTPTransport.prototype;

/**
 * Transport name
 *
 * @api public
 */

HTTPPolling.prototype.name = 'httppolling';

/**
 * Override setHandlers
 *
 * @api private
 */

HTTPPolling.prototype.setHandlers = function () {
  HTTPTransport.prototype.setHandlers.call(this);
  this.socket.removeListener('end', this.bound.end);
  this.socket.removeListener('close', this.bound.close);
};

/**
 * Removes heartbeat timeouts for polling.
 */

HTTPPolling.prototype.setHeartbeatInterval = function () {
  return this;
};

/**
 * Handles a request
 *
 * @api private
 */

HTTPPolling.prototype.handleRequest = function (req) {
  HTTPTransport.prototype.handleRequest.call(this, req);

  if (req.method == 'GET') {
    var self = this;

    this.pollTimeout = setTimeout(function () {
      self.packet({ type: 'noop' });
      self.log.debug(self.name + ' closed due to exceeded duration');
    }, this.manager.get('polling duration') * 1000);

    this.log.debug('setting poll timeout');
  }
};

/**
 * Clears polling timeout
 *
 * @api private
 */

HTTPPolling.prototype.clearPollTimeout = function () {
  if (this.pollTimeout) {
    clearTimeout(this.pollTimeout);
    this.pollTimeout = null;
    this.log.debug('clearing poll timeout');
  }

  return this;
};

/**
 * Override clear timeouts to clear the poll timeout
 *
 * @api private
 */

HTTPPolling.prototype.clearTimeouts = function () {
  HTTPTransport.prototype.clearTimeouts.call(this);

  this.clearPollTimeout();
};

/**
 * doWrite to clear poll timeout
 *
 * @api private
 */

HTTPPolling.prototype.doWrite = function () {
  this.clearPollTimeout();
};

/**
 * Performs a write.
 *
 * @api private.
 */

HTTPPolling.prototype.write = function (data, close) {
  this.doWrite(data);
  this.response.end();
  this.onClose();
};

/**
 * Override end.
 *
 * @api private
 */

HTTPPolling.prototype.end = function () {
  this.clearPollTimeout();
  return HTTPTransport.prototype.end.call(this);
};

<|endoftext|>


<commit_before>/**
 * node-zip-stream
 *
 * Copyright (c) 2014 Chris Talkington, contributors.
 * Licensed under the MIT license.
 * https://github.com/ctalkington/node-zip-stream/blob/master/LICENSE-MIT
 */
var zlib = require('zlib');
var inherits = require('util').inherits;

var util = require('./');

function DeflateRawChecksum(options) {
  zlib.DeflateRaw.call(this, options);

  this.checksum = util.crc32();
  this.digest = null;

  this.rawSize = 0;
  this.compressedSize = 0;

  this.on('data', function(chunk) {
    this.compressedSize += chunk.length;
  });

  this.once('end', function() {
    this.digest = this.checksum.digest();
  });
}

inherits(DeflateRawChecksum, zlib.DeflateRaw);

DeflateRawChecksum.prototype.write = function(chunk, cb) {
  if (chunk) {
    this.checksum.update(chunk);
    this.rawSize += chunk.length;
  }

  return zlib.DeflateRaw.prototype.write.call(this, chunk, cb);
};

module.exports = DeflateRawChecksum;
<commit_msg>util: count compressed byte length by extending push instead of data events. think we may be reverting to streams1 by using event so early on.<commit_after>/**
 * node-zip-stream
 *
 * Copyright (c) 2014 Chris Talkington, contributors.
 * Licensed under the MIT license.
 * https://github.com/ctalkington/node-zip-stream/blob/master/LICENSE-MIT
 */
var zlib = require('zlib');
var inherits = require('util').inherits;

var util = require('./');

function DeflateRawChecksum(options) {
  zlib.DeflateRaw.call(this, options);

  this.checksum = util.crc32();
  this.digest = null;

  this.rawSize = 0;
  this.compressedSize = 0;

  this.once('end', function() {
    this.digest = this.checksum.digest();
  });
}

inherits(DeflateRawChecksum, zlib.DeflateRaw);

DeflateRawChecksum.prototype.push = function(chunk, encoding) {
  if (chunk) {
    this.compressedSize += chunk.length;
  }

  return zlib.DeflateRaw.prototype.push.call(this, chunk, encoding);
};

DeflateRawChecksum.prototype.write = function(chunk, cb) {
  if (chunk) {
    this.checksum.update(chunk);
    this.rawSize += chunk.length;
  }

  return zlib.DeflateRaw.prototype.write.call(this, chunk, cb);
};

module.exports = DeflateRawChecksum;
<|endoftext|>