<commit_before>var assert = require("assert");
var parse = require("../lib/parser").parse;
var Printer = require("../lib/printer").Printer;
var util = require("../lib/util");
var n = require("../lib/types").namedTypes;
var b = require("../lib/types").builders;
var printer = new Printer;

function parseExpression(expr) {
    var ast = parse(expr);
    n.File.assert(ast);
    ast = ast.program.body[0];
    if (n.ExpressionStatement.check(ast))
        return ast.expression;
    return ast;
}

function check(expr) {
    var ast1 = parseExpression(expr);
    var printed = printer.printGenerically(ast1);
    try {
        var ast2 = parseExpression(printed);
    } finally {
        assert.ok(
            util.deepEquivalent(ast1, ast2),
            expr + " printed incorrectly as " + printed
        );
    }
}

var operators = [
    "==", "!=", "===", "!==",
    "<", "<=", ">", ">=",
    "<<", ">>", ">>>",
    "+", "-", "*", "/", "%",
    "&", // TODO Missing from the Parser API.
    "|", "^", "in",
    "instanceof",
    "&&", "||"
];

exports.testArithmetic = function(t) {
    check("1 - 2");
    check("  2 +2 ");

    operators.forEach(function(op1) {
        operators.forEach(function(op2) {
            check("(a " + op1 + " b) " + op2 + " c");
            check("a " + op1 + " (b " + op2 + " c)");
        });
    });

    t.finish();
};

exports.testUnary = function(t) {
    check("(-a).b");
    check("(+a).b");
    check("(!a).b");
    check("(~a).b");
    check("(typeof a).b");
    check("(void a).b");
    check("(delete a.b).c");

    t.finish();
};

exports.testBinary = function(t) {
    check("(a && b)()");
    check("typeof (a && b)");
    check("(a && b)[c]");
    check("(a && b).c");

    t.finish();
};

exports.testSequence = function(t) {
    check("(a, b)()");
    check("a(b, (c, d), e)");
    check("!(a, b)");
    check("a + (b, c) + d");
    check("var a = (1, 2), b = a + a;");
    check("(a, { b: 2 }).b");
    check("[a, (b, c), d]");
    check("({ a: (1, 2) }).a");
    check("(a, b) ? (a = 1, b = 2) : (c = 3)");

    t.finish();
};

exports.testNewExpression = function(t) {
    check("new (a.b())");
    check("new (a.b())(c)");
    check("new a.b(c)");
    check("+new Date");
    check("(new Date).getTime()");
    check("new a");
    check("(new a)(b)");
    check("(new (a.b(c))(d))(e)");
    check("(new Date)['getTime']()");
    check('(new Date)["getTime"]()');

    t.finish();
};

exports.testNumbers = function(t) {
    check("(1).foo");
    check("(-1).foo");
    check("+0");
    check("NaN.foo");
    check("(-Infinity).foo");

    t.finish();
};

exports.testAssign = function(t) {
    check("!(a = false)");
    check("a + (b = 2) + c");
    check("(a = fn)()");
    check("(a = b) ? c : d");
    check("(a = b)[c]");
    check("(a = b).c");

    t.finish();
};

exports.testFunction = function(t) {
    check("a(function(){}.bind(this))");
    check("(function(){}).apply(this, arguments)");
    check("function f() { (function(){}).call(this) }");
    check("while (true) { (function(){}).call(this) }");

    t.finish();
};

exports.testObjectLiteral = function(t) {
    check("a({b:c(d)}.b)");
    check("({a:b(c)}).a");

    t.finish();
};

exports.testReprintedParens = function(t) {
    var code = "a(function g(){}.call(this));";
    var ast1 = parse(code);
    var body = ast1.program.body;

    // Copy the function from a position where it does not need
    // parentheses to a position where it does need parentheses.
    body.push(b.expressionStatement(
        body[0].expression.arguments[0]));

    var generic = printer.printGenerically(ast1);
    var ast2 = parse(generic);
    assert.ok(
        util.deepEquivalent(ast1, ast2),
        "generic reprinting failed: " + generic);

    var reprint = printer.print(ast1);
    var ast3 = parse(reprint);
    assert.ok(
        util.deepEquivalent(ast1, ast3),
        "conservative reprinting failed: " + reprint);

    t.finish();
};
<commit_msg>Use esprima.parse in hot parentheses test loop.<commit_after>var assert = require("assert");
var esprima = require("esprima");
var parse = require("../lib/parser").parse;
var Printer = require("../lib/printer").Printer;
var util = require("../lib/util");
var n = require("../lib/types").namedTypes;
var b = require("../lib/types").builders;
var printer = new Printer;

function parseExpression(expr) {
    var ast = esprima.parse(expr);
    n.Program.assert(ast);
    ast = ast.body[0];
    if (n.ExpressionStatement.check(ast))
        return ast.expression;
    return ast;
}

function check(expr) {
    var ast1 = parseExpression(expr);
    var printed = printer.printGenerically(ast1);
    try {
        var ast2 = parseExpression(printed);
    } finally {
        assert.ok(
            util.deepEquivalent(ast1, ast2),
            expr + " printed incorrectly as " + printed
        );
    }
}

var operators = [
    "==", "!=", "===", "!==",
    "<", "<=", ">", ">=",
    "<<", ">>", ">>>",
    "+", "-", "*", "/", "%",
    "&", // TODO Missing from the Parser API.
    "|", "^", "in",
    "instanceof",
    "&&", "||"
];

exports.testArithmetic = function(t) {
    check("1 - 2");
    check("  2 +2 ");

    operators.forEach(function(op1) {
        operators.forEach(function(op2) {
            check("(a " + op1 + " b) " + op2 + " c");
            check("a " + op1 + " (b " + op2 + " c)");
        });
    });

    t.finish();
};

exports.testUnary = function(t) {
    check("(-a).b");
    check("(+a).b");
    check("(!a).b");
    check("(~a).b");
    check("(typeof a).b");
    check("(void a).b");
    check("(delete a.b).c");

    t.finish();
};

exports.testBinary = function(t) {
    check("(a && b)()");
    check("typeof (a && b)");
    check("(a && b)[c]");
    check("(a && b).c");

    t.finish();
};

exports.testSequence = function(t) {
    check("(a, b)()");
    check("a(b, (c, d), e)");
    check("!(a, b)");
    check("a + (b, c) + d");
    check("var a = (1, 2), b = a + a;");
    check("(a, { b: 2 }).b");
    check("[a, (b, c), d]");
    check("({ a: (1, 2) }).a");
    check("(a, b) ? (a = 1, b = 2) : (c = 3)");

    t.finish();
};

exports.testNewExpression = function(t) {
    check("new (a.b())");
    check("new (a.b())(c)");
    check("new a.b(c)");
    check("+new Date");
    check("(new Date).getTime()");
    check("new a");
    check("(new a)(b)");
    check("(new (a.b(c))(d))(e)");
    check("(new Date)['getTime']()");
    check('(new Date)["getTime"]()');

    t.finish();
};

exports.testNumbers = function(t) {
    check("(1).foo");
    check("(-1).foo");
    check("+0");
    check("NaN.foo");
    check("(-Infinity).foo");

    t.finish();
};

exports.testAssign = function(t) {
    check("!(a = false)");
    check("a + (b = 2) + c");
    check("(a = fn)()");
    check("(a = b) ? c : d");
    check("(a = b)[c]");
    check("(a = b).c");

    t.finish();
};

exports.testFunction = function(t) {
    check("a(function(){}.bind(this))");
    check("(function(){}).apply(this, arguments)");
    check("function f() { (function(){}).call(this) }");
    check("while (true) { (function(){}).call(this) }");

    t.finish();
};

exports.testObjectLiteral = function(t) {
    check("a({b:c(d)}.b)");
    check("({a:b(c)}).a");

    t.finish();
};

exports.testReprintedParens = function(t) {
    var code = "a(function g(){}.call(this));";
    var ast1 = parse(code);
    var body = ast1.program.body;

    // Copy the function from a position where it does not need
    // parentheses to a position where it does need parentheses.
    body.push(b.expressionStatement(
        body[0].expression.arguments[0]));

    var generic = printer.printGenerically(ast1);
    var ast2 = parse(generic);
    assert.ok(
        util.deepEquivalent(ast1, ast2),
        "generic reprinting failed: " + generic);

    var reprint = printer.print(ast1);
    var ast3 = parse(reprint);
    assert.ok(
        util.deepEquivalent(ast1, ast3),
        "conservative reprinting failed: " + reprint);

    t.finish();
};
<|endoftext|>


<commit_before>var kdbtree = require('../')
var test = require('tape')
var fdstore = require('fd-chunk-store')
var tmpdir = require('os').tmpdir()
var almostEqual = require('almost-equal')
var FLT = almostEqual.FLT_EPSILON

var path = require('path')
var file = path.join(tmpdir, 'kdb-tree-' + Math.random())

test('points', function (t) {
  var n = 20
  t.plan(n*(2+4+2) + 2)
  var kdb = kdbtree({
    types: [ 'float32', 'float32', 'float32' ],
    size: 4096,
    store: fdstore(4096, file),
    root: 0
  })
  var data = []
  var pending = n
  for (var i = 0; i < n; i++) (function () {
    var x = Math.random() * 200 - 100
    var y = Math.random() * 200 - 100
    var z = Math.random() * 200 - 100
    var loc = Math.floor(Math.random() * 1000)
    data.push([x,y,z,loc])
    kdb.insert([x,y,z,loc], function (err) {
      t.ifError(err)
      kdb.query([x,y,z], function (err, pts) {
        t.ifError(err)
        t.equal(pts.length, 1)
        approx(t, pts[0], [x,y,z,loc])
        t.equal(pts[0][3], loc)
        if (--pending === 0) check()
      })
    })
  })()

  function check () {
    kdb.query([[15,50],[-60,10],[50,100]], function (err, pts) {
      t.ifError(err)
      t.deepEqual(pts, data.filter(function (pt) {
        return pt[0] >= 15 && pt[0] <= 50
          && pt[1] >= -60 && pt[1] <= 10
          && pt[2] >= 50 && pt[2] <= 100
      }))
    })
  }
})

function approx (t, a, b) {
  for (var i = 0; i < a.length; i++) {
    t.ok(almostEqual(a[i], b[i], FLT, FLT),
      'approx equal: ' + a[i] + ' ~ ' + b[i])
  }
}
<commit_msg>approximate results in final query check<commit_after>var kdbtree = require('../')
var test = require('tape')
var fdstore = require('fd-chunk-store')
var tmpdir = require('os').tmpdir()
var almostEqual = require('almost-equal')
var FLT = almostEqual.FLT_EPSILON

var path = require('path')
var file = path.join(tmpdir, 'kdb-tree-' + Math.random())

test('points', function (t) {
  var n = 20
  var kdb = kdbtree({
    types: [ 'float32', 'float32', 'float32' ],
    size: 4096,
    store: fdstore(4096, file),
    root: 0
  })
  var data = []
  var pending = n
  for (var i = 0; i < n; i++) (function () {
    var x = Math.random() * 200 - 100
    var y = Math.random() * 200 - 100
    var z = Math.random() * 200 - 100
    var loc = Math.floor(Math.random() * 1000)
    data.push([x,y,z,loc])
    kdb.insert([x,y,z,loc], function (err) {
      t.ifError(err)
      kdb.query([x,y,z], function (err, pts) {
        t.ifError(err)
        t.equal(pts.length, 1)
        approx(t, pts[0], [x,y,z,loc])
        t.equal(pts[0][3], loc)
        if (--pending === 0) check()
      })
    })
  })()

  function check () {
    kdb.query([[15,50],[-60,10],[50,100]], function (err, pts) {
      t.ifError(err)
      var expected = data.filter(function (pt) {
        return pt[0] >= 15 && pt[0] <= 50
          && pt[1] >= -60 && pt[1] <= 10
          && pt[2] >= 50 && pt[2] <= 100
      })
      for (var i = 0; i < Math.max(pts.length, expected.length); i++) {
        approx(t, pts[i], expected[i])
      }
      t.end()
    })
  }
})

function approx (t, a, b) {
  for (var i = 0; i < a.length; i++) {
    t.ok(almostEqual(a[i], b[i], FLT, FLT),
      'approx equal: ' + a[i] + ' ~ ' + b[i])
  }
}
<|endoftext|>


<commit_before>/* eslint-env mocha */
const request = require('supertest');
const fs = require('fs');
const server = require('../server');
const expect = require('expect.js');

describe('Test api', function() {
  describe('get definition', function() {
    it('should return definition.yml', done => {
      request(server)
          .get('/definition.yml')
          .expect(res => {
            const definition = res.text;
            const definitionFile = fs.readFileSync('definition.yml');
            expect(definition).to.equal(definitionFile.toString());
          })
          .expect(200, done);
    });
  });

  describe('with unknown route', function() {
    it('should reply with 404', done => {
      request(server)
          .get('/no-where')
          .expect(404, done);
    });
  });

  /* Communes */
  describe('Communes', function() {
    describe('with no input', function() {
      it('should reply with 400', done => {
        request(server)
            .get('/communes')
            .expect(400, done);
      });
    });

    describe('with code insee', function() {
      it('should work for insee 94067', function() {
        request(server)
            .get('/communes/?code=94067')
            .expect(200);
      });

      describe('with name', function() {
        it('should work for Paris', done => {
          request(server)
              .get('/communes/?nom=paris')
              .expect(200, done);
        });
      });

      describe('with code postal', function() {
        it('should work for cp 28100', done => {
          request(server)
              .get('/communes/?codePostal=28100')
              .expect(res => {
                expect(res.body.length).to.equal(1);
                const commune = res.body[0];
                expect(commune.nom).to.equal('Dreux');
              })
              .end(done);
        });
      });

      it('should reply a commune', done => {
        request(server)
          .get('/communes/?code=55001')
          .expect(res => {
            expect(res.body.length).to.equal(1);
            const commune = res.body[0];
            expect(commune.nom).to.equal('Abainville');
            expect(commune.code).to.equal('55001');
            expect(commune.codesPostaux).to.eql(['55130']);
            expect(commune).to.have.keys(['population', 'codeDepartement', 'codeRegion']);
          })
          .end(done);
      });
    });

    describe('with format', function() {
      it('should return a FeatureCollection (geojson)', done => {
        request(server)
            .get('/communes/?code=94067&format=geojson')
            .expect(res => {
              const communes = res.body;
              expect(communes).to.have.key('type');
              expect(communes.type).to.be('FeatureCollection');
            })
            .end(done);
      });
    });
  });

  /* Départements */
  describe('Departements', function() {
    describe('with no input', function() {
      it('should reply with 200', done => {
        request(server)
            .get('/departements')
            .expect(200, done);
      });
      it('should reply all 101 departements', done => {
        request(server)
            .get('/departements')
            .expect(res => {
              expect(res.body.length).to.equal(101);
            })
            .end(done);
      });
    });

    describe('with code', function() {
      it('should work for 75', function() {
        request(server)
            .get('/departements/?code=75')
            .expect(200);
      });

      describe('with name', function() {
        it('should work for Paris', done => {
          request(server)
              .get('/departements/?nom=paris')
              .expect(200, done);
        });
      });

      describe('with code region', function() {
        it('should work for 11', done => {
          request(server)
              .get('/departements/?codeRegion=11')
              .expect(res => {
                expect(res.body.length).to.equal(8);
                const departement = res.body[0];
                expect(departement.nom).to.equal('Paris');
              })
              .end(done);
        });
        it('should reply a departement', done => {
          request(server)
            .get('/departements/?code=27')
            .expect(res => {
              expect(res.body.length).to.equal(1);
              const departement = res.body[0];
              expect(departement).to.eql({ nom: 'Eure', code: '27', codeRegion: '28' });
            })
            .end(done);
        });
      });

      describe('list communes', function() {
        it('should reply the list of communes', done => {
          request(server)
              .get('/departements/11/communes')
              .expect(res => {
                expect(res.body.length).to.equal(436);
              })
              .end(done);
        });
        it('should reply with 404', done => {
          request(server)
              .get('/departements/666/communes')
              .expect(404, done);
        });
        it('should return a FeatureCollection (geojson)', done => {
          request(server)
              .get('/departements/75/communes?format=geojson')
              .expect(res => {
                const communes = res.body;
                expect(communes).to.have.key('type');
                expect(communes.type).to.be('FeatureCollection');
              })
              .end(done);
        });
      });

    });
  });

  /* Régions */
  describe('Regions', function() {
    describe('with no input', function() {
      it('should reply with 200', done => {
        request(server)
            .get('/regions')
            .expect(200, done);
      });
      it('should reply all 18 regions', done => {
        request(server)
            .get('/regions')
            .expect(res => {
              expect(res.body.length).to.equal(18);
            })
            .end(done);
      });
    });

    describe('with code', function() {
      it('should work for 28', function() {
        request(server)
            .get('/regions/?code=28')
            .expect(200);
      });
      it('should reply a departement', done => {
        request(server)
          .get('/regions/?code=28')
          .expect(res => {
            expect(res.body.length).to.equal(1);
            const departement = res.body[0];
            expect(departement).to.eql({ nom: 'Normandie', code: '28' });
          })
          .end(done);
      });
    });

    describe('with name', function() {
      it('should work for Normandie', done => {
        request(server)
            .get('/regions/?nom=normandie')
            .expect(200, done);
      });
    });
  });
});
<commit_msg>Add new route tests<commit_after>/* eslint-env mocha */
const request = require('supertest');
const fs = require('fs');
const server = require('../server');
const expect = require('expect.js');

describe('Test api', function() {
  describe('get definition', function() {
    it('should return definition.yml', done => {
      request(server)
          .get('/definition.yml')
          .expect(res => {
            const definition = res.text;
            const definitionFile = fs.readFileSync('definition.yml');
            expect(definition).to.equal(definitionFile.toString());
          })
          .expect(200, done);
    });
  });

  describe('with unknown route', function() {
    it('should reply with 404', done => {
      request(server)
          .get('/no-where')
          .expect(404, done);
    });
  });

  /* Communes */
  describe('Communes', function() {
    describe('with no input', function() {
      it('should reply with 400', done => {
        request(server)
            .get('/communes')
            .expect(400, done);
      });
    });

    describe('with code insee', function() {
      it('should work for insee 94067', function() {
        request(server)
            .get('/communes/?code=94067')
            .expect(200);
      });

      describe('with name', function() {
        it('should work for Paris', done => {
          request(server)
              .get('/communes/?nom=paris')
              .expect(200, done);
        });
      });

      describe('with code postal', function() {
        it('should work for cp 28100', done => {
          request(server)
              .get('/communes/?codePostal=28100')
              .expect(res => {
                expect(res.body.length).to.equal(1);
                const commune = res.body[0];
                expect(commune.nom).to.equal('Dreux');
              })
              .end(done);
        });
      });

      it('should reply a commune', done => {
        request(server)
          .get('/communes/?code=55001')
          .expect(res => {
            expect(res.body.length).to.equal(1);
            const commune = res.body[0];
            expect(commune.nom).to.equal('Abainville');
            expect(commune.code).to.equal('55001');
            expect(commune.codesPostaux).to.eql(['55130']);
            expect(commune).to.have.keys(['population', 'codeDepartement', 'codeRegion']);
          })
          .end(done);
      });
    });

    describe('with format', function() {
      it('should return a FeatureCollection (geojson)', done => {
        request(server)
            .get('/communes/?code=94067&format=geojson')
            .expect(res => {
              const communes = res.body;
              expect(communes).to.have.key('type');
              expect(communes.type).to.be('FeatureCollection');
            })
            .end(done);
      });
    });
  });

  /* Départements */
  describe('Departements', function() {
    describe('with no input', function() {
      it('should reply with 200', done => {
        request(server)
            .get('/departements')
            .expect(200, done);
      });
      it('should reply all 101 departements', done => {
        request(server)
            .get('/departements')
            .expect(res => {
              expect(res.body.length).to.equal(101);
            })
            .end(done);
      });
    });

    describe('with code', function() {
      it('should work for 75', function() {
        request(server)
            .get('/departements/?code=75')
            .expect(200);
      });

      describe('with name', function() {
        it('should work for Paris', done => {
          request(server)
              .get('/departements/?nom=paris')
              .expect(200, done);
        });
      });

      describe('with code region', function() {
        it('should work for 11', done => {
          request(server)
              .get('/departements/?codeRegion=11')
              .expect(res => {
                expect(res.body.length).to.equal(8);
                const departement = res.body[0];
                expect(departement.nom).to.equal('Paris');
              })
              .end(done);
        });
        it('should reply a departement', done => {
          request(server)
            .get('/departements/?code=27')
            .expect(res => {
              expect(res.body.length).to.equal(1);
              const departement = res.body[0];
              expect(departement).to.eql({ nom: 'Eure', code: '27', codeRegion: '28' });
            })
            .end(done);
        });
      });

      describe('list communes', function() {
        it('should reply the list of communes', done => {
          request(server)
              .get('/departements/11/communes')
              .expect(res => {
                expect(res.body.length).to.equal(436);
              })
              .end(done);
        });
        it('should reply with 404', done => {
          request(server)
              .get('/departements/666/communes')
              .expect(404, done);
        });
        it('should return a FeatureCollection (geojson)', done => {
          request(server)
              .get('/departements/75/communes?format=geojson')
              .expect(res => {
                const communes = res.body;
                expect(communes).to.have.key('type');
                expect(communes.type).to.be('FeatureCollection');
              })
              .end(done);
        });
      });

    });
  });

  /* Régions */
  describe('Regions', function() {
    describe('with no input', function() {
      it('should reply with 200', done => {
        request(server)
            .get('/regions')
            .expect(200, done);
      });
      it('should reply all 18 regions', done => {
        request(server)
            .get('/regions')
            .expect(res => {
              expect(res.body.length).to.equal(18);
            })
            .end(done);
      });
    });

    describe('with code', function() {
      it('should work for 28', function() {
        request(server)
            .get('/regions/?code=28')
            .expect(200);
      });
      it('should reply a departement', done => {
        request(server)
          .get('/regions/?code=28')
          .expect(res => {
            expect(res.body.length).to.equal(1);
            const departement = res.body[0];
            expect(departement).to.eql({ nom: 'Normandie', code: '28' });
          })
          .end(done);
      });
    });

    describe('with name', function() {
      it('should work for Normandie', done => {
        request(server)
            .get('/regions/?nom=normandie')
            .expect(200, done);
      });
    });

    describe('list departements', function() {
      it('should reply the list of departements', done => {
        request(server)
            .get('/departements/84/departements')
            .expect(res => {
              expect(res.body.length).to.equal(7);
            })
            .end(done);
      });
      it('should reply with 404', done => {
        request(server)
            .get('/departements/666/departements')
            .expect(404, done);
      });
      it('should return a FeatureCollection (geojson)', done => {
        request(server)
            .get('/departements/84/departements?format=geojson')
            .expect(res => {
              const departements = res.body;
              expect(departements).to.have.key('type');
              expect(departements.type).to.be('FeatureCollection');
            })
            .end(done);
      });
    });

  });
});
<|endoftext|>


<commit_before>/*global describe, before, after, it */
var combo   = require('../'),
    server  = require('../lib/server'),

    assert  = require('assert'),
    express = require('express'),
    request = require('request'),

    PORT     = 8942,
    BASE_URL = 'http://localhost:' + PORT;

process.env['NODE_ENV'] = 'test';

describe('combohandler', function () {
    var app, httpServer;

    before(function () {
        app = server({
            roots: {
                '/css': __dirname + '/fixtures/root/css',
                '/js' : __dirname + '/fixtures/root/js'
            }
        });

        httpServer = app.listen(PORT);
    });

    after(function () {
        httpServer.close();
    });

    it('should combine JavaScript', function (done) {
        request(BASE_URL + '/js?a.js&b.js', function (err, res, body) {
            assert.ifError(err);
            res.should.have.status(200);
            res.should.have.header('content-type', 'application/javascript;charset=utf-8');
            res.should.have.header('last-modified');
            body.should.equal('a();\n\nb();\n');
            done();
        });
    });

    it('should combine CSS', function (done) {
        request(BASE_URL + '/css?a.css&b.css', function (err, res, body) {
            assert.ifError(err);
            res.should.have.status(200);
            res.should.have.header('content-type', 'text/css;charset=utf-8');
            res.should.have.header('last-modified');
            body.should.equal('.a { color: green; }\n\n.b { color: green; }\n');
            done();
        });
    });

    it('should support symlinks pointing outside the root', function (done) {
        request(BASE_URL + '/js?a.js&b.js&outside.js', function (err, res, body) {
            assert.ifError(err);
            res.should.have.status(200);
            res.should.have.header('content-type', 'application/javascript;charset=utf-8');
            res.should.have.header('last-modified');
            body.should.equal('a();\n\nb();\n\noutside();\n');
            done();
        });
    });

    // -- Config Options -------------------------------------------------------
    describe('config: maxAge', function () {
        before(function () {
            app.get('/max-age-null', combo.combine({
                rootPath: __dirname + '/fixtures/root/js',
                maxAge  : null
            }), function (req, res) {
                res.send(res.body);
            });

            app.get('/max-age-0', combo.combine({
                rootPath: __dirname + '/fixtures/root/js',
                maxAge  : 0
            }), function (req, res) {
                res.send(res.body);
            });
        });

        it('should default to one year', function (done) {
            request(BASE_URL + '/js?a.js', function (err, res, body) {
                assert.ifError(err);
                res.should.have.status(200);
                res.should.have.header('cache-control', 'public,max-age=31536000');

                var expires = new Date(res.headers['expires']);
                ((expires - Date.now()) / 1000).should.be.within(31535990, 31536000);

                done();
            });
        });

        it('should not set Cache-Control and Expires headers when maxAge is null', function (done) {
            request(BASE_URL + '/max-age-null?a.js', function (err, res, body) {
                assert.ifError(err);
                res.should.have.status(200);
                res.headers.should.not.have.property('cache-control');
                res.headers.should.not.have.property('expires');
                done();
            });
        });

        it('should support a maxAge of 0', function (done) {
            request(BASE_URL + '/max-age-0?a.js', function (err, res, body) {
                assert.ifError(err);
                res.should.have.status(200);
                res.should.have.header('cache-control', 'public,max-age=0');

                var expires = new Date(res.headers['expires']);
                ((expires - Date.now()) / 1000).should.be.within(-5, 5);

                done();
            });
        });
    });

    // -- Errors ---------------------------------------------------------------
    describe('errors', function () {
        it('should return a 400 Bad Request error when no files are specified', function (done) {
            request(BASE_URL + '/js', function (err, res, body) {
                assert.ifError(err);
                res.should.have.status(400);
                body.should.equal('Bad request. No files requested.');
                done();
            });
        });

        it('should throw a 400 Bad Request error when a file is not found', function (done) {
            request(BASE_URL + '/js?bogus.js', function (err, res, body) {
                assert.ifError(err);
                res.should.have.status(400);
                res.should.have.header('content-type', 'text/plain; charset=utf-8');
                body.should.equal('Bad request. File not found: bogus.js');
                done();
            });
        });

        it('should throw a 400 Bad Request error when a white-listed MIME type is not found', function (done) {
            request(BASE_URL + '/js?foo.bar', function (err, res, body) {
                assert.ifError(err);
                res.should.have.status(400);
                body.should.equal('Bad request. Illegal MIME type present.');
                done();
            });
        });

        it('should throw a 400 Bad Request error when an unmapped MIME type is found with other valid types', function (done) {
            request(BASE_URL + '/js?a.js&foo.bar', function (err, res, body) {
                assert.ifError(err);
                res.should.have.status(400);
                body.should.equal('Bad request. Only one MIME type allowed per request.');
                done();
            });
        });

        it('should throw a 400 Bad Request error when more than one valid MIME type is found', function (done) {
            request(BASE_URL + '/js?a.js&b.css', function (err, res, body) {
                assert.ifError(err);
                res.should.have.status(400);
                body.should.equal('Bad request. Only one MIME type allowed per request.');
                done();
            });
        });

        it('should throw a 400 Bad Request error when a querystring is truncated', function (done) {
            request(BASE_URL + '/js?a.js&b', function (err, res, body) {
                assert.ifError(err);
                res.should.have.status(400);
                body.should.equal('Bad request. Truncated query parameters.');
                done();
            });
        });

        it('should throw a 400 Bad Request error when a querystring is dramatically truncated', function (done) {
            request(BASE_URL + '/js?a', function (err, res, body) {
                assert.ifError(err);
                res.should.have.status(400);
                body.should.equal('Bad request. Truncated query parameters.');
                done();
            });
        });

        describe('path traversal', function () {
            var paths = [
                '../../../../package.json',
                '..%2f..%2f..%2f..%2fpackage.json',
                '%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2fpackage.json',
                '%2e%2e/%2e%2e/%2e%2e/%2e%2e/package.json',
                '..\\..\\..\\..\\package.json',
                '..%5c..%5c..%5c..%5cpackage.json',
                '%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5cpackage.json',
                '%2e%2e\\%2e%2e\\%2e%2e\\%2e%2e\\package.json',
                '....//....//....//....//package.json',
                '....%2f%2f....%2f%2f....%2f%2f....%2f%2fpackage.json',
                '....\\\\....\\\\....\\\\....\\\\package.json',
                '....%5c%5c....%5c%5c....%5c%5c....%5c%5cpackage.json'
            ];

            paths.forEach(function (path) {
                it('should throw a 400 Bad Request error when path traversal is attempted: ' + path, function (done) {
                    request(BASE_URL + '/js?' + path, function (err, res, body) {
                        assert.ifError(err);
                        res.should.have.status(400);
                        res.should.have.header('content-type', 'text/plain; charset=utf-8');
                        body.should.match(/^Bad request. File not found: /);
                        done();
                    });
                });
            });
        });
    });

    // -- URL Rewrites ---------------------------------------------------------
    describe("url rewrites", function () {
        before(function () {
            app.get('/norewrite', combo.combine({
                rootPath: __dirname + '/fixtures/rewrite'
            }), function (req, res) {
                res.send(res.body);
            });

            app.get('/rewrite', combo.combine({
                rootPath: __dirname + '/fixtures/rewrite',
                basePath: "/rewritten"
            }), function (req, res) {
                res.send(res.body);
            });

            app.get('/rewrite-noslash', combo.combine({
                rootPath: __dirname + '/fixtures/rewrite',
                basePath: "/rewritten/"
            }), function (req, res) {
                res.send(res.body);
            });
        });

        it("should allow the basePath to end in a slash", function (done) {
            request(BASE_URL + "/rewrite-noslash?urls.css", function (err, res, body) {
                assert.ifError(err);
                body.should.equal([
                    "#no-quotes { background: url(/rewritten/no-quotes.png);}",
                    "#single-quotes { background: url(\'/rewritten/single-quotes.png\');}",
                    "#double-quotes { background: url(\"/rewritten/double-quotes.png\");}",
                    "#spaces { background: url(",
                    "  \"/rewritten/spaces.png\" );}",
                    "#data-url { background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==);}",
                    "#absolute-url { background: url(http://www.example.com/foo.gif?a=b&c=d#bebimbop);}",
                    "#protocol-relative-url { background: url(//www.example.com/foo.gif?a=b&c=d#bebimbop);}",
                    "#escaped-stuff { background:url(\"/rewritten/\\)\\\";\\'\\(.png\"); }"
                ].join("\n"));
                done();
            });
        });

        it("should not rewrite without a basePath", function (done) {
            request(BASE_URL + "/norewrite?urls.css", function (err, res, body) {
                assert.ifError(err);
                body.should.equal([
                    "#no-quotes { background: url(no-quotes.png);}",
                    "#single-quotes { background: url(\'single-quotes.png\');}",
                    "#double-quotes { background: url(\"double-quotes.png\");}",
                    "#spaces { background: url(",
                    "  \"spaces.png\" );}",
                    "#data-url { background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==);}",
                    "#absolute-url { background: url(http://www.example.com/foo.gif?a=b&c=d#bebimbop);}",
                    "#protocol-relative-url { background: url(//www.example.com/foo.gif?a=b&c=d#bebimbop);}",
                    "#escaped-stuff { background:url(\"\\)\\\";\\'\\(.png\"); }"
                ].join("\n"));
                done();
            });
        });

        it("should rewrite valid urls", function (done) {
            request(BASE_URL + "/rewrite?urls.css&deeper/more.css", function (err, res, body) {
                assert.ifError(err);
                body.should.equal([
                    "#no-quotes { background: url(/rewritten/no-quotes.png);}",
                    "#single-quotes { background: url(\'/rewritten/single-quotes.png\');}",
                    "#double-quotes { background: url(\"/rewritten/double-quotes.png\");}",
                    "#spaces { background: url(",
                    "  \"/rewritten/spaces.png\" );}",
                    "#data-url { background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==);}",
                    "#absolute-url { background: url(http://www.example.com/foo.gif?a=b&c=d#bebimbop);}",
                    "#protocol-relative-url { background: url(//www.example.com/foo.gif?a=b&c=d#bebimbop);}",
                    "#escaped-stuff { background:url(\"/rewritten/\\)\\\";\\'\\(.png\"); }",
                    "#depth { background: url(/rewritten/deeper/deeper.png);}",
                    "#up-one { background: url(/rewritten/shallower.png);}",
                    "#down-one { background: url(/rewritten/deeper/more/down-one.png);}"
                ].join("\n"));
                done();
            });
        });
    });
});
<commit_msg>Remove unused 'express' require in test.<commit_after>/*global describe, before, after, it */
var combo   = require('../'),
    server  = require('../lib/server'),

    assert  = require('assert'),
    request = require('request'),

    PORT     = 8942,
    BASE_URL = 'http://localhost:' + PORT;

process.env['NODE_ENV'] = 'test';

describe('combohandler', function () {
    var app, httpServer;

    before(function () {
        app = server({
            roots: {
                '/css': __dirname + '/fixtures/root/css',
                '/js' : __dirname + '/fixtures/root/js'
            }
        });

        httpServer = app.listen(PORT);
    });

    after(function () {
        httpServer.close();
    });

    it('should combine JavaScript', function (done) {
        request(BASE_URL + '/js?a.js&b.js', function (err, res, body) {
            assert.ifError(err);
            res.should.have.status(200);
            res.should.have.header('content-type', 'application/javascript;charset=utf-8');
            res.should.have.header('last-modified');
            body.should.equal('a();\n\nb();\n');
            done();
        });
    });

    it('should combine CSS', function (done) {
        request(BASE_URL + '/css?a.css&b.css', function (err, res, body) {
            assert.ifError(err);
            res.should.have.status(200);
            res.should.have.header('content-type', 'text/css;charset=utf-8');
            res.should.have.header('last-modified');
            body.should.equal('.a { color: green; }\n\n.b { color: green; }\n');
            done();
        });
    });

    it('should support symlinks pointing outside the root', function (done) {
        request(BASE_URL + '/js?a.js&b.js&outside.js', function (err, res, body) {
            assert.ifError(err);
            res.should.have.status(200);
            res.should.have.header('content-type', 'application/javascript;charset=utf-8');
            res.should.have.header('last-modified');
            body.should.equal('a();\n\nb();\n\noutside();\n');
            done();
        });
    });

    // -- Config Options -------------------------------------------------------
    describe('config: maxAge', function () {
        before(function () {
            app.get('/max-age-null', combo.combine({
                rootPath: __dirname + '/fixtures/root/js',
                maxAge  : null
            }), function (req, res) {
                res.send(res.body);
            });

            app.get('/max-age-0', combo.combine({
                rootPath: __dirname + '/fixtures/root/js',
                maxAge  : 0
            }), function (req, res) {
                res.send(res.body);
            });
        });

        it('should default to one year', function (done) {
            request(BASE_URL + '/js?a.js', function (err, res, body) {
                assert.ifError(err);
                res.should.have.status(200);
                res.should.have.header('cache-control', 'public,max-age=31536000');

                var expires = new Date(res.headers['expires']);
                ((expires - Date.now()) / 1000).should.be.within(31535990, 31536000);

                done();
            });
        });

        it('should not set Cache-Control and Expires headers when maxAge is null', function (done) {
            request(BASE_URL + '/max-age-null?a.js', function (err, res, body) {
                assert.ifError(err);
                res.should.have.status(200);
                res.headers.should.not.have.property('cache-control');
                res.headers.should.not.have.property('expires');
                done();
            });
        });

        it('should support a maxAge of 0', function (done) {
            request(BASE_URL + '/max-age-0?a.js', function (err, res, body) {
                assert.ifError(err);
                res.should.have.status(200);
                res.should.have.header('cache-control', 'public,max-age=0');

                var expires = new Date(res.headers['expires']);
                ((expires - Date.now()) / 1000).should.be.within(-5, 5);

                done();
            });
        });
    });

    // -- Errors ---------------------------------------------------------------
    describe('errors', function () {
        it('should return a 400 Bad Request error when no files are specified', function (done) {
            request(BASE_URL + '/js', function (err, res, body) {
                assert.ifError(err);
                res.should.have.status(400);
                body.should.equal('Bad request. No files requested.');
                done();
            });
        });

        it('should throw a 400 Bad Request error when a file is not found', function (done) {
            request(BASE_URL + '/js?bogus.js', function (err, res, body) {
                assert.ifError(err);
                res.should.have.status(400);
                res.should.have.header('content-type', 'text/plain; charset=utf-8');
                body.should.equal('Bad request. File not found: bogus.js');
                done();
            });
        });

        it('should throw a 400 Bad Request error when a white-listed MIME type is not found', function (done) {
            request(BASE_URL + '/js?foo.bar', function (err, res, body) {
                assert.ifError(err);
                res.should.have.status(400);
                body.should.equal('Bad request. Illegal MIME type present.');
                done();
            });
        });

        it('should throw a 400 Bad Request error when an unmapped MIME type is found with other valid types', function (done) {
            request(BASE_URL + '/js?a.js&foo.bar', function (err, res, body) {
                assert.ifError(err);
                res.should.have.status(400);
                body.should.equal('Bad request. Only one MIME type allowed per request.');
                done();
            });
        });

        it('should throw a 400 Bad Request error when more than one valid MIME type is found', function (done) {
            request(BASE_URL + '/js?a.js&b.css', function (err, res, body) {
                assert.ifError(err);
                res.should.have.status(400);
                body.should.equal('Bad request. Only one MIME type allowed per request.');
                done();
            });
        });

        it('should throw a 400 Bad Request error when a querystring is truncated', function (done) {
            request(BASE_URL + '/js?a.js&b', function (err, res, body) {
                assert.ifError(err);
                res.should.have.status(400);
                body.should.equal('Bad request. Truncated query parameters.');
                done();
            });
        });

        it('should throw a 400 Bad Request error when a querystring is dramatically truncated', function (done) {
            request(BASE_URL + '/js?a', function (err, res, body) {
                assert.ifError(err);
                res.should.have.status(400);
                body.should.equal('Bad request. Truncated query parameters.');
                done();
            });
        });

        describe('path traversal', function () {
            var paths = [
                '../../../../package.json',
                '..%2f..%2f..%2f..%2fpackage.json',
                '%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2fpackage.json',
                '%2e%2e/%2e%2e/%2e%2e/%2e%2e/package.json',
                '..\\..\\..\\..\\package.json',
                '..%5c..%5c..%5c..%5cpackage.json',
                '%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5cpackage.json',
                '%2e%2e\\%2e%2e\\%2e%2e\\%2e%2e\\package.json',
                '....//....//....//....//package.json',
                '....%2f%2f....%2f%2f....%2f%2f....%2f%2fpackage.json',
                '....\\\\....\\\\....\\\\....\\\\package.json',
                '....%5c%5c....%5c%5c....%5c%5c....%5c%5cpackage.json'
            ];

            paths.forEach(function (path) {
                it('should throw a 400 Bad Request error when path traversal is attempted: ' + path, function (done) {
                    request(BASE_URL + '/js?' + path, function (err, res, body) {
                        assert.ifError(err);
                        res.should.have.status(400);
                        res.should.have.header('content-type', 'text/plain; charset=utf-8');
                        body.should.match(/^Bad request. File not found: /);
                        done();
                    });
                });
            });
        });
    });

    // -- URL Rewrites ---------------------------------------------------------
    describe("url rewrites", function () {
        before(function () {
            app.get('/norewrite', combo.combine({
                rootPath: __dirname + '/fixtures/rewrite'
            }), function (req, res) {
                res.send(res.body);
            });

            app.get('/rewrite', combo.combine({
                rootPath: __dirname + '/fixtures/rewrite',
                basePath: "/rewritten"
            }), function (req, res) {
                res.send(res.body);
            });

            app.get('/rewrite-noslash', combo.combine({
                rootPath: __dirname + '/fixtures/rewrite',
                basePath: "/rewritten/"
            }), function (req, res) {
                res.send(res.body);
            });
        });

        it("should allow the basePath to end in a slash", function (done) {
            request(BASE_URL + "/rewrite-noslash?urls.css", function (err, res, body) {
                assert.ifError(err);
                body.should.equal([
                    "#no-quotes { background: url(/rewritten/no-quotes.png);}",
                    "#single-quotes { background: url(\'/rewritten/single-quotes.png\');}",
                    "#double-quotes { background: url(\"/rewritten/double-quotes.png\");}",
                    "#spaces { background: url(",
                    "  \"/rewritten/spaces.png\" );}",
                    "#data-url { background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==);}",
                    "#absolute-url { background: url(http://www.example.com/foo.gif?a=b&c=d#bebimbop);}",
                    "#protocol-relative-url { background: url(//www.example.com/foo.gif?a=b&c=d#bebimbop);}",
                    "#escaped-stuff { background:url(\"/rewritten/\\)\\\";\\'\\(.png\"); }"
                ].join("\n"));
                done();
            });
        });

        it("should not rewrite without a basePath", function (done) {
            request(BASE_URL + "/norewrite?urls.css", function (err, res, body) {
                assert.ifError(err);
                body.should.equal([
                    "#no-quotes { background: url(no-quotes.png);}",
                    "#single-quotes { background: url(\'single-quotes.png\');}",
                    "#double-quotes { background: url(\"double-quotes.png\");}",
                    "#spaces { background: url(",
                    "  \"spaces.png\" );}",
                    "#data-url { background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==);}",
                    "#absolute-url { background: url(http://www.example.com/foo.gif?a=b&c=d#bebimbop);}",
                    "#protocol-relative-url { background: url(//www.example.com/foo.gif?a=b&c=d#bebimbop);}",
                    "#escaped-stuff { background:url(\"\\)\\\";\\'\\(.png\"); }"
                ].join("\n"));
                done();
            });
        });

        it("should rewrite valid urls", function (done) {
            request(BASE_URL + "/rewrite?urls.css&deeper/more.css", function (err, res, body) {
                assert.ifError(err);
                body.should.equal([
                    "#no-quotes { background: url(/rewritten/no-quotes.png);}",
                    "#single-quotes { background: url(\'/rewritten/single-quotes.png\');}",
                    "#double-quotes { background: url(\"/rewritten/double-quotes.png\");}",
                    "#spaces { background: url(",
                    "  \"/rewritten/spaces.png\" );}",
                    "#data-url { background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==);}",
                    "#absolute-url { background: url(http://www.example.com/foo.gif?a=b&c=d#bebimbop);}",
                    "#protocol-relative-url { background: url(//www.example.com/foo.gif?a=b&c=d#bebimbop);}",
                    "#escaped-stuff { background:url(\"/rewritten/\\)\\\";\\'\\(.png\"); }",
                    "#depth { background: url(/rewritten/deeper/deeper.png);}",
                    "#up-one { background: url(/rewritten/shallower.png);}",
                    "#down-one { background: url(/rewritten/deeper/more/down-one.png);}"
                ].join("\n"));
                done();
            });
        });
    });
});
<|endoftext|>


<commit_before>// @flow
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { StyleSheet, Text } from 'react-native';
import { Page, Icon } from 'DailyScrum/src/components';

class Summary extends Component {
  props: PropsType;

  render() {
    return (
      <Page style={styles.container}>
        <Icon name="warning" size={40} color="black" />
        <Text>Project summary is building itself</Text>
        <Text>Want to contribute?</Text>
        <Text>Head over to GitHub or msg me :)</Text>
      </Page>
    );
  }
}

type PropsType = {
  navigation: any,
};

const styles = StyleSheet.create({
  container: {
    justifyContent: 'center',
    alignItems: 'center',
  },
});

export default connect()(Summary);
<commit_msg>[Project/Summary] Show project name<commit_after>// @flow
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { StyleSheet, Text } from 'react-native';
import { Page, Icon } from 'DailyScrum/src/components';
import { currentProjectSelector } from '../../modules/projects/reducer';
import type { ProjectType } from '../../types/Project';

class Summary extends Component {
  props: PropsType;

  render() {
    const { project } = this.props;
    if (!project) return <Page isLoading />;

    return (
      <Page style={styles.container}>
        <Text>{project.name}</Text>
      </Page>
    );
  }
}

type PropsType = {
  navigation: any,
  project: ProjectType,
};

const styles = StyleSheet.create({
  container: {
    justifyContent: 'center',
    alignItems: 'center',
  },
});

const mapStateToProps = state => ({
  project: currentProjectSelector(state),
});

export default connect(mapStateToProps)(Summary);
<|endoftext|>


<commit_before>// Write your Javascript code.<commit_msg>Commit result of build - minified site JS.<commit_after><|endoftext|>


<commit_before>import React from 'react';

import { formatNumber, formatMilliseconds, formatPercentage } from 'common/format';
import Analyzer from 'Parser/Core/Analyzer';
import Combatants from 'Parser/Core/Modules/Combatants';
import SPELLS from 'common/SPELLS';

const debug = true;

class DeathTracker extends Analyzer {
  static dependencies = {
    combatants: Combatants,
  };

  lastDeathTimestamp = 0;
  lastResurrectionTimestamp = 0;
  timeDead = 0;
  castCount = 0;
  isAlive = true;

  on_toPlayer_death(event) {
    this.lastDeathTimestamp = this.owner.currentTimestamp;
    debug && console.log("Player Died @ " + formatMilliseconds(event.timestamp - this.owner.fight.start_time));
    this.isAlive = false;
  }

  on_toPlayer_resurrect(event) {
    this.lastResurrectionTimestamp = this.owner.currentTimestamp;
    this.timeDead += this.lastResurrectionTimestamp - this.lastDeathTimestamp;
    debug && console.log("Player was Resurrected @ " + formatMilliseconds(event.timestamp - this.owner.fight.start_time));
    this.isAlive = true;
  }

  on_byPlayer_cast(event) {
    this.castCount += 1;

    if (event.ability.guid === SPELLS.REINCARNATION.id)
    {
      this.lastResurrectionTimestamp = this.owner.currentTimestamp;
      this.timeDead += this.lastResurrectionTimestamp - this.lastDeathTimestamp;
      debug && console.log("Player was Resurrected @ " + formatMilliseconds(event.timestamp - this.owner.fight.start_time));
      this.isAlive = true;
    }

  }

  get totalTimeDead() {
    return this.timeDead + (this.isAlive ? 0 : this.owner.currentTimestamp - this.lastDeathTimestamp);
  }

  get timeDeadSeconds() {
    return (this.totalTimeDead / 1000);
  }

  get timeDeadPercent() {
    return this.totalTimeDead / this.owner.fightDuration;
  }

  get deathSuggestionThresholds() {
    return {
      actual: this.timeDeadPercent,
      isGreaterThan: {
        major: 0.00,
      },
      style: 'percentage',
    };
  }

  suggestions(when) {
    const boss = this.owner.boss;
    if (!boss || !boss.fight.disableDeathSuggestion) {
      when(this.totalTimeDead).isGreaterThan(0)
        .addSuggestion((suggest, actual, recommended) => {
          return suggest(You died during this fight and were dead for {formatNumber(this.timeDeadSeconds)} seconds ({formatPercentage(this.timeDeadPercent)}% of the fight). Make sure you are paying attention to mechanics and dodging avoidable damage. Additionally, make sure you are using your defensive abilities to avoid damage and Health Potions, Healthstones, or self healing abilities to heal yourself when you are very low.)
            .icon('ability_fiegndead')
            .actual(`${formatNumber(this.timeDeadSeconds)} seconds dead`)
            .recommended(`${formatNumber(recommended)} is recommended`)
            .major(this.deathSuggestionThresholds.isGreaterThan.major);
        });
      }
      when(this.castCount).isLessThan(1)
        .addSuggestion((suggest, actual, recommended) => {
          return suggest(You did not cast a single spell this fight. You were either dead for the entire fight, or were AFK.)
            .icon('ability_fiegndead')
            .major(this.deathSuggestionThresholds.isGreaterThan.major);
      });
    }
  }

export default DeathTracker;
<commit_msg>Update DeathTracker.js<commit_after>import React from 'react';

import SPELLS from 'common/SPELLS';
import { formatNumber, formatMilliseconds, formatPercentage } from 'common/format';
import Analyzer from 'Parser/Core/Analyzer';
import Combatants from 'Parser/Core/Modules/Combatants';

const debug = true;

class DeathTracker extends Analyzer {
  static dependencies = {
    combatants: Combatants,
  };

  lastDeathTimestamp = 0;
  lastResurrectionTimestamp = 0;
  timeDead = 0;
  castCount = 0;
  isAlive = true;

  on_toPlayer_death(event) {
    this.lastDeathTimestamp = this.owner.currentTimestamp;
    debug && console.log("Player Died @ " + formatMilliseconds(event.timestamp - this.owner.fight.start_time));
    this.isAlive = false;
  }

  on_toPlayer_resurrect(event) {
    this.lastResurrectionTimestamp = this.owner.currentTimestamp;
    this.timeDead += this.lastResurrectionTimestamp - this.lastDeathTimestamp;
    debug && console.log("Player was Resurrected @ " + formatMilliseconds(event.timestamp - this.owner.fight.start_time));
    this.isAlive = true;
  }

  on_byPlayer_cast(event) {
    this.castCount += 1;

    if (event.ability.guid === SPELLS.REINCARNATION.id) {
      this.lastResurrectionTimestamp = this.owner.currentTimestamp;
      this.timeDead += this.lastResurrectionTimestamp - this.lastDeathTimestamp;
      debug && console.log("Player was Resurrected @ " + formatMilliseconds(event.timestamp - this.owner.fight.start_time));
      this.isAlive = true;
    }
  }

  get totalTimeDead() {
    return this.timeDead + (this.isAlive ? 0 : this.owner.currentTimestamp - this.lastDeathTimestamp);
  }

  get timeDeadSeconds() {
    return (this.totalTimeDead / 1000);
  }

  get timeDeadPercent() {
    return this.totalTimeDead / this.owner.fightDuration;
  }

  get deathSuggestionThresholds() {
    return {
      actual: this.timeDeadPercent,
      isGreaterThan: {
        major: 0.00,
      },
      style: 'percentage',
    };
  }

  suggestions(when) {
    const boss = this.owner.boss;
    if (!boss || !boss.fight.disableDeathSuggestion) {
      when(this.totalTimeDead).isGreaterThan(0)
        .addSuggestion((suggest, actual, recommended) => {
          return suggest(You died during this fight and were dead for {formatNumber(this.timeDeadSeconds)} seconds ({formatPercentage(this.timeDeadPercent)}% of the fight). Make sure you are paying attention to mechanics and dodging avoidable damage. Additionally, make sure you are using your defensive abilities to avoid damage and Health Potions, Healthstones, or self healing abilities to heal yourself when you are very low.)
            .icon('ability_fiegndead')
            .actual(`${formatNumber(this.timeDeadSeconds)} seconds dead`)
            .recommended(`${formatNumber(recommended)} is recommended`)
            .major(this.deathSuggestionThresholds.isGreaterThan.major);
        });
      }
      when(this.castCount).isLessThan(1)
        .addSuggestion((suggest, actual, recommended) => {
          return suggest(You did not cast a single spell this fight. You were either dead for the entire fight, or were AFK.)
            .icon('ability_fiegndead')
            .major(this.deathSuggestionThresholds.isGreaterThan.major);
      });
    }
  }

export default DeathTracker;
<|endoftext|>


<commit_before>/**
 * Grafana-Zabbix
 * Zabbix plugin for Grafana.
 * http://github.com/alexanderzobnin/grafana-zabbix
 *
 * Trigger panel.
 * This feature sponsored by CORE IT
 * http://www.coreit.fr
 *
 * Copyright 2015 Alexander Zobnin alexanderzobnin@gmail.com
 * Licensed under the Apache License, Version 2.0
 */

import _ from 'lodash';
import moment from 'moment';
import {MetricsPanelCtrl} from 'app/plugins/sdk';
import {triggerPanelEditor} from './editor';
import './css/panel_triggers.css!';

var defaultSeverity = [
  { priority: 0, severity: 'Not classified',  color: '#B7DBAB', show: true },
  { priority: 1, severity: 'Information',     color: '#82B5D8', show: true },
  { priority: 2, severity: 'Warning',         color: '#E5AC0E', show: true },
  { priority: 3, severity: 'Average',         color: '#C15C17', show: true },
  { priority: 4, severity: 'High',            color: '#BF1B00', show: true },
  { priority: 5, severity: 'Disaster',        color: '#890F02', show: true }
];

var panelDefaults = {
  datasource: null,
  triggers: {
    group: {filter: ""},
    host: {filter: ""},
    application: {filter: ""},
    trigger: {filter: ""}
  },
  hostField: true,
  statusField: false,
  severityField: false,
  lastChangeField: true,
  ageField: true,
  infoField: true,
  limit: 10,
  showTriggers: 'all triggers',
  sortTriggersBy: { text: 'last change', value: 'lastchange' },
  showEvents: { text: 'Problem events', value: '1' },
  triggerSeverity: defaultSeverity,
  okEventColor: '#890F02',
};

var triggerStatusMap = {
  '0': 'OK',
  '1': 'Problem'
};

var defaultTimeFormat = "DD MMM YYYY HH:mm:ss";

class TriggerPanelCtrl extends MetricsPanelCtrl {

  /** @ngInject */
  constructor($scope, $injector, $q, $element, datasourceSrv, templateSrv) {
    super($scope, $injector);
    this.datasourceSrv = datasourceSrv;
    this.templateSrv = templateSrv;
    this.triggerStatusMap = triggerStatusMap;
    this.defaultTimeFormat = defaultTimeFormat;

    // Load panel defaults
    _.defaults(this.panel, panelDefaults);

    this.triggerList = [];
    this.refreshData();
  }

  // Add panel editor
  initEditMode() {
    //super.initEditMode();
    this.editorTabs = [];
    this.addEditorTab('General', 'public/app/partials/panelgeneral.html');
    this.icon = "fa fa-lightbulb-o";
    this.addEditorTab('Options', triggerPanelEditor, 2);
    this.editModeInitiated = true;
  }

  refreshData() {
    var self = this;

    // Load datasource
    return this.datasourceSrv.get(this.panel.datasource).then(datasource => {
      var zabbix = datasource.zabbixAPI;
      var queryProcessor = datasource.queryProcessor;
      var showEvents = self.panel.showEvents.value;
      var triggerFilter = self.panel.triggers;
      var groupFilter = self.templateSrv.replace(triggerFilter.group.filter);
      var hostFilter = self.templateSrv.replace(triggerFilter.host.filter);
      var appFilter = self.templateSrv.replace(triggerFilter.application.filter);
      var buildQuery = queryProcessor.buildTriggerQuery(groupFilter, hostFilter, appFilter);
      return buildQuery.then(query => {
        return zabbix.getTriggers(query.groupids,
                                  query.hostids,
                                  query.applicationids,
                                  showEvents)
          .then(triggers => {
            return _.map(triggers, trigger => {
              var triggerObj = trigger;

              // Format last change and age
              trigger.lastchangeUnix = Number(trigger.lastchange);
              var timestamp = moment.unix(trigger.lastchangeUnix);
              if (self.panel.customLastChangeFormat) {
                // User defined format
                triggerObj.lastchange = timestamp.format(self.panel.lastChangeFormat);
              } else {
                triggerObj.lastchange = timestamp.format(self.defaultTimeFormat);
              }
              triggerObj.age = timestamp.fromNow(true);

              // Set color
              if (trigger.value === '1') {
                triggerObj.color = self.panel.triggerSeverity[trigger.priority].color;
              } else {
                triggerObj.color = self.panel.okEventColor;
              }

              triggerObj.severity = self.panel.triggerSeverity[trigger.priority].severity;
              return triggerObj;
            });
          })
          .then(triggerList => {

            // Request acknowledges for trigger
            var eventids = _.map(triggerList, trigger => {
              return trigger.lastEvent.eventid;
            });

            return zabbix.getAcknowledges(eventids)
              .then(events => {

                // Map events to triggers
                _.each(triggerList, trigger => {
                  var event = _.find(events, event => {
                    return event.eventid === trigger.lastEvent.eventid;
                  });

                  if (event) {
                    trigger.acknowledges = _.map(event.acknowledges, ack => {
                      var time = new Date(+ack.clock * 1000);
                      ack.time = time.toLocaleString();
                      ack.user = ack.alias + ' (' + ack.name + ' ' + ack.surname + ')';
                      return ack;
                    });
                  }
                });

                // Filter triggers by description
                var triggerFilter = self.panel.triggers.trigger.filter;
                if (triggerFilter) {
                  triggerList = filterTriggers(triggerList, triggerFilter);
                }

                // Filter acknowledged triggers
                if (self.panel.showTriggers === 'unacknowledged') {
                  triggerList = _.filter(triggerList, trigger => {
                    return !trigger.acknowledges;
                  });
                } else if (self.panel.showTriggers === 'acknowledged') {
                  triggerList = _.filter(triggerList, 'acknowledges');
                } else {
                  triggerList = triggerList;
                }

                // Filter triggers by severity
                triggerList = _.filter(triggerList, trigger => {
                  return self.panel.triggerSeverity[trigger.priority].show;
                });

                // Sort triggers
                if (self.panel.sortTriggersBy.value === 'priority') {
                  triggerList = _.sortBy(triggerList, 'priority').reverse();
                } else {
                  triggerList = _.sortBy(triggerList, 'lastchangeUnix').reverse();
                }

                // Limit triggers number
                self.triggerList  = _.first(triggerList, self.panel.limit);

                self.renderingCompleted();
              });
          });
      });
    });
  }
}

TriggerPanelCtrl.templateUrl = 'module.html';

function filterTriggers(triggers, triggerFilter) {
  if (isRegex(triggerFilter)) {
    return _.filter(triggers, function(trigger) {
      return buildRegex(triggerFilter).test(trigger.description);
    });
  } else {
    return _.filter(triggers, function(trigger) {
      return trigger.description === triggerFilter;
    });
  }
}

function isRegex(str) {
  // Pattern for testing regex
  var regexPattern = /^\/(.*)\/([gmi]*)$/m;
  return regexPattern.test(str);
}

function buildRegex(str) {
  var regexPattern = /^\/(.*)\/([gmi]*)$/m;
  var matches = str.match(regexPattern);
  var pattern = matches[1];
  var flags = matches[2] !== "" ? matches[2] : undefined;
  return new RegExp(pattern, flags);
}

export {
  TriggerPanelCtrl,
  TriggerPanelCtrl as PanelCtrl
};
<commit_msg>Added initEditMode() explanations.<commit_after>/**
 * Grafana-Zabbix
 * Zabbix plugin for Grafana.
 * http://github.com/alexanderzobnin/grafana-zabbix
 *
 * Trigger panel.
 * This feature sponsored by CORE IT
 * http://www.coreit.fr
 *
 * Copyright 2015 Alexander Zobnin alexanderzobnin@gmail.com
 * Licensed under the Apache License, Version 2.0
 */

import _ from 'lodash';
import moment from 'moment';
import {MetricsPanelCtrl} from 'app/plugins/sdk';
import {triggerPanelEditor} from './editor';
import './css/panel_triggers.css!';

var defaultSeverity = [
  { priority: 0, severity: 'Not classified',  color: '#B7DBAB', show: true },
  { priority: 1, severity: 'Information',     color: '#82B5D8', show: true },
  { priority: 2, severity: 'Warning',         color: '#E5AC0E', show: true },
  { priority: 3, severity: 'Average',         color: '#C15C17', show: true },
  { priority: 4, severity: 'High',            color: '#BF1B00', show: true },
  { priority: 5, severity: 'Disaster',        color: '#890F02', show: true }
];

var panelDefaults = {
  datasource: null,
  triggers: {
    group: {filter: ""},
    host: {filter: ""},
    application: {filter: ""},
    trigger: {filter: ""}
  },
  hostField: true,
  statusField: false,
  severityField: false,
  lastChangeField: true,
  ageField: true,
  infoField: true,
  limit: 10,
  showTriggers: 'all triggers',
  sortTriggersBy: { text: 'last change', value: 'lastchange' },
  showEvents: { text: 'Problem events', value: '1' },
  triggerSeverity: defaultSeverity,
  okEventColor: '#890F02',
};

var triggerStatusMap = {
  '0': 'OK',
  '1': 'Problem'
};

var defaultTimeFormat = "DD MMM YYYY HH:mm:ss";

class TriggerPanelCtrl extends MetricsPanelCtrl {

  /** @ngInject */
  constructor($scope, $injector, $q, $element, datasourceSrv, templateSrv) {
    super($scope, $injector);
    this.datasourceSrv = datasourceSrv;
    this.templateSrv = templateSrv;
    this.triggerStatusMap = triggerStatusMap;
    this.defaultTimeFormat = defaultTimeFormat;

    // Load panel defaults
    _.defaults(this.panel, panelDefaults);

    this.triggerList = [];
    this.refreshData();
  }

  // Add panel editor
  initEditMode() {
    // Use initialize method from PanelCtrl instead MetricsPanelCtrl.
    // We don't need metric editor from Metrics Panel.
    this.editorTabs = [];
    this.addEditorTab('General', 'public/app/partials/panelgeneral.html');

    this.icon = "fa fa-lightbulb-o";
    this.addEditorTab('Options', triggerPanelEditor, 2);
    this.editModeInitiated = true;
  }

  refreshData() {
    var self = this;

    // Load datasource
    return this.datasourceSrv.get(this.panel.datasource).then(datasource => {
      var zabbix = datasource.zabbixAPI;
      var queryProcessor = datasource.queryProcessor;
      var showEvents = self.panel.showEvents.value;
      var triggerFilter = self.panel.triggers;
      var groupFilter = self.templateSrv.replace(triggerFilter.group.filter);
      var hostFilter = self.templateSrv.replace(triggerFilter.host.filter);
      var appFilter = self.templateSrv.replace(triggerFilter.application.filter);
      var buildQuery = queryProcessor.buildTriggerQuery(groupFilter, hostFilter, appFilter);
      return buildQuery.then(query => {
        return zabbix.getTriggers(query.groupids,
                                  query.hostids,
                                  query.applicationids,
                                  showEvents)
          .then(triggers => {
            return _.map(triggers, trigger => {
              var triggerObj = trigger;

              // Format last change and age
              trigger.lastchangeUnix = Number(trigger.lastchange);
              var timestamp = moment.unix(trigger.lastchangeUnix);
              if (self.panel.customLastChangeFormat) {
                // User defined format
                triggerObj.lastchange = timestamp.format(self.panel.lastChangeFormat);
              } else {
                triggerObj.lastchange = timestamp.format(self.defaultTimeFormat);
              }
              triggerObj.age = timestamp.fromNow(true);

              // Set color
              if (trigger.value === '1') {
                triggerObj.color = self.panel.triggerSeverity[trigger.priority].color;
              } else {
                triggerObj.color = self.panel.okEventColor;
              }

              triggerObj.severity = self.panel.triggerSeverity[trigger.priority].severity;
              return triggerObj;
            });
          })
          .then(triggerList => {

            // Request acknowledges for trigger
            var eventids = _.map(triggerList, trigger => {
              return trigger.lastEvent.eventid;
            });

            return zabbix.getAcknowledges(eventids)
              .then(events => {

                // Map events to triggers
                _.each(triggerList, trigger => {
                  var event = _.find(events, event => {
                    return event.eventid === trigger.lastEvent.eventid;
                  });

                  if (event) {
                    trigger.acknowledges = _.map(event.acknowledges, ack => {
                      var time = new Date(+ack.clock * 1000);
                      ack.time = time.toLocaleString();
                      ack.user = ack.alias + ' (' + ack.name + ' ' + ack.surname + ')';
                      return ack;
                    });
                  }
                });

                // Filter triggers by description
                var triggerFilter = self.panel.triggers.trigger.filter;
                if (triggerFilter) {
                  triggerList = filterTriggers(triggerList, triggerFilter);
                }

                // Filter acknowledged triggers
                if (self.panel.showTriggers === 'unacknowledged') {
                  triggerList = _.filter(triggerList, trigger => {
                    return !trigger.acknowledges;
                  });
                } else if (self.panel.showTriggers === 'acknowledged') {
                  triggerList = _.filter(triggerList, 'acknowledges');
                } else {
                  triggerList = triggerList;
                }

                // Filter triggers by severity
                triggerList = _.filter(triggerList, trigger => {
                  return self.panel.triggerSeverity[trigger.priority].show;
                });

                // Sort triggers
                if (self.panel.sortTriggersBy.value === 'priority') {
                  triggerList = _.sortBy(triggerList, 'priority').reverse();
                } else {
                  triggerList = _.sortBy(triggerList, 'lastchangeUnix').reverse();
                }

                // Limit triggers number
                self.triggerList  = _.first(triggerList, self.panel.limit);

                self.renderingCompleted();
              });
          });
      });
    });
  }
}

TriggerPanelCtrl.templateUrl = 'module.html';

function filterTriggers(triggers, triggerFilter) {
  if (isRegex(triggerFilter)) {
    return _.filter(triggers, function(trigger) {
      return buildRegex(triggerFilter).test(trigger.description);
    });
  } else {
    return _.filter(triggers, function(trigger) {
      return trigger.description === triggerFilter;
    });
  }
}

function isRegex(str) {
  // Pattern for testing regex
  var regexPattern = /^\/(.*)\/([gmi]*)$/m;
  return regexPattern.test(str);
}

function buildRegex(str) {
  var regexPattern = /^\/(.*)\/([gmi]*)$/m;
  var matches = str.match(regexPattern);
  var pattern = matches[1];
  var flags = matches[2] !== "" ? matches[2] : undefined;
  return new RegExp(pattern, flags);
}

export {
  TriggerPanelCtrl,
  TriggerPanelCtrl as PanelCtrl
};
<|endoftext|>