<commit_before>/* jshint -W097 */
/* jshint strict:false */
/* jslint node: true */
/* jshint expr: true */
var expect = require('chai').expect;
var fs        = require('fs');

describe('Test package.json and io-package.json', function() {
    it('Test package files', function (done) {
        console.log();

        var fileContentIOPackage = fs.readFileSync(__dirname + '/../io-package.json', 'utf8');
        var ioPackage = JSON.parse(fileContentIOPackage);

        var fileContentNPMPackage = fs.readFileSync(__dirname + '/../package.json', 'utf8');
        var npmPackage = JSON.parse(fileContentNPMPackage);

        expect(ioPackage).to.be.an('object');
        expect(npmPackage).to.be.an('object');

        expect(ioPackage.common.version, 'ERROR: Version number in io-package.json needs to exist').to.exist;
        expect(npmPackage.version, 'ERROR: Version number in package.json needs to exist').to.exist;

        expect(ioPackage.common.version, 'ERROR: Version numbers in package.json and io-package.json needs to match').to.be.equal(npmPackage.version);

        if (!ioPackage.common.news || !ioPackage.common.news[ioPackage.common.version]) {
            console.log('WARNING: No news entry for current version exists in io-package.json, no rollback in Admin possible!');
            console.log();
        }

        expect(npmPackage.author, 'ERROR: Author in package.json needs to exist').to.exist;
        expect(ioPackage.common.authors, 'ERROR: Authors in io-package.json needs to exist').to.exist;

        if (ioPackage.common.name.indexOf('template') !== 0) {
            if (Array.isArray(ioPackage.common.authors)) {
                expect(ioPackage.common.authors.length, 'ERROR: Author in io-package.json needs to be set').to.not.be.equal(0);
                if (ioPackage.common.authors.length === 1) {
                    expect(ioPackage.common.authors[0], 'ERROR: Author in io-package.json needs to be a real name').to.not.be.equal('my Name <my@email.com>');
                }
            }
            else {
                expect(ioPackage.common.authors, 'ERROR: Author in io-package.json needs to be a real name').to.not.be.equal('my Name <my@email.com>');
            }
        }
        else {
            console.log('WARNING: Testing for set authors field in io-package skipped because template adapter');
            console.log();
        }
        expect(fs.existsSync(__dirname + '/../README.md'), 'ERROR: README.md needs to exist! Please create one with description, detail information and changelog. English is mandatory.').to.be.true;
        if (!ioPackage.common.titleLang || typeof ioPackage.common.titleLang !== 'object') {
            console.log('WARNING: titleLang is not existing in io-package.json. Please add');
            console.log();
        }
        if (
            ioPackage.common.title.indexOf('iobroker') !== -1 ||
            ioPackage.common.title.indexOf('ioBroker') !== -1 ||
            ioPackage.common.title.indexOf('adapter') !== -1 ||
            ioPackage.common.title.indexOf('Adapter') !== -1
        ) {
            console.log('WARNING: title contains Adapter or ioBroker. It is clear anyway, that it is adapter for ioBroker.');
            console.log();
        }

        if (ioPackage.common.name.indexOf('vis-') !== 0) {
            if (!ioPackage.common.materialize || !fs.existsSync(__dirname + '/../admin/index_m.html') || !fs.existsSync(__dirname + '/../gulpfile.js')) {
                console.log('WARNING: Admin3 support is missing! Please add it');
                console.log();
            }
            if (ioPackage.common.materialize) {
                expect(fs.existsSync(__dirname + '/../admin/index_m.html'), 'Admin3 support is enabled in io-package.json, but index_m.html is missing!').to.be.true;
            }
        }

        var licenseFileExists = fs.existsSync(__dirname + '/../LICENSE');
        var fileContentReadme = fs.readFileSync(__dirname + '/../README.md', 'utf8');
        if (fileContentReadme.indexOf('## Changelog') === -1) {
            console.log('Warning: The README.md should have a section ## Changelog');
            console.log();
        }
        expect((licenseFileExists || fileContentReadme.indexOf('## License') !== -1), 'A LICENSE must exist as LICENSE file or as part of the README.md').to.be.true;
        if (!licenseFileExists) {
            console.log('Warning: The License should also exist as LICENSE file');
            console.log();
        }
        if (fileContentReadme.indexOf('## License') === -1) {
            console.log('Warning: The README.md should also have a section ## License to be shown in Admin3');
            console.log();
        }
        done();
    });
});
<commit_msg>update basic package-file testing<commit_after>/* jshint -W097 */
/* jshint strict:false */
/* jslint node: true */
/* jshint expr: true */
'use strict';

const expect = require('chai').expect;
const fs     = require('fs');

describe('Test package.json and io-package.json', () => {
    it('Test package files', done => {
        console.log();

        const fileContentIOPackage = fs.readFileSync(__dirname + '/../io-package.json', 'utf8');
        const ioPackage = JSON.parse(fileContentIOPackage);

        const fileContentNPMPackage = fs.readFileSync(__dirname + '/../package.json', 'utf8');
        const npmPackage = JSON.parse(fileContentNPMPackage);

        expect(ioPackage).to.be.an('object');
        expect(npmPackage).to.be.an('object');

        expect(ioPackage.common.version, 'ERROR: Version number in io-package.json needs to exist').to.exist;
        expect(npmPackage.version, 'ERROR: Version number in package.json needs to exist').to.exist;

        expect(ioPackage.common.version, 'ERROR: Version numbers in package.json and io-package.json needs to match').to.be.equal(npmPackage.version);

        if (!ioPackage.common.news || !ioPackage.common.news[ioPackage.common.version]) {
            console.log('WARNING: No news entry for current version exists in io-package.json, no rollback in Admin possible!');
            console.log();
        }

        expect(npmPackage.author, 'ERROR: Author in package.json needs to exist').to.exist;
        expect(ioPackage.common.authors, 'ERROR: Authors in io-package.json needs to exist').to.exist;

        expect(ioPackage.common.license, 'ERROR: License missing in io-package in common.license').to.exist;

        if (ioPackage.common.name.indexOf('template') !== 0) {
            if (Array.isArray(ioPackage.common.authors)) {
                expect(ioPackage.common.authors.length, 'ERROR: Author in io-package.json needs to be set').to.not.be.equal(0);
                if (ioPackage.common.authors.length === 1) {
                    expect(ioPackage.common.authors[0], 'ERROR: Author in io-package.json needs to be a real name').to.not.be.equal('my Name <my@email.com>');
                }
            }
            else {
                expect(ioPackage.common.authors, 'ERROR: Author in io-package.json needs to be a real name').to.not.be.equal('my Name <my@email.com>');
            }
        }
        else {
            console.log('WARNING: Testing for set authors field in io-package skipped because template adapter');
            console.log();
        }
        expect(fs.existsSync(__dirname + '/../README.md'), 'ERROR: README.md needs to exist! Please create one with description, detail information and changelog. English is mandatory.').to.be.true;
        if (!ioPackage.common.titleLang || typeof ioPackage.common.titleLang !== 'object') {
            console.log('WARNING: titleLang is not existing in io-package.json. Please add');
            console.log();
        }
        if (
            ioPackage.common.title.indexOf('iobroker') !== -1 ||
            ioPackage.common.title.indexOf('ioBroker') !== -1 ||
            ioPackage.common.title.indexOf('adapter') !== -1 ||
            ioPackage.common.title.indexOf('Adapter') !== -1
        ) {
            console.log('WARNING: title contains Adapter or ioBroker. It is clear anyway, that it is adapter for ioBroker.');
            console.log();
        }

        if (!ioPackage.common.controller && !ioPackage.common.onlyWWW && !ioPackage.common.noConfig) {
            if (!ioPackage.common.materialize || !fs.existsSync(__dirname + '/../admin/index_m.html') || !fs.existsSync(__dirname + '/../gulpfile.js')) {
                console.log('WARNING: Admin3 support is missing! Please add it');
                console.log();
            }
            if (ioPackage.common.materialize) {
                expect(fs.existsSync(__dirname + '/../admin/index_m.html'), 'Admin3 support is enabled in io-package.json, but index_m.html is missing!').to.be.true;
            }
        }

        const licenseFileExists = fs.existsSync(__dirname + '/../LICENSE');
        const fileContentReadme = fs.readFileSync(__dirname + '/../README.md', 'utf8');
        if (fileContentReadme.indexOf('## Changelog') === -1) {
            console.log('Warning: The README.md should have a section ## Changelog');
            console.log();
        }
        expect((licenseFileExists || fileContentReadme.indexOf('## License') !== -1), 'A LICENSE must exist as LICENSE file or as part of the README.md').to.be.true;
        if (!licenseFileExists) {
            console.log('Warning: The License should also exist as LICENSE file');
            console.log();
        }
        if (fileContentReadme.indexOf('## License') === -1) {
            console.log('Warning: The README.md should also have a section ## License to be shown in Admin3');
            console.log();
        }
        done();
    });
});
<|endoftext|>


<commit_before>//Import/require modules needed to crawl the schoolmaster schedules.
var http = require('http');
var cheerio = require('cheerio');
var iconv = require('iconv-lite');

//Define schooltypes that need to be ripped.
var scheduletypes = [
  'Klasrooster',
  'Docentrooster',
  'Leerlingrooster',
  'Lokaalrooster'
];
var schoolid;

//Function for getting pages with http requests.
function get(callback) {
  var index = [];
  //Go past all of the scheduletypes and download their pages.
  for (scheduletype of scheduletypes) {
    (function (scheduletype) {
      var link = 'http://roosters5.gepro-osi.nl/roosters/rooster.php?school=' + schoolid + '&type=' + scheduletype;

      scheduletype = scheduletype.replace(/rooster/g, '').toLowerCase();

      http.get(link, function (res) {
        var _download = '';

        res.on('data', function (data) {
          _download += data;
        });

        res.on('end', function () {
          var list = extract(_download);

          if (scheduletype == 'leerling') {
            for(studentcategory of list) {
              http.get('http://' + res.req.socket._host + res.req.path + '&afdeling=' + studentcategory, function (res) {
                var _download = '';

                res.on('data', function (data) {
                  _download += iconv.decode(data, 'binary');
                });

                res.on('end', function () {
                  var list = cheerio('select', _download).children();

                  for (student in list) {
                    if (!isNaN(student)) {
                      var name = cheerio(list[student]).text().split(' - ')[1];
                      var id = cheerio(list[student]).val();

                      var database_entry = {
                        'id' : id,
                        'full_name' : name,
                        'first_name' : name.split(' ')[0],
                        'last_name' : name.split(' ').splice(1).join(' '),
                        'type' : scheduletype
                      }

                      index.push(database_entry);
                    }
                  }
                });
              });
            }
            callback(index);
          }
          else {
            for (entry of list) {
              var database_entry = {
                'name' : entry,
                'type' : scheduletype
              }
              index.push(database_entry);
            }
          }

        });
      });
    })(scheduletype);
  }
}

//Function for extracting the lists with useful information from the crawled pages.
//(e.g Student names/ids, Teacher codes, Chamber numbers)
function extract(page) {
	var array = cheerio('select', page).text().split('\n');
	return array.splice(1, array.length - 2);
}

//Function being called to access functionality from this module.
function crawl(sid) {
  schoolid = sid;
  var times = 0;
  get(function (data) {
    console.log(data);
  });
}

crawl(934);
<commit_msg>Added an end to the script, (to close the database);<commit_after>//Import/require modules needed to crawl the schoolmaster schedules.
var http = require('http');
var cheerio = require('cheerio');
var iconv = require('iconv-lite');
var mongodb = require('mongodb').MongoClient;

//Define schooltypes that need to be ripped.
var scheduletypes = [
  'Klasrooster',
  'Docentrooster',
  'Leerlingrooster',
  'Lokaalrooster'
];
var schoolid;

//Function for getting pages with http requests.
function get(database) {

  var collection = database.collection('index');
  collection.drop();

  //Go past all of the scheduletypes and download their pages.
  for (scheduletype of scheduletypes) {
    (function (scheduletype) {
      var link = 'http://roosters5.gepro-osi.nl/roosters/rooster.php?school=' + schoolid + '&type=' + scheduletype;

      scheduletype = scheduletype.replace(/rooster/g, '').toLowerCase();

      http.get(link, function (res) {
        var _download = '';

        res.on('data', function (data) {
          _download += data;
        });

        res.on('end', function () {
          var list = extract(_download);

          if (scheduletype == 'leerling') {
            for(studentcategory of list) {
              (function (studentcategory) {

                http.get('http://' + res.req.socket._host + res.req.path + '&afdeling=' + studentcategory, function (res) {
                  var _download = '';

                  res.on('data', function (data) {
                    _download += iconv.decode(data, 'binary');
                  });

                  res.on('end', function () {
                    var list_students = cheerio('select', _download).children();

                    for (student in list_students) {
                      if (!isNaN(student)) {
                        var name = cheerio(list_students[student]).text().split(' - ')[1];
                        var id = cheerio(list_students[student]).val();

                        var database_entry = {
                          'id' : id,
                          'username' : id + name.split(' ')[0].toLowerCase(),
                          'full_name' : name,
                          'first_name' : name.split(' ')[0],
                          'last_name' : name.split(' ').splice(1).join(' '),
                          'studentcategory' : studentcategory,
                          'type' : scheduletype
                        }

                        collection.insert(database_entry, showOutput);
                        if (studentcategory == list[list.length - 1] && student == list_students.length - 1) {
                          database.close();
                        }
                      }
                    }
                  });
                });
              })(studentcategory);
            }
          }
          else {
            for (entry of list) {
              var database_entry = {
                'name' : entry,
                'type' : scheduletype
              }
              collection.insert(database_entry, showOutput);
            }
          }

        });
      });
    })(scheduletype);
  }
}

//Function for extracting the lists with useful information from the crawled pages.
//(e.g Student names/ids, Teacher codes, Chamber numbers)
function extract(page) {
	var array = cheerio('select', page).text().split('\n');
	return array.splice(1, array.length - 2);
}

//Function being called to access functionality from this module.
function crawl(sid) {
  schoolid = sid;
  mongodb.connect('mongodb://wallpiece/roosterio', function (error, database) {
    if (error) console.warn(error);
    get(database);
  })
}

function showOutput(error, message) {
  if (process.argv[2] == '-v') {
    if (error) process.stdout.write(error.toString());
    process.stdout.write(message + '\n');
  }
}

crawl(934);
<|endoftext|>


<commit_before>function Spiral(graphType) {
  this.graphParams = {
    graphType: graphType || "points",
    numberOfPoints: null,
    period: null,
    margin: {
      top: 10,
      right: 10,
      bottom: 10,
      left: 10
    },
    svgHeight: 0,
    svgWidth: 0,
  },
  this.spacing = 1,
  this.lineWidth = 50,
  this.targetElement = '#chart',
  this.width = this.graphParams.svgWidth - this.graphParams.margin.left - this.graphParams.margin.right,
  this.height = this.graphParams.svgHeight - this.graphParams.margin.top - this.graphParams.margin.bottom,
  this.data = [],
  this.x = d3.scale.linear().range([0, 730]).domain([-750, 750]),
  this.y = d3.scale.linear().range([480, 0]).domain([-500, 500]),
  this.cartesian = function(radius, angle, size, startAngle, endAngle) {
    var size = size || 1;
    var xPos = this.x(radius * Math.cos(angle));
    var yPos = this.y(radius * Math.sin(angle));
    return [xPos, yPos, size, radius, angle, startAngle, endAngle];
  },
  this.render = function() {
    var spiralContext = this;

    var svg = d3.select(spiralContext.targetElement)
      .append("svg")
      .attr("width", spiralContext.graphParams.svgWidth)
      .attr("height", spiralContext.graphParams.svgHeight)

    if (spiralContext.graphParams.graphType === "points") {
      svg.append("g")
        .attr("transform", "translate(" + spiralContext.graphParams.margin.left + "," + spiralContext.graphParams.margin.top + ")");

      svg.selectAll("g").selectAll("dot")
        .data(spiralContext.data)
          .enter().append("circle")
            .attr("r", function(d) { return d[2]; })
            .attr("cx", function(d) { return d[0]; })
            .attr("cy", function(d) { return d[1]; });
    } else if (spiralContext.graphParams.graphType === "custom-path") {
      spiralContext.data.forEach(function(datum, t, dataSet){
        var start = startAngle(t, spiralContext.graphParams.period);
        var end = endAngle(t, spiralContext.graphParams.period);

        var startInnerRadius = radius(spiralContext.spacing, start) - spiralContext.lineWidth*0.5;
        var startOuterRadius = radius(spiralContext.spacing, start) + spiralContext.lineWidth*0.5;
        var endInnerRadius = radius(spiralContext.spacing, end) - spiralContext.lineWidth*0.5;
        var endOuterRadius = radius(spiralContext.spacing, end) + spiralContext.lineWidth*0.5;

        var ctrlInnerRad = 0.01; // Use to adjust arc inner radius
        var ctrlOuterRad = 0.01; // Use to adjust arc outer radius
        var innerControlPoint = spiralContext.cartesian(radius(spiralContext.spacing, theta(t, spiralContext.graphParams.period)) - spiralContext.lineWidth*0.5 + ctrlInnerRad, theta(t, spiralContext.graphParams.period));
        var outerControlPoint = spiralContext.cartesian(radius(spiralContext.spacing, theta(t, spiralContext.graphParams.period)) + spiralContext.lineWidth*0.5 + ctrlOuterRad, theta(t, spiralContext.graphParams.period));

        var startPoint = spiralContext.cartesian(startInnerRadius, start); // Bottom right of arc
        var point2 = spiralContext.cartesian(startOuterRadius, start); // Top right of arc
        var point3 = spiralContext.cartesian(endOuterRadius, end); // Top left of arc
        var point4 = spiralContext.cartesian(endInnerRadius, end); // Bottom left of arc
        var arcPath = "M" + startPoint[0] + " " + startPoint[1] + "L" + point2[0] + " " + point2[1];
        arcPath += "Q" + outerControlPoint[0] + " " + outerControlPoint[1] + " " + point3[0] + " " + point3[1];
        arcPath += "L" + point4[0] + " " + point4[1];
        arcPath += "Q" + innerControlPoint[0] + " " + innerControlPoint[1] + " " + startPoint[0] + " " + startPoint[1] + "Z";
        datum[1] = arcPath
      });

      svg.append("g")
        .attr("transform", "translate(" + spiralContext.graphParams.margin.left + "," + spiralContext.graphParams.margin.top + ")");
      svg.selectAll("g").selectAll("path")
        .data(spiralContext.data.slice(100))
        .enter().append("path")
          .style("fill", function(d) { return "black"; })
          .style("opacity", function(d) {return d[2]/9})
          .attr("d", function(d) { return d[1]});
    } else if (spiralContext.graphParams.graphType === "non-spiral") {
      // --------------------vvv Standard Line Graph vvv---------------------------
      var x2 = d3.scale.linear().range([0, 730]);
      var y2 = d3.scale.linear().range([480, 0]);
      x2.domain(d3.extent(spiralContext.data, function(d) { return d[0]; }));
      y2.domain(d3.extent(spiralContext.data, function(d) { return d[1]; }));

      var xAxis = d3.svg.axis().scale(x2)
        .orient("bottom").ticks(5);

      var yAxis = d3.svg.axis().scale(y2)
        .orient("left").ticks(5);

      var line = d3.svg.line()
        .x(function(d) { return x2(d[0]); })
        .y(function(d) { return y2(d[1]); });

      // Add the X Axis
      svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate("+spiralContext.graphParams.margin.left+"," + 480 + ")")
        .call(xAxis)
        .append("text")
          .attr("x", 710)
          .attr("y", -3)
          .attr("dy", "-.35em")
          .style("text-anchor", "middle")
          .text("time");

      // Add the Y Axis
      svg.append("g")
        .attr("class", "y axis")
        .attr("transform", "translate("+spiralContext.graphParams.margin.left+",0)")
        .call(yAxis)
        .append("text")
          .attr("transform", "rotate(-90)")
          .attr("y", 6)
          .attr("dy", ".71em")
          .style("text-anchor", "end")
          .text("Signal (a.u.)");

      svg.append("path")
        .datum(spiralContext.data)
        .attr("class", "line")
        .attr("d", line)
        .attr("fill", "none")
        .attr("stroke-width", "1")
        .attr("stroke", "steelblue")
        .attr("transform", "translate("+spiralContext.graphParams.margin.left+",0)")
    }
  },
  this.randomData = function() {
    this.data = [];
    for (var i=0; i<this.graphParams.numberOfPoints; i++){
      var angle = theta(i, this.graphParams.period);
      var rad = radius(this.spacing, angle);
      var size = 1 + Math.random()*1.5;
      if (i % 10 === 0) {
        size = 5.5 + Math.random()*3;
      }

      if (this.graphParams.graphType === 'non-spiral') {
        this.data.push([i, size*this.graphParams.period, 2])
      } else {
        this.data.push(this.cartesian(rad, angle, size, startAngle(i, this.graphParams.period), endAngle(i, this.graphParams.period)));
      }
    }
  },
  this.setParam = function(param, value) {
    var spiralContext = this;
    if (['svgHeight', 'svgWidth', 'numberOfPoints', 'period', 'margin.top', 'margin.right', 'margin.bottom', 'margin.left'].indexOf(param) > -1)  {
      spiralContext.graphParams[param] = value;
    } else {
      spiralContext[param] = value;
    }
    if (['svgHeight', 'svgWidth', 'margin.top', 'margin.right', 'margin.bottom', 'margin.left'].indexOf(param) > -1) {
      spiralContext.width = spiralContext.graphParams.svgWidth - spiralContext.graphParams.margin.left - spiralContext.graphParams.margin.right;
      spiralContext.height = spiralContext.graphParams.svgHeight - spiralContext.graphParams.margin.top - spiralContext.graphParams.margin.bottom;
      spiralContext.x = d3.scale.linear().range([0, spiralContext.width]).domain([-spiralContext.graphParams.svgWidth, spiralContext.graphParams.svgWidth]);
      spiralContext.y = d3.scale.linear().range([spiralContext.height, 0]).domain([-spiralContext.graphParams.svgHeight, spiralContext.graphParams.svgHeight]);
    }
  },
  this.redraw = function() {
    var spiralContext = this;
    var graphContainer = document.getElementById(spiralContext.targetElement.substr(1));
    while (graphContainer.firstChild) {
      graphContainer.removeChild(graphContainer.firstChild)
    }
    spiralContext.render();
  },
  this.autocorrelate = function() {}
}

// For time point #t, calculate the angle to the center of the arc
// period is the number of time points per revolution (2 PI)
function theta(t, period) {
  return 2 * Math.PI / (period) * t;
}

function startAngle(t, period) {
  return (theta(t-1, period) + theta(t, period))/2;
}

function endAngle(t, period) {
  return (theta(t+1, period) + theta(t, period))/2;
}

function radius(spacing, angle) {
  return spacing * angle;
}<commit_msg>Continue refactor<commit_after>function Spiral(graphType) {
  this.graphParams = {
    graphType: graphType || "points",
    numberOfPoints: null,
    period: null,
    margin: {
      top: 10,
      right: 10,
      bottom: 10,
      left: 10
    },
    svgHeight: 0,
    svgWidth: 0,
    spacing: 1,
    lineWidth: 50,
    targetElement: '#chart',
  },
  this.data = [],
  this.x = d3.scale.linear().range([0, 730]).domain([-750, 750]),
  this.y = d3.scale.linear().range([480, 0]).domain([-500, 500]),
  this.cartesian = function(radius, angle, size, startAngle, endAngle) {
    var size = size || 1;
    var xPos = this.x(radius * Math.cos(angle));
    var yPos = this.y(radius * Math.sin(angle));
    return [xPos, yPos, size, radius, angle, startAngle, endAngle];
  },
  this.render = function() {
    var spiralContext = this;

    var svg = d3.select(spiralContext.graphParams.targetElement)
      .append("svg")
      .attr("width", spiralContext.graphParams.svgWidth)
      .attr("height", spiralContext.graphParams.svgHeight)

    if (spiralContext.graphParams.graphType === "points") {
      svg.append("g")
        .attr("transform", "translate(" + spiralContext.graphParams.margin.left + "," + spiralContext.graphParams.margin.top + ")");

      svg.selectAll("g").selectAll("dot")
        .data(spiralContext.data)
          .enter().append("circle")
            .attr("r", function(d) { return d[2]; })
            .attr("cx", function(d) { return d[0]; })
            .attr("cy", function(d) { return d[1]; });
    } else if (spiralContext.graphParams.graphType === "custom-path") {
      spiralContext.data.forEach(function(datum, t, dataSet){
        var start = startAngle(t, spiralContext.graphParams.period);
        var end = endAngle(t, spiralContext.graphParams.period);

        var startInnerRadius = radius(spiralContext.graphParams.spacing, start) - spiralContext.graphParams.lineWidth*0.5;
        var startOuterRadius = radius(spiralContext.graphParams.spacing, start) + spiralContext.graphParams.lineWidth*0.5;
        var endInnerRadius = radius(spiralContext.graphParams.spacing, end) - spiralContext.graphParams.lineWidth*0.5;
        var endOuterRadius = radius(spiralContext.graphParams.spacing, end) + spiralContext.graphParams.lineWidth*0.5;

        var ctrlInnerRad = 0.01; // Use to adjust arc inner radius
        var ctrlOuterRad = 0.01; // Use to adjust arc outer radius
        var innerControlPoint = spiralContext.cartesian(radius(spiralContext.graphParams.spacing, theta(t, spiralContext.graphParams.period)) - spiralContext.graphParams.lineWidth*0.5 + ctrlInnerRad, theta(t, spiralContext.graphParams.period));
        var outerControlPoint = spiralContext.cartesian(radius(spiralContext.graphParams.spacing, theta(t, spiralContext.graphParams.period)) + spiralContext.graphParams.lineWidth*0.5 + ctrlOuterRad, theta(t, spiralContext.graphParams.period));

        var startPoint = spiralContext.cartesian(startInnerRadius, start); // Bottom right of arc
        var point2 = spiralContext.cartesian(startOuterRadius, start); // Top right of arc
        var point3 = spiralContext.cartesian(endOuterRadius, end); // Top left of arc
        var point4 = spiralContext.cartesian(endInnerRadius, end); // Bottom left of arc
        var arcPath = "M" + startPoint[0] + " " + startPoint[1] + "L" + point2[0] + " " + point2[1];
        arcPath += "Q" + outerControlPoint[0] + " " + outerControlPoint[1] + " " + point3[0] + " " + point3[1];
        arcPath += "L" + point4[0] + " " + point4[1];
        arcPath += "Q" + innerControlPoint[0] + " " + innerControlPoint[1] + " " + startPoint[0] + " " + startPoint[1] + "Z";
        datum[1] = arcPath
      });

      svg.append("g")
        .attr("transform", "translate(" + spiralContext.graphParams.margin.left + "," + spiralContext.graphParams.margin.top + ")");
      svg.selectAll("g").selectAll("path")
        .data(spiralContext.data.slice(100))
        .enter().append("path")
          .style("fill", function(d) { return "black"; })
          .style("opacity", function(d) {return d[2]/9})
          .attr("d", function(d) { return d[1]});
    } else if (spiralContext.graphParams.graphType === "non-spiral") {
      // --------------------vvv Standard Line Graph vvv---------------------------
      var x2 = d3.scale.linear().range([0, 730]);
      var y2 = d3.scale.linear().range([480, 0]);
      x2.domain(d3.extent(spiralContext.data, function(d) { return d[0]; }));
      y2.domain(d3.extent(spiralContext.data, function(d) { return d[1]; }));

      var xAxis = d3.svg.axis().scale(x2)
        .orient("bottom").ticks(5);

      var yAxis = d3.svg.axis().scale(y2)
        .orient("left").ticks(5);

      var line = d3.svg.line()
        .x(function(d) { return x2(d[0]); })
        .y(function(d) { return y2(d[1]); });

      // Add the X Axis
      svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate("+spiralContext.graphParams.margin.left+"," + 480 + ")")
        .call(xAxis)
        .append("text")
          .attr("x", 710)
          .attr("y", -3)
          .attr("dy", "-.35em")
          .style("text-anchor", "middle")
          .text("time");

      // Add the Y Axis
      svg.append("g")
        .attr("class", "y axis")
        .attr("transform", "translate("+spiralContext.graphParams.margin.left+",0)")
        .call(yAxis)
        .append("text")
          .attr("transform", "rotate(-90)")
          .attr("y", 6)
          .attr("dy", ".71em")
          .style("text-anchor", "end")
          .text("Signal (a.u.)");

      svg.append("path")
        .datum(spiralContext.data)
        .attr("class", "line")
        .attr("d", line)
        .attr("fill", "none")
        .attr("stroke-width", "1")
        .attr("stroke", "steelblue")
        .attr("transform", "translate("+spiralContext.graphParams.margin.left+",0)")
    }
  },
  this.randomData = function() {
    this.data = [];
    for (var i=0; i<this.graphParams.numberOfPoints; i++){
      var angle = theta(i, this.graphParams.period);
      var rad = radius(this.graphParams.spacing, angle);
      var size = 1 + Math.random()*1.5;
      if (i % 10 === 0) {
        size = 5.5 + Math.random()*3;
      }

      if (this.graphParams.graphType === 'non-spiral') {
        this.data.push([i, size*this.graphParams.period, 2])
      } else {
        this.data.push(this.cartesian(rad, angle, size, startAngle(i, this.graphParams.period), endAngle(i, this.graphParams.period)));
      }
    }
  },
  this.setParam = function(param, value) {
    var spiralContext = this;
    if (['targetElement', 'lineWidth', 'spacing', 'svgHeight', 'svgWidth', 'numberOfPoints', 'period', 'margin.top', 'margin.right', 'margin.bottom', 'margin.left'].indexOf(param) > -1)  {
      spiralContext.graphParams[param] = value;
    } else {
      spiralContext[param] = value;
    }
    if (['svgHeight', 'svgWidth', 'margin.top', 'margin.right', 'margin.bottom', 'margin.left'].indexOf(param) > -1) {
      var width = spiralContext.graphParams.svgWidth - spiralContext.graphParams.margin.left - spiralContext.graphParams.margin.right;
      var height = spiralContext.graphParams.svgHeight - spiralContext.graphParams.margin.top - spiralContext.graphParams.margin.bottom;
      spiralContext.x = d3.scale.linear().range([0, width]).domain([-spiralContext.graphParams.svgWidth, spiralContext.graphParams.svgWidth]);
      spiralContext.y = d3.scale.linear().range([height, 0]).domain([-spiralContext.graphParams.svgHeight, spiralContext.graphParams.svgHeight]);
    }
  },
  this.redraw = function() {
    var spiralContext = this;
    var graphContainer = document.getElementById(spiralContext.graphParams.targetElement.substr(1));
    while (graphContainer.firstChild) {
      graphContainer.removeChild(graphContainer.firstChild)
    }
    spiralContext.render();
  },
  this.autocorrelate = function() {}
}

// For time point #t, calculate the angle to the center of the arc
// period is the number of time points per revolution (2 PI)
function theta(t, period) {
  return 2 * Math.PI / (period) * t;
}

function startAngle(t, period) {
  return (theta(t-1, period) + theta(t, period))/2;
}

function endAngle(t, period) {
  return (theta(t+1, period) + theta(t, period))/2;
}

function radius(spacing, angle) {
  return spacing * angle;
}<|endoftext|>


<commit_before>/* This the library file for the Sprite Javascript framework -- sprite.js */

(function(){

function Sprite() {
    // positions
    this.x = 0;
    this.y = 0;
    // x velocity
    this.xv = 0;
    // y velocity
    this.yv = 0;

    // image
    this.img = null;
    // weight, height
    this.w = 100;
    this.h = 100;

    this.xoffset=0;
    this.yoffset=0;

    this.dom = null;

    this.xscale = 1;
    this.yscale = 1;
    // radial position
    this.r = 0;

    this.transform_changed = false;
}

Sprite.prototype.init = function() {
    var d = document.createElement('div');
    d.className = 'sprite';
    d.style['overflow'] = 'hidden';
    d.style['position'] = 'absolute';
    this.dom = d;
    document.body.appendChild(this.dom);
};

Sprite.prototype.constructor = Sprite;

Sprite.prototype.rotate = function (v) {
    this.transform_changed = true;
    this.r = this.r+v;
};

Sprite.prototype.scale = function (x, y) {
    this.transform_changed = true;
    this.xscale = x;
    this.yscale = y;
};

Sprite.prototype.move = function (x, y) {
    this.x = this.x+x;
    this.y = this.y+y;
};

Sprite.prototype.update2 = function updateDomProperties () {
    var style = this.dom.style;
    style.width=this.w;
    style.height=this.h;
    style.top=this.y+'px';
    style.left=this.x+'px';
    this.img.style.left=this.xoffset+'px';
    this.img.style.top=this.yoffset+'px';
    if(this.transform_changed) {
        style[jsp.tproperty] = 'rotate('+this.r+'rad) scale('+this.xscale+', '+this.yscale+')';
        this.transform_changed = false;
    }
};

Sprite.prototype.update = function updateCssText () {
    /* my tests show that cssText is way more efficient on firefox.
    somewhat better on webkit and a bit worse on Opera */
    var cssText = "";
    cssText+='width:'+this.w+'px;';
    cssText+='height:'+this.h+'px;';
    cssText+='top:'+this.y+'px;';
    cssText+='left:'+this.x+'px;';
    this.img.style.left=this.xoffset+'px';
    this.img.style.top=this.yoffset+'px';
    // this has pretty bad perfs implication on Opera, don't update the value if nothing changed
    if(this.transform_changed) {
        cssText+=jsp.cproperty+':rotate('+this.r+'rad) scale('+this.xscale+', '+this.yscale+');';
        this.transform_changed = false;
    }
    this.dom.style.cssText = cssText;
};

Sprite.prototype.toString = function () {
    return String(this.x) + ',' + String(this.y);
};

Sprite.prototype.loadImg = function (src) {
    this.img = new Image();
    var there = this;
    this.img.onload = function() {
        there.dom.appendChild(there.img);
    };
    this.img.src = src;
};

function Cycle(triplet) {
    /* Cycle for the Sprite image.
    A cycle is a list of triplet (x offset, y offset, game tick duration) */
    this.triplet = triplet;
    this.cycle_duration = 0;
    this.changing_ticks = [];
    for(var i=0; i<triplet.length; i++) {
        this.cycle_duration = this.cycle_duration + triplet[i][2];
        this.changing_ticks.push(this.cycle_duration);
    }
    this.sprites = [];
    this.repeat = true;
    this.tick = 0;
};

Cycle.prototype.next = function () {
    if(this.tick > this.cycle_duration) {

    }
    for(var i=0; i<this.changing_ticks.length; i++) {
        if(this.tick == this.changing_ticks[i]) {
            for(j=0; j<this.sprites.length; j++) {
                this.sprites[j].xoffset = this.triplet[i][0];
                this.sprites[j].yoffset = this.triplet[i][1];
            }
        }
    }
    this.tick = this.tick + 1;
    if(this.tick > this.cycle_duration)
        this.tick = 0;
};

function SquaredSprite() {

};

SquaredSprite.prototype = new Sprite();
SquaredSprite.prototype.constructor = SquaredSprite;

var jsp = {};
jsp.Sprite = Sprite;
jsp.SquaredSprite = SquaredSprite;
jsp.Cycle = Cycle;

jsp.tproperty = false;
jsp.cproperty = false;
function getTransformProperty() {
    var properties = ['transform', 'WebkitTransform', 'MozTransform', 'OTransform'];
    var css_properties = ['transform', '-webkit-transform', '-moz-transform', '-o-transform'];
    var p = false;
    while (p = properties.shift()) {
        var c = css_properties.shift();
        if (typeof document.body.style[p] != 'undefined') {
            jsp.tproperty = p;
            jsp.cproperty = c;
        }
    }
}
 // TODO: be sure the body is loaded before doing that
getTransformProperty();
window.jsp = jsp;

})();<commit_msg>Remove unecessay styling<commit_after>/* This the library file for the Sprite Javascript framework -- sprite.js */

(function(){

function Sprite() {
    // positions
    this.x = 0;
    this.y = 0;
    // x velocity
    this.xv = 0;
    // y velocity
    this.yv = 0;

    // image
    this.img = null;
    // weight, height
    this.w = 100;
    this.h = 100;

    this.xoffset=0;
    this.yoffset=0;

    this.dom = null;

    this.xscale = 1;
    this.yscale = 1;
    // radial position
    this.r = 0;

    this.transform_changed = false;
}

Sprite.prototype.init = function() {
    var d = document.createElement('div');
    d.className = 'sprite';
    this.dom = d;
    document.body.appendChild(this.dom);
};

Sprite.prototype.constructor = Sprite;

Sprite.prototype.rotate = function (v) {
    this.transform_changed = true;
    this.r = this.r+v;
};

Sprite.prototype.scale = function (x, y) {
    this.transform_changed = true;
    this.xscale = x;
    this.yscale = y;
};

Sprite.prototype.move = function (x, y) {
    this.x = this.x+x;
    this.y = this.y+y;
};

Sprite.prototype.update2 = function updateDomProperties () {
    var style = this.dom.style;
    style.width=this.w;
    style.height=this.h;
    style.top=this.y+'px';
    style.left=this.x+'px';
    this.img.style.left=this.xoffset+'px';
    this.img.style.top=this.yoffset+'px';
    if(this.transform_changed) {
        style[jsp.tproperty] = 'rotate('+this.r+'rad) scale('+this.xscale+', '+this.yscale+')';
        this.transform_changed = false;
    }
};

Sprite.prototype.update = function updateCssText () {
    /* my tests show that cssText is way more efficient on firefox.
    somewhat better on webkit and a bit worse on Opera */
    var cssText = "";
    cssText+='width:'+this.w+'px;';
    cssText+='height:'+this.h+'px;';
    cssText+='top:'+this.y+'px;';
    cssText+='left:'+this.x+'px;';
    this.img.style.left=this.xoffset+'px';
    this.img.style.top=this.yoffset+'px';
    // this has pretty bad perfs implication on Opera, don't update the value if nothing changed
    if(this.transform_changed) {
        cssText+=jsp.cproperty+':rotate('+this.r+'rad) scale('+this.xscale+', '+this.yscale+');';
        this.transform_changed = false;
    }
    this.dom.style.cssText = cssText;
};

Sprite.prototype.toString = function () {
    return String(this.x) + ',' + String(this.y);
};

Sprite.prototype.loadImg = function (src) {
    this.img = new Image();
    var there = this;
    this.img.onload = function() {
        there.dom.appendChild(there.img);
    };
    this.img.src = src;
};

function Cycle(triplet) {
    /* Cycle for the Sprite image.
    A cycle is a list of triplet (x offset, y offset, game tick duration) */
    this.triplet = triplet;
    this.cycle_duration = 0;
    this.changing_ticks = [];
    for(var i=0; i<triplet.length; i++) {
        this.cycle_duration = this.cycle_duration + triplet[i][2];
        this.changing_ticks.push(this.cycle_duration);
    }
    this.sprites = [];
    this.repeat = true;
    this.tick = 0;
};

Cycle.prototype.next = function () {
    if(this.tick > this.cycle_duration) {

    }
    for(var i=0; i<this.changing_ticks.length; i++) {
        if(this.tick == this.changing_ticks[i]) {
            for(j=0; j<this.sprites.length; j++) {
                this.sprites[j].xoffset = this.triplet[i][0];
                this.sprites[j].yoffset = this.triplet[i][1];
            }
        }
    }
    this.tick = this.tick + 1;
    if(this.tick > this.cycle_duration)
        this.tick = 0;
};

function SquaredSprite() {

};

SquaredSprite.prototype = new Sprite();
SquaredSprite.prototype.constructor = SquaredSprite;

var jsp = {};
jsp.Sprite = Sprite;
jsp.SquaredSprite = SquaredSprite;
jsp.Cycle = Cycle;

jsp.tproperty = false;
jsp.cproperty = false;
function getTransformProperty() {
    var properties = ['transform', 'WebkitTransform', 'MozTransform', 'OTransform'];
    var css_properties = ['transform', '-webkit-transform', '-moz-transform', '-o-transform'];
    var p = false;
    while (p = properties.shift()) {
        var c = css_properties.shift();
        if (typeof document.body.style[p] != 'undefined') {
            jsp.tproperty = p;
            jsp.cproperty = c;
        }
    }
}
 // TODO: be sure the body is loaded before doing that
getTransformProperty();
window.jsp = jsp;

})();<|endoftext|>


<commit_before>var assert = require("assert");
var path = require("path");
var promisify = require("promisify-node");
var Promise = require("nodegit-promise");
var fse = promisify(require("fs-extra"));
var local = path.join.bind(path, __dirname);

describe("Repository", function() {
  var NodeGit = require("../../");
  var Repository = NodeGit.Repository;
  var Index = NodeGit.Index;
  var Signature = NodeGit.Signature;

  var reposPath = local("../repos/workdir");
  var newRepoPath = local("../repos/newrepo");
  var emptyRepoPath = local("../repos/empty");

  beforeEach(function() {
    var test = this;

    return Repository.open(reposPath)
      .then(function(repository) {
        test.repository = repository;
      })
      .then(function() {
        return Repository.open(emptyRepoPath);
      })
      .then(function(emptyRepo) {
        test.emptyRepo = emptyRepo;
      });
  });

  it("can open a valid repository", function() {
    assert.ok(this.repository instanceof Repository);
  });

  it("cannot open an invalid repository", function() {
    return Repository.open("repos/nonrepo")
      .then(null, function(err) {
        assert.ok(err instanceof Error);
      });
  });

  it("does not try to open paths that don't exist", function() {
    var missingPath = "/surely/this/directory/does/not/exist/on/this/machine";

    return Repository.open(missingPath)
      .then(null, function(err) {
        assert.ok(err instanceof Error);
      });
  });

  it("can initialize a repository into a folder", function() {
    return Repository.init(newRepoPath, 1)
      .then(function(path, isBare) {
        return Repository.open(newRepoPath);
      });
  });

  it("can utilize repository init options", function() {
    return fse.remove(newRepoPath)
      .then(function() {
        return Repository.initExt(newRepoPath, {
          flags: Repository.INIT_FLAG.MKPATH
        });
      });
  });

  it("can read the index", function() {
    return this.repository.index()
      .then(function(index) {
        assert.ok(index instanceof Index);
      });
  });

  it("can list remotes", function() {
    return this.repository.getRemotes()
      .then(function(remotes) {
        assert.equal(remotes.length, 1);
        assert.equal(remotes[0], "origin");
      });
  });

  it("can get the current branch", function() {
    return this.repository.getCurrentBranch()
      .then(function(branch) {
        assert.equal(branch.shorthand(), "master");
      });
  });

  it("can get the default signature", function() {
    var sig = this.repository.defaultSignature();

    assert(sig instanceof Signature);
  });

  it("gets statuses with StatusFile", function() {
    var fileName = "my-new-file-that-shouldnt-exist.file";
    var fileContent = "new file from repository test";
    var repo = this.repository;
    var filePath = path.join(repo.workdir(), fileName);

    return fse.writeFile(filePath, fileContent)
      .then(function() {
        return repo.getStatus().then(function(statuses) {
          assert.equal(statuses.length, 1);
          assert.equal(statuses[0].path(), fileName);
          assert.ok(statuses[0].isNew());
        });
      })
      .then(function() {
        return fse.remove(filePath);
      })
      .catch(function (e) {
        return fse.remove(filePath)
          .then(function() {
            return Promise.reject(e);
          });
      });
  });

  it("gets extended statuses", function() {
    var fileName = "my-new-file-that-shouldnt-exist.file";
    var fileContent = "new file from repository test";
    var repo = this.repository;
    var filePath = path.join(repo.workdir(), fileName);

    return fse.writeFile(filePath, fileContent)
      .then(function() {
        var statuses = repo.getStatusExt();

        assert.equal(statuses.length, 1);
        assert.equal(statuses[0].path(), fileName);
        assert.equal(statuses[0].indexToWorkdir().newFile().path(), fileName);
        assert.ok(statuses[0].isNew());
      })
      .then(function() {
        return fse.remove(filePath);
      })
      .catch(function (e) {
        return fse.remove(filePath)
          .then(function() {
            return Promise.reject(e);
          });
      });
  });

  it("gets fetch-heads", function() {
    var repo = this.repository;
    var foundMaster;

    return repo.fetch("origin", {
      credentials: function(url, userName) {
        return NodeGit.Cred.sshKeyFromAgent(userName);
      },
      certificateCheck: function() {
        return 1;
      }
    })
    .then(function() {
      return repo.fetchheadForeach(function(refname, remoteUrl, oid, isMerge) {
        if (refname == "refs/heads/master") {
          foundMaster = true;
          assert.equal(refname, "refs/heads/master");
          assert.equal(remoteUrl, "https://github.com/nodegit/test");
          assert.equal(
            oid.toString(),
            "32789a79e71fbc9e04d3eff7425e1771eb595150");
          assert.equal(isMerge, 1);
        }
      });
    })
    .then(function() {
      if (!foundMaster) {
        throw new Error("Couldn't find master in iteration of fetch heads");
      }
    });
  });

  it("can discover if a path is part of a repository", function() {
    var testPath = path.join(reposPath, "lib", "util", "normalize_oid.js");
    var expectedPath = path.join(reposPath, ".git");
    return NodeGit.Repository.discover(testPath, 0, "")
      .then(function(foundPath) {
        assert.equal(expectedPath, foundPath);
      });
  });

  it("can create a repo using initExt", function() {
    var initFlags = NodeGit.Repository.INIT_FLAG.NO_REINIT |
      NodeGit.Repository.INIT_FLAG.MKPATH |
      NodeGit.Repository.INIT_FLAG.MKDIR;
    return fse.remove(newRepoPath)
      .then(function() {
        return NodeGit.Repository.initExt(newRepoPath, { flags: initFlags });
      })
      .then(function() {
        return NodeGit.Repository.open(newRepoPath);
      });
  });

  it("can get the head commit", function() {
    return this.repository.getHeadCommit()
      .then(function(commit) {
        assert.equal(
          commit.toString(),
          "32789a79e71fbc9e04d3eff7425e1771eb595150"
        );
      });
  });

  it("returns null if there is no head commit", function() {
    return this.emptyRepo.getHeadCommit()
      .then(function(commit) {
        assert(!commit);
      });
  });
});
<commit_msg>Test initExt for error handling<commit_after>var assert = require("assert");
var path = require("path");
var promisify = require("promisify-node");
var Promise = require("nodegit-promise");
var fse = promisify(require("fs-extra"));
var local = path.join.bind(path, __dirname);

describe("Repository", function() {
  var NodeGit = require("../../");
  var Repository = NodeGit.Repository;
  var Index = NodeGit.Index;
  var Signature = NodeGit.Signature;

  var reposPath = local("../repos/workdir");
  var newRepoPath = local("../repos/newrepo");
  var emptyRepoPath = local("../repos/empty");

  beforeEach(function() {
    var test = this;

    return Repository.open(reposPath)
      .then(function(repository) {
        test.repository = repository;
      })
      .then(function() {
        return Repository.open(emptyRepoPath);
      })
      .then(function(emptyRepo) {
        test.emptyRepo = emptyRepo;
      });
  });

  it("can open a valid repository", function() {
    assert.ok(this.repository instanceof Repository);
  });

  it("cannot open an invalid repository", function() {
    return Repository.open("repos/nonrepo")
      .then(null, function(err) {
        assert.ok(err instanceof Error);
      });
  });

  it("does not try to open paths that don't exist", function() {
    var missingPath = "/surely/this/directory/does/not/exist/on/this/machine";

    return Repository.open(missingPath)
      .then(null, function(err) {
        assert.ok(err instanceof Error);
      });
  });

  it("can initialize a repository into a folder", function() {
    return Repository.init(newRepoPath, 1)
      .then(function(path, isBare) {
        return Repository.open(newRepoPath);
      });
  });

  it("can utilize repository init options", function() {
    return fse.remove(newRepoPath)
      .then(function() {
        return Repository.initExt(newRepoPath, {
          flags: Repository.INIT_FLAG.MKPATH
        });
      });
  });

  it("can read the index", function() {
    return this.repository.index()
      .then(function(index) {
        assert.ok(index instanceof Index);
      });
  });

  it("can list remotes", function() {
    return this.repository.getRemotes()
      .then(function(remotes) {
        assert.equal(remotes.length, 1);
        assert.equal(remotes[0], "origin");
      });
  });

  it("can get the current branch", function() {
    return this.repository.getCurrentBranch()
      .then(function(branch) {
        assert.equal(branch.shorthand(), "master");
      });
  });

  it("can get the default signature", function() {
    var sig = this.repository.defaultSignature();

    assert(sig instanceof Signature);
  });

  it("gets statuses with StatusFile", function() {
    var fileName = "my-new-file-that-shouldnt-exist.file";
    var fileContent = "new file from repository test";
    var repo = this.repository;
    var filePath = path.join(repo.workdir(), fileName);

    return fse.writeFile(filePath, fileContent)
      .then(function() {
        return repo.getStatus().then(function(statuses) {
          assert.equal(statuses.length, 1);
          assert.equal(statuses[0].path(), fileName);
          assert.ok(statuses[0].isNew());
        });
      })
      .then(function() {
        return fse.remove(filePath);
      })
      .catch(function (e) {
        return fse.remove(filePath)
          .then(function() {
            return Promise.reject(e);
          });
      });
  });

  it("gets extended statuses", function() {
    var fileName = "my-new-file-that-shouldnt-exist.file";
    var fileContent = "new file from repository test";
    var repo = this.repository;
    var filePath = path.join(repo.workdir(), fileName);

    return fse.writeFile(filePath, fileContent)
      .then(function() {
        var statuses = repo.getStatusExt();

        assert.equal(statuses.length, 1);
        assert.equal(statuses[0].path(), fileName);
        assert.equal(statuses[0].indexToWorkdir().newFile().path(), fileName);
        assert.ok(statuses[0].isNew());
      })
      .then(function() {
        return fse.remove(filePath);
      })
      .catch(function (e) {
        return fse.remove(filePath)
          .then(function() {
            return Promise.reject(e);
          });
      });
  });

  it("gets fetch-heads", function() {
    var repo = this.repository;
    var foundMaster;

    return repo.fetch("origin", {
      credentials: function(url, userName) {
        return NodeGit.Cred.sshKeyFromAgent(userName);
      },
      certificateCheck: function() {
        return 1;
      }
    })
    .then(function() {
      return repo.fetchheadForeach(function(refname, remoteUrl, oid, isMerge) {
        if (refname == "refs/heads/master") {
          foundMaster = true;
          assert.equal(refname, "refs/heads/master");
          assert.equal(remoteUrl, "https://github.com/nodegit/test");
          assert.equal(
            oid.toString(),
            "32789a79e71fbc9e04d3eff7425e1771eb595150");
          assert.equal(isMerge, 1);
        }
      });
    })
    .then(function() {
      if (!foundMaster) {
        throw new Error("Couldn't find master in iteration of fetch heads");
      }
    });
  });

  it("can discover if a path is part of a repository", function() {
    var testPath = path.join(reposPath, "lib", "util", "normalize_oid.js");
    var expectedPath = path.join(reposPath, ".git");
    return NodeGit.Repository.discover(testPath, 0, "")
      .then(function(foundPath) {
        assert.equal(expectedPath, foundPath);
      });
  });

  it("can create a repo using initExt", function() {
    var initFlags = NodeGit.Repository.INIT_FLAG.NO_REINIT |
      NodeGit.Repository.INIT_FLAG.MKPATH |
      NodeGit.Repository.INIT_FLAG.MKDIR;
    return fse.remove(newRepoPath)
      .then(function() {
        return NodeGit.Repository.initExt(newRepoPath, { flags: initFlags });
      })
      .then(function() {
        return NodeGit.Repository.open(newRepoPath);
      });
  });

  it("will throw when a repo cannot be initialized using initExt", function() {
    var initFlags = NodeGit.Repository.INIT_FLAG.NO_REINIT |
      NodeGit.Repository.INIT_FLAG.MKPATH |
      NodeGit.Repository.INIT_FLAG.MKDIR;

    var nonsensePath = "gibberish";

    return NodeGit.Repository.initExt(nonsensePath, { flags: initFlags })
      .then(function() {
        assert.fail("Should have thrown an error.");
      })
      .catch(function(error) {
        assert(error, "Should have thrown an error.");
      });
  });

  it("can get the head commit", function() {
    return this.repository.getHeadCommit()
      .then(function(commit) {
        assert.equal(
          commit.toString(),
          "32789a79e71fbc9e04d3eff7425e1771eb595150"
        );
      });
  });

  it("returns null if there is no head commit", function() {
    return this.emptyRepo.getHeadCommit()
      .then(function(commit) {
        assert(!commit);
      });
  });
});
<|endoftext|>


<commit_before>require('./testdom')('');
import { assert } from 'chai';
import React from 'react';
import TestUtils from 'react-addons-test-utils';
import TocContainer from '../src/components/toc-container.jsx';
import testData from './testdata';
import filteredTestData from './filteredtestdata';

describe('<TocContainer />', function () {
  let el;
  function buttonEvent () {
    return true;
  }

  beforeEach(function () {
    el = TestUtils.renderIntoDocument( React.createElement(TocContainer, { buttonEvent, data: testData }, null) );
  });

  it('onFilterChange should not accept characters other than A-Z, - and \'', function () {
    el.onFilterChange({target:{ value: '9'}});
    assert.deepEqual(el.state.filteredData, testData);
    el.onFilterChange({target:{ value: '^'}});
    assert.deepEqual(el.state.filteredData, testData);
    el.onFilterChange({target:{ value: '@'}});
    assert.deepEqual(el.state.filteredData, testData);
  });

  it('onFilterChange should return two dragons', function () {
    el.onFilterChange({target:{ value: 'dragon'}});
    setTimeout(function(){
      assert.deepEqual(el.state.filteredData, filteredTestData);
    }, 20);
  });
});
<commit_msg>Proposed test<commit_after>require('./testdom')('');
import { assert } from 'chai';
import React from 'react';
import TestUtils from 'react-addons-test-utils';
import TocContainer from '../src/components/toc-container.jsx';
import testData from './testdata';
import filteredTestData from './filteredtestdata';

describe('<TocContainer />', function () {
  let el;
  function buttonEvent () {
    return true;
  }

  beforeEach(function () {
    el = TestUtils.renderIntoDocument( React.createElement(TocContainer, { buttonEvent, data: testData }, null) );
  });

  it('onFilterChange should not accept characters other than A-Z, - and \'', function () {
    el.onFilterChange({target:{ value: '9'}});
    assert.deepEqual(el.state.filteredData, testData);
    el.onFilterChange({target:{ value: '^'}});
    assert.deepEqual(el.state.filteredData, testData);
    el.onFilterChange({target:{ value: '@'}});
    assert.deepEqual(el.state.filteredData, testData);
  });

  it('onFilterChange should return two dragons', function () {
    el.onFilterChange({target:{ value: 'dragon'}});
    setTimeout(function(){
      assert.deepEqual(el.state.filteredData, filteredTestData);
    }, 20);
  });

  it('onFilterByChange should set state.filterBy to an approved value', function () {
    //el.onFilterByChange({target:{ value: 'challenge_rating'}});
    //assert.inArray(el.state.filterBy, [name, challenge_rating, type, subtype, terrain]);
    //el.onFilterByChange({target:{ value: 'dragon'}});
    //assert.!inArray(el.state.filterBy, [name, challenge_rating, type, subtype, terrain]);
  });

  it('onFilterChange should return two dragons', function () {
    //el.onFilterChange({target:{ value: '14'}});
    //setTimeout(function(){
    //  assert.deepEqual(el.state.filteredData, filteredTestData[0]);
    //}, 20);
  });
});
<|endoftext|>


<commit_before>var Query = require('../../lib/query'),
    should = require('should');

describe('query', function() {

  /**
   * WHERE
   *
   * Build the WHERE part of an sql statement from a js object
   */

  describe('.where()', function() {

    describe('`AND` criteria', function() {

      describe('case insensitivity', function() {

        // Lookup criteria
        var criteria = {
          where: {
            name: 'Foo',
            age: 1
          }
        };

        var schema = {
          test: {
            definition: { name: { type: 'text' }},
            schema: { name: { type: 'text' }}
          }
        };

        it('should build a SELECT statement using LOWER() on strings', function() {
          var query = new Query({ name: { type: 'text' }, age: { type: 'integer'}}, schema)
                      .find('test', criteria);

          var sql = 'SELECT "test"."name" FROM "test" WHERE LOWER("test"."name") = $1 ' +
                    'AND "test"."age" = $2';

          query.query.should.eql(sql);
          query.values[0].should.eql('foo');
        });
      });

      describe('criteria is simple key value lookups', function() {

        // Lookup criteria
        var criteria = {
          where: {
            name: 'foo',
            age: 27
          }
        };

        var schema = {
          test: {
            definition: { name: { type: 'text' }},
            schema: { name: { type: 'text' }}
          }
        };

        it('should build a simple SELECT statement', function() {
          var query = new Query({ name: { type: 'text' }, age: { type: 'integer'}}, schema)
                      .find('test', criteria);

          var sql = 'SELECT "test"."name" FROM "test" WHERE LOWER("test"."name") = $1 ' +
                    'AND "test"."age" = $2';

          query.query.should.eql(sql);
          query.values.length.should.eql(2);
        });

      });

      describe('has multiple comparators', function() {

        // Lookup criteria
        var criteria = {
          where: {
            name: 'foo',
            age: {
              '>' : 27,
              '<' : 30
            }
          }
        };

        var schema = {
          test: {
            definition: { name: { type: 'text' }},
            schema: { name: { type: 'text' }}
          }
        };

        it('should build a SELECT statement with comparators', function() {
          var query = new Query({ name: { type: 'text' }, age: { type: 'integer'}}, schema)
                      .find('test', criteria);

          var sql = 'SELECT "test"."name" FROM "test" WHERE LOWER("test"."name") = $1 ' +
                    'AND "test"."age" > $2 AND "test"."age" < $3 ';

          query.query.should.eql(sql);
          query.values.length.should.eql(3);
        });

      });
    });

    describe('`LIKE` criteria', function() {

      // Lookup criteria
      var criteria = {
        where: {
          like: {
            type: '%foo%',
            name: 'bar%'
          }
        }
      };

      var schema = {
        test: {
          definition: { name: { type: 'text' }},
          schema: { name: { type: 'text' }}
        }
      };

      it('should build a SELECT statement with ILIKE', function() {
        var query = new Query({ type: { type: 'text' }, name: { type: 'text'}}, schema)
                    .find('test', criteria);

        var sql = 'SELECT "test"."name" FROM "test" WHERE LOWER("test"."type") ILIKE $1 ' +
                  'AND LOWER("test"."name") ILIKE $2';

        query.query.should.eql(sql);
        query.values.length.should.eql(2);
      });

    });

    describe('`OR` criteria', function() {

      // Lookup criteria
      var criteria = {
        where: {
          or: [
            { like: { foo: '%foo%' } },
            { like: { bar: '%bar%' } }
          ]
        }
      };

      var schema = {
        test: {
          definition: { name: { type: 'text' }},
          schema: { name: { type: 'text' }}
        }
      };

      it('should build a SELECT statement with multiple like statements', function() {
        var query = new Query({ foo: { type: 'text' }, bar: { type: 'text'}}, schema)
                    .find('test', criteria);

        var sql = 'SELECT "test"."name" FROM "test" WHERE LOWER("test"."foo") ILIKE $1 ' +
                  'OR LOWER("test"."bar") ILIKE $2';

        query.query.should.eql(sql);
        query.values.length.should.eql(2);
      });
    });

    describe('`IN` criteria', function() {

      // Lookup criteria
      var criteria = {
        where: {
          name: [
            'foo',
            'bar',
            'baz'
          ]
        }
      };

      var schema = {
        test: {
          definition: { name: { type: 'text' }},
          schema: { name: { type: 'text' }}
        }
      };

      it('should build a SELECT statement with an IN array', function() {
        var query = new Query({ name: { type: 'text' }}, schema).find('test', criteria);
        var sql = 'SELECT "test"."name" FROM "test" WHERE LOWER("test"."name") IN ($1, $2, $3)';

        query.query.should.eql(sql);
        query.values.length.should.eql(3);
      });

    });

    describe('`NOT` criteria', function() {

      // Lookup criteria
      var criteria = {
        where: {
          age: {
            not: 40
          }
        }
      };

      var schema = {
        test: {
          definition: { name: { type: 'text' }},
          schema: { name: { type: 'text' }}
        }
      };

      it('should build a SELECT statement with an NOT clause', function() {
        var query = new Query({age: { type: 'integer'}}, schema).find('test', criteria);

        query.query.should.eql('SELECT "test"."name" FROM "test" WHERE "test"."age" <> $1 ');
        query.values.length.should.eql(1);
      });

    });

  });
});
<commit_msg>fix unit tests<commit_after>var Query = require('../../lib/query'),
    should = require('should');

describe('query', function() {

  /**
   * WHERE
   *
   * Build the WHERE part of an sql statement from a js object
   */

  describe('.where()', function() {

    describe('`AND` criteria', function() {

      describe('case insensitivity', function() {

        // Lookup criteria
        var criteria = {
          where: {
            name: 'Foo',
            age: 1
          }
        };

        var schema = {
          test: {
            definition: { name: { type: 'text' }},
            schema: { name: { type: 'text' }}
          }
        };

        it('should build a SELECT statement using LOWER() on strings', function() {
          var query = new Query({ name: { type: 'text' }, age: { type: 'integer'}}, schema)
                      .find('test', criteria);

          var sql = 'SELECT "test"."name" FROM "test" WHERE LOWER("test"."name") = $1 ' +
                    'AND "test"."age" = $2';

          query.query.should.eql(sql);
          query.values[0].should.eql('foo');
        });
      });

      describe('criteria is simple key value lookups', function() {

        // Lookup criteria
        var criteria = {
          where: {
            name: 'foo',
            age: 27
          }
        };

        var schema = {
          test: {
            definition: { name: { type: 'text' }},
            schema: { name: { type: 'text' }}
          }
        };

        it('should build a simple SELECT statement', function() {
          var query = new Query({ name: { type: 'text' }, age: { type: 'integer'}}, schema)
                      .find('test', criteria);

          var sql = 'SELECT "test"."name" FROM "test" WHERE LOWER("test"."name") = $1 ' +
                    'AND "test"."age" = $2';

          query.query.should.eql(sql);
          query.values.length.should.eql(2);
        });

      });

      describe('has multiple comparators', function() {

        // Lookup criteria
        var criteria = {
          where: {
            name: 'foo',
            age: {
              '>' : 27,
              '<' : 30
            }
          }
        };

        var schema = {
          test: {
            definition: { name: { type: 'text' }},
            schema: { name: { type: 'text' }}
          }
        };

        it('should build a SELECT statement with comparators', function() {
          var query = new Query({ name: { type: 'text' }, age: { type: 'integer'}}, schema)
                      .find('test', criteria);

          var sql = 'SELECT "test"."name" FROM "test" WHERE LOWER("test"."name") = $1 ' +
                    'AND "test"."age" > $2 AND "test"."age" < $3 ';

          query.query.should.eql(sql);
          query.values.length.should.eql(3);
        });

      });
    });

    describe('`LIKE` criteria', function() {

      // Lookup criteria
      var criteria = {
        where: {
          like: {
            type: '%foo%',
            name: 'bar%'
          }
        }
      };

      var schema = {
        test: {
          definition: { name: { type: 'text' }},
          schema: { name: { type: 'text' }}
        }
      };

      it('should build a SELECT statement with ILIKE', function() {
        var query = new Query({ type: { type: 'text' }, name: { type: 'text'}}, schema)
                    .find('test', criteria);

        var sql = 'SELECT "test"."name" FROM "test" WHERE LOWER("test"."type") ILIKE $1 ' +
                  'AND LOWER("test"."name") ILIKE $2';

        query.query.should.eql(sql);
        query.values.length.should.eql(2);
      });

    });

    describe('`OR` criteria', function() {

      // Lookup criteria
      var criteria = {
        where: {
          or: [
            { like: { foo: '%foo%' } },
            { like: { bar: '%bar%' } }
          ]
        }
      };

      var schema = {
        test: {
          definition: { name: { type: 'text' }},
          schema: { name: { type: 'text' }}
        }
      };

      it('should build a SELECT statement with multiple like statements', function() {
        var query = new Query({ foo: { type: 'text' }, bar: { type: 'text'}}, schema)
                    .find('test', criteria);

        var sql = 'SELECT "test"."name" FROM "test" WHERE ((LOWER("test"."foo") ILIKE $1) ' +
                  'OR (LOWER("test"."bar") ILIKE $2))';

        query.query.should.eql(sql);
        query.values.length.should.eql(2);
      });
    });

    describe('`IN` criteria', function() {

      // Lookup criteria
      var criteria = {
        where: {
          name: [
            'foo',
            'bar',
            'baz'
          ]
        }
      };

      var schema = {
        test: {
          definition: { name: { type: 'text' }},
          schema: { name: { type: 'text' }}
        }
      };

      it('should build a SELECT statement with an IN array', function() {
        var query = new Query({ name: { type: 'text' }}, schema).find('test', criteria);
        var sql = 'SELECT "test"."name" FROM "test" WHERE LOWER("test"."name") IN ($1, $2, $3)';

        query.query.should.eql(sql);
        query.values.length.should.eql(3);
      });

    });

    describe('`NOT` criteria', function() {

      // Lookup criteria
      var criteria = {
        where: {
          age: {
            not: 40
          }
        }
      };

      var schema = {
        test: {
          definition: { name: { type: 'text' }},
          schema: { name: { type: 'text' }}
        }
      };

      it('should build a SELECT statement with an NOT clause', function() {
        var query = new Query({age: { type: 'integer'}}, schema).find('test', criteria);

        query.query.should.eql('SELECT "test"."name" FROM "test" WHERE "test"."age" <> $1 ');
        query.values.length.should.eql(1);
      });

    });

  });
});
<|endoftext|>


<commit_before>/*global suso, describe, it, expect, beforeEach, document */
/*jslint plusplus: true */

(function () {
	"use strict";

	describe("Report view", function () {
		var grid = new suso.Grid(),
			ctrl,
			disp;

		it("when called without a ctrl, returns result wrapped in div with id Report-Display", function () {
			disp = new suso.views.Report({ grid: grid });
			expect(document.body.innerHTML.indexOf('
')).toBeGreaterThan(-1);
		});

		it("when called with a ctrl, returns a div with class report-container", function () {
			ctrl = document.createElement("div");
			disp = new suso.views.Report({ grid: grid, ctrl: ctrl });
			expect(ctrl.innerHTML.indexOf('
')).toBeGreaterThan(-1);
		});

		it("creates a div to conatin reports", function () {
			ctrl = document.createElement("div");
			disp = new suso.views.Report({ grid: grid, ctrl: ctrl });
			expect(ctrl.innerHTML.indexOf('

Report

')).toBeGreaterThan(-1);
		});

		it("creates divs inside container for each report", function () {
			ctrl = document.createElement("div");
			disp = new suso.views.Report({ grid: grid, ctrl: ctrl });
			grid.addSeeds([[1]]);
			expect(ctrl.innerHTML.indexOf('

Report
<div class="report"')).toBeGreaterThan(-1);
		});
	});
}());<commit_msg>update report view tests<commit_after>/*global suso, describe, it, expect, beforeEach, document */
/*jslint plusplus: true */

(function () {
	"use strict";

	describe("Report view", function () {
		var grid = new suso.Grid(),
			ctrl,
			disp;

		it("when called without a ctrl, returns result wrapped in div with id Report-Display", function () {
			disp = new suso.views.Report({ grid: grid });
			expect(document.body.innerHTML.indexOf('
')).toBeGreaterThan(-1);
		});

		it("when called with a ctrl, returns a div with class report-container", function () {
			ctrl = document.createElement("div");
			disp = new suso.views.Report({ grid: grid, ctrl: ctrl });
			expect(ctrl.innerHTML.indexOf('
')).toBeGreaterThan(-1);
		});

		it("creates a div to conatin reports", function () {
			ctrl = document.createElement("div");
			disp = new suso.views.Report({ grid: grid, ctrl: ctrl });
			expect(ctrl.innerHTML.indexOf('
Report
')).toBeGreaterThan(-1);
		});

		it("creates divs inside container for each report", function () {
			ctrl = document.createElement("div");
			disp = new suso.views.Report({ grid: grid, ctrl: ctrl });
			grid.addSeeds([[1]]);
			expect(ctrl.innerHTML.indexOf('
Report<div class="report"')).toBeGreaterThan(-1);
		});
	});
}());<|endoftext|>


<commit_before>/* Batchler.js, (c) 2015, Michael Fisher, v. 0.0.0.x */
if(!this['console']) {
  this['console'] = function (message) {};
}
var Batchler = {};
Batchler.Request = function (executer) {
  var exec = executer;
  /* Execute function. This function is called by the request's executer. The success and fail callbacks should include a call to the executer's callback function. */
  this.execute = execute;
  return this;
};
Batchler.Requests = {};
/* Executes requests synchronously. */
Batchler.Requests.SyncExecuter = function () {
  var queue = [];
  var queueIndex = 0;
  var running = false;
  this.percentComplete = Math.round(((queueIndex / queue.length) * 100));
  this.add = function (request) {
    queue.push(request);
    console.log('Synchronous request added.')
  };
  this.callback = function (result) {
    if (result) {
      console.log(result);
    }
	if (queueIndex == queue.length) {
      this.complete();
    }
	if (queueIndex < queue.length) {
      queue[queueIndex].execute();
      queueIndex += 1;
    }
  };
  this.run = function () {
    if (running === false) {
      running = true;
	  console.log('Sync executer running.');
      this.callback();
    }
  };
  this.complete = function () {
    console.log('Sync executer requests complete.')
  };
  return this;
};
/* Executes requests asynchronously. */
Batchler.Requests.AsyncExecuter = function () {
  var queue = [];
  var completed = 0;
  var running = false;
  this.add = function (request) {
    console.log('Asynchronous request added.');
    queue.push(request);
  };
  this.callback = function (result) {
	if (result) {
      console.log(result);
    }
	if (completed == queue.length) {
      this.complete();
    }
    if (completed < queue.length) {
      completed++;
    }
  };
  this.run = function () {
    if (running === false) {
      running = true;
      for (var ii in queue) {
        queue[ii].execute();
      }
      console.log('Async executer running.')
    }
  };
  this.complete = function () {
    console.log('Async executer requests complete.')
  };
  return this;
};
<commit_msg>Update Batchler.js<commit_after>/* Batchler.js, (c) 2015, Michael Fisher, v. 0.0.0 */
if(!this['console']) {
  this['console'] = function (message) {};
}
var Batchler = {};
Batchler.Request = function () {
  /* Execute function. This function is called by the request's executer. The success and fail callbacks should include a call to the executer's callback function. */
  this.execute = null;
  return this;
};
Batchler.Requests = {};
/* Executes requests synchronously. */
Batchler.Requests.SyncExecuter = function () {
  var queue = [];
  var queueIndex = 0;
  var running = false;
  this.percentComplete = Math.round(((queueIndex / queue.length) * 100));
  this.add = function (request) {
    queue.push(request);
    console.log('Synchronous request added.')
  };
  this.callback = function (result) {
    if (result) {
      console.log(result);
    }
	if (queueIndex == queue.length) {
      this.complete();
    }
	if (queueIndex < queue.length) {
      queue[queueIndex].execute();
      queueIndex += 1;
    }
  };
  this.run = function () {
    if (running === false) {
      running = true;
	  console.log('Sync executer running.');
      this.callback();
    }
  };
  this.complete = function () {
    console.log('Sync executer requests complete.')
  };
  return this;
};
/* Executes requests asynchronously. */
Batchler.Requests.AsyncExecuter = function () {
  var queue = [];
  var completed = 0;
  var running = false;
  this.add = function (request) {
    console.log('Asynchronous request added.');
    queue.push(request);
  };
  this.callback = function (result) {
	if (result) {
      console.log(result);
    }
	if (completed == queue.length) {
      this.complete();
    }
    if (completed < queue.length) {
      completed++;
    }
  };
  this.run = function () {
    if (running === false) {
      running = true;
      for (var ii in queue) {
        queue[ii].execute();
      }
      console.log('Async executer running.')
    }
  };
  this.complete = function () {
    console.log('Async executer requests complete.')
  };
  return this;
};
<|endoftext|>


<commit_before>'use strict';

const _ = require('lodash');
const path = require('path');
const Promise = require('bluebird');
const Model = require('../').Model;
const knexUtils = require('../lib/utils/knexUtils');
const transaction = require('../').transaction;
const snakeCaseMappers = require('../').snakeCaseMappers;

const chai = require('chai');
chai.use(require('chai-subset'));

class TestSession {

  static init() {
    if (this.staticInitCalled) {
      return;
    }

    registerUnhandledRejectionHandler();

    this.staticInitCalled = true;
  }

  constructor(opt) {
    TestSession.init();

    this.opt = opt;
    this.knex = this.createKnex(opt);
    this.unboundModels = this.createModels();
    this.models = _.mapValues(this.unboundModels, model => model.bindKnex(this.knex));
  }

  createKnex() {
    return require('knex')(this.opt.knexConfig);
  }

  createModels() {
    class Model1 extends Model {
      static get tableName() {
        return 'Model1';
      }

      static get namedFilters() {
        return {
          'select:id': (builder) => builder.select('id'),
          'select:model1Prop1': (builder) => builder.select('model1Prop1'),
          'orderBy:model1Prop1': (builder) => builder.orderBy('model1Prop1')
        };
      }

      static get relationMappings() {
        return {
          model1Relation1: {
            relation: Model.BelongsToOneRelation,
            modelClass: Model1,
            join: {
              from: 'Model1.model1Id',
              to: 'Model1.id'
            }
          },

          model1Relation1Inverse: {
            relation: Model.HasOneRelation,
            modelClass: Model1,
            join: {
              from: 'Model1.id',
              to: 'Model1.model1Id'
            }
          },

          model1Relation2: {
            relation: Model.HasManyRelation,
            modelClass: Model2,
            join: {
              from: 'Model1.id',
              to: 'model2.model1_id'
            }
          },

          model1Relation3: {
            relation: Model.ManyToManyRelation,
            modelClass: Model2,
            join: {
              from: 'Model1.id',
              through: {
                from: 'Model1Model2.model1Id',
                to: 'Model1Model2.model2Id',
                extra: ['extra1', 'extra2']
              },
              to: 'model2.id_col'
            }
          }
        };
      }
    }

    class Model2 extends Model {
      static get tableName() {
        return 'model2';
      }

      static get idColumn() {
        return 'id_col';
      }

      static get columnNameMappers() {
        return snakeCaseMappers();
      }

      static get relationMappings() {
        return {
          model2Relation1: {
            relation: Model.ManyToManyRelation,
            modelClass: Model1,
            join: {
              from: 'model2.id_col',
              through: {
                from: 'Model1Model2.model2Id',
                to: 'Model1Model2.model1Id',
                extra: {aliasedExtra: 'extra3'}
              },
              to: 'Model1.id'
            }
          },

          model2Relation2: {
            relation: Model.HasOneThroughRelation,
            modelClass: Model1,
            join: {
              from: 'model2.id_col',
              through: {
                from: 'Model1Model2One.model2Id',
                to: 'Model1Model2One.model1Id'
              },
              to: 'Model1.id'
            }
          }
        };
      }
    }

    [
      ['$beforeInsert', 5],
      ['$afterInsert', 1],
      ['$beforeDelete', 1],
      ['$afterDelete', 1],
      ['$beforeUpdate', 5, (self, args) => self.$beforeUpdateOptions = _.cloneDeep(args[0])],
      ['$afterUpdate', 1, (self, args) => self.$afterUpdateOptions = _.cloneDeep(args[0])],
      ['$afterGet', 1]
    ].forEach(hook => {
      Model1.prototype[hook[0]] = createHook(hook[0], hook[1], hook[2]);
      Model2.prototype[hook[0]] = createHook(hook[0], hook[1], hook[2]);
    });

    return {
      Model1: Model1,
      Model2: Model2
    };
  }

  createDb() {
    const knex = this.knex;
    const opt = this.opt;

    return Promise.resolve()
      .then(() => knex.schema.dropTableIfExists('Model1Model2'))
      .then(() => knex.schema.dropTableIfExists('Model1Model2One'))
      .then(() => knex.schema.dropTableIfExists('Model1'))
      .then(() => knex.schema.dropTableIfExists('model2'))
      .then(() => {
        return knex.schema
          .createTable('Model1', table => {
            table.increments('id').primary();
            table.integer('model1Id').index();
            table.string('model1Prop1');
            table.integer('model1Prop2');
          })
          .createTable('model2', table => {
            table.increments('id_col').primary();
            table.integer('model1_id').index();
            table.string('model2_prop1');
            table.integer('model2_prop2');
          })
          .createTable('Model1Model2', table => {
            table.increments('id').primary();
            table.string('extra1');
            table.string('extra2');
            table.string('extra3');
            table.integer('model1Id').unsigned().notNullable().references('id').inTable('Model1').onDelete('CASCADE').index();
            table.integer('model2Id').unsigned().notNullable().references('id_col').inTable('model2').onDelete('CASCADE').index();
          })
          .createTable('Model1Model2One', table => {
            table.integer('model1Id').unsigned().notNullable().references('id').inTable('Model1').onDelete('CASCADE').index();
            table.integer('model2Id').unsigned().notNullable().references('id_col').inTable('model2').onDelete('CASCADE').index();
          });
      })
      .catch(() => {
        throw new Error('Could not connect to '
          + opt.knexConfig.client
          + '. Make sure the server is running and the database '
          + opt.knexConfig.connection.database
          + ' is created. You can see the test database configurations from file '
          + path.join(__dirname, 'index.js'));
      });
  }

  populate(data) {
    return transaction(this.knex, (trx) => {
      return trx('Model1Model2')
        .delete()
        .then(() => trx('Model1Model2One').delete())
        .then(() => trx('Model1').delete())
        .then(() => trx('model2').delete())
        .then(() => this.models.Model1.query(trx).insertGraph(data))
        .then(() => {
          return Promise.resolve(['Model1', 'model2', 'Model1Model2']).map(table => {
            const idCol = (_.find(this.models, {tableName: table}) || {idColumn: 'id'}).idColumn;

            return trx(table).max(idCol).then(res => {
              const maxId = parseInt(res[0][_.keys(res[0])[0]], 10) || 0;

              // Reset sequence.
              if (knexUtils.isSqlite(trx)) {
                return trx.raw('UPDATE sqlite_sequence SET seq = ' + maxId + ' WHERE name = "' + table + '"');
              } else if (knexUtils.isPostgres(trx)) {
                return trx.raw('ALTER SEQUENCE "' + table + '_' + idCol + '_seq" RESTART WITH ' + (maxId + 1));
              } else if (knexUtils.isMySql(trx)) {
                return trx.raw('ALTER TABLE ' + table + ' AUTO_INCREMENT = ' + (maxId + 1));
              } else {
                throw new Error('sequence truncate not implemented for the given database');
              }
            });
          });
        })
        .then(() => data);
    });
  }

  destroy() {
    return this.knex.destroy();
  }

  addUnhandledRejectionHandler(handler) {
    const handlers = TestSession.unhandledRejectionHandlers;
    handlers.push(handler);
  }

  removeUnhandledRejectionHandler(handler) {
    const handlers = TestSession.unhandledRejectionHandlers;
    handlers.splice(handlers.indexOf(handler), 1);
  }

  isPostgres() {
    return knexUtils.isPostgres(this.knex);
  }

  isMySql() {
    return knexUtils.isMySql(this.knex);
  }
}

TestSession.staticInitCalled = false;
TestSession.unhandledRejectionHandlers = [];

// Creates an asynchronous hook that waits for `delay` milliseconds
// and then increments a `${name}Called` property.
function createHook(name, delay, extraAction) {
  return function () {
    const args = arguments;

    return Promise.delay(delay).then(() => {
      inc(this, `${name}Called`);
      (extraAction || _.noop)(this, args);
    });
  };
}

function inc(obj, key) {
  if (!_.has(obj, key)) {
    obj[key] = 1;
  } else {
    obj[key]++;
  }
}

function registerUnhandledRejectionHandler() {
  Promise.onPossiblyUnhandledRejection(error => {
    if (_.isEmpty(TestSession.unhandledRejectionHandlers)) {
      console.error(error.stack);
    }

    TestSession.unhandledRejectionHandlers.forEach(handler => {
      handler(error);
    });
  });
}

module.exports = TestSession;<commit_msg>decrease fake delays in test model hooks<commit_after>'use strict';

const _ = require('lodash');
const path = require('path');
const Promise = require('bluebird');
const Model = require('../').Model;
const knexUtils = require('../lib/utils/knexUtils');
const transaction = require('../').transaction;
const snakeCaseMappers = require('../').snakeCaseMappers;

const chai = require('chai');
chai.use(require('chai-subset'));

class TestSession {

  static init() {
    if (this.staticInitCalled) {
      return;
    }

    registerUnhandledRejectionHandler();

    this.staticInitCalled = true;
  }

  constructor(opt) {
    TestSession.init();

    this.opt = opt;
    this.knex = this.createKnex(opt);
    this.unboundModels = this.createModels();
    this.models = _.mapValues(this.unboundModels, model => model.bindKnex(this.knex));
  }

  createKnex() {
    return require('knex')(this.opt.knexConfig);
  }

  createModels() {
    class Model1 extends Model {
      static get tableName() {
        return 'Model1';
      }

      static get namedFilters() {
        return {
          'select:id': (builder) => builder.select('id'),
          'select:model1Prop1': (builder) => builder.select('model1Prop1'),
          'orderBy:model1Prop1': (builder) => builder.orderBy('model1Prop1')
        };
      }

      static get relationMappings() {
        return {
          model1Relation1: {
            relation: Model.BelongsToOneRelation,
            modelClass: Model1,
            join: {
              from: 'Model1.model1Id',
              to: 'Model1.id'
            }
          },

          model1Relation1Inverse: {
            relation: Model.HasOneRelation,
            modelClass: Model1,
            join: {
              from: 'Model1.id',
              to: 'Model1.model1Id'
            }
          },

          model1Relation2: {
            relation: Model.HasManyRelation,
            modelClass: Model2,
            join: {
              from: 'Model1.id',
              to: 'model2.model1_id'
            }
          },

          model1Relation3: {
            relation: Model.ManyToManyRelation,
            modelClass: Model2,
            join: {
              from: 'Model1.id',
              through: {
                from: 'Model1Model2.model1Id',
                to: 'Model1Model2.model2Id',
                extra: ['extra1', 'extra2']
              },
              to: 'model2.id_col'
            }
          }
        };
      }
    }

    class Model2 extends Model {
      static get tableName() {
        return 'model2';
      }

      static get idColumn() {
        return 'id_col';
      }

      static get columnNameMappers() {
        return snakeCaseMappers();
      }

      static get relationMappings() {
        return {
          model2Relation1: {
            relation: Model.ManyToManyRelation,
            modelClass: Model1,
            join: {
              from: 'model2.id_col',
              through: {
                from: 'Model1Model2.model2Id',
                to: 'Model1Model2.model1Id',
                extra: {aliasedExtra: 'extra3'}
              },
              to: 'Model1.id'
            }
          },

          model2Relation2: {
            relation: Model.HasOneThroughRelation,
            modelClass: Model1,
            join: {
              from: 'model2.id_col',
              through: {
                from: 'Model1Model2One.model2Id',
                to: 'Model1Model2One.model1Id'
              },
              to: 'Model1.id'
            }
          }
        };
      }
    }

    [
      ['$beforeInsert', 1],
      ['$afterInsert', 0],
      ['$beforeDelete', 1],
      ['$afterDelete', 1],
      ['$beforeUpdate', 1, (self, args) => self.$beforeUpdateOptions = _.cloneDeep(args[0])],
      ['$afterUpdate', 1, (self, args) => self.$afterUpdateOptions = _.cloneDeep(args[0])],
      ['$afterGet', 1]
    ].forEach(hook => {
      Model1.prototype[hook[0]] = createHook(hook[0], hook[1], hook[2]);
      Model2.prototype[hook[0]] = createHook(hook[0], hook[1], hook[2]);
    });

    return {
      Model1: Model1,
      Model2: Model2
    };
  }

  createDb() {
    const knex = this.knex;
    const opt = this.opt;

    return Promise.resolve()
      .then(() => knex.schema.dropTableIfExists('Model1Model2'))
      .then(() => knex.schema.dropTableIfExists('Model1Model2One'))
      .then(() => knex.schema.dropTableIfExists('Model1'))
      .then(() => knex.schema.dropTableIfExists('model2'))
      .then(() => {
        return knex.schema
          .createTable('Model1', table => {
            table.increments('id').primary();
            table.integer('model1Id').index();
            table.string('model1Prop1');
            table.integer('model1Prop2');
          })
          .createTable('model2', table => {
            table.increments('id_col').primary();
            table.integer('model1_id').index();
            table.string('model2_prop1');
            table.integer('model2_prop2');
          })
          .createTable('Model1Model2', table => {
            table.increments('id').primary();
            table.string('extra1');
            table.string('extra2');
            table.string('extra3');
            table.integer('model1Id').unsigned().notNullable().references('id').inTable('Model1').onDelete('CASCADE').index();
            table.integer('model2Id').unsigned().notNullable().references('id_col').inTable('model2').onDelete('CASCADE').index();
          })
          .createTable('Model1Model2One', table => {
            table.integer('model1Id').unsigned().notNullable().references('id').inTable('Model1').onDelete('CASCADE').index();
            table.integer('model2Id').unsigned().notNullable().references('id_col').inTable('model2').onDelete('CASCADE').index();
          });
      })
      .catch(() => {
        throw new Error('Could not connect to '
          + opt.knexConfig.client
          + '. Make sure the server is running and the database '
          + opt.knexConfig.connection.database
          + ' is created. You can see the test database configurations from file '
          + path.join(__dirname, 'index.js'));
      });
  }

  populate(data) {
    return transaction(this.knex, (trx) => {
      return trx('Model1Model2')
        .delete()
        .then(() => trx('Model1Model2One').delete())
        .then(() => trx('Model1').delete())
        .then(() => trx('model2').delete())
        .then(() => this.models.Model1.query(trx).insertGraph(data))
        .then(() => {
          return Promise.resolve(['Model1', 'model2', 'Model1Model2']).map(table => {
            const idCol = (_.find(this.models, {tableName: table}) || {idColumn: 'id'}).idColumn;

            return trx(table).max(idCol).then(res => {
              const maxId = parseInt(res[0][_.keys(res[0])[0]], 10) || 0;

              // Reset sequence.
              if (knexUtils.isSqlite(trx)) {
                return trx.raw('UPDATE sqlite_sequence SET seq = ' + maxId + ' WHERE name = "' + table + '"');
              } else if (knexUtils.isPostgres(trx)) {
                return trx.raw('ALTER SEQUENCE "' + table + '_' + idCol + '_seq" RESTART WITH ' + (maxId + 1));
              } else if (knexUtils.isMySql(trx)) {
                return trx.raw('ALTER TABLE ' + table + ' AUTO_INCREMENT = ' + (maxId + 1));
              } else {
                throw new Error('sequence truncate not implemented for the given database');
              }
            });
          });
        })
        .then(() => data);
    });
  }

  destroy() {
    return this.knex.destroy();
  }

  addUnhandledRejectionHandler(handler) {
    const handlers = TestSession.unhandledRejectionHandlers;
    handlers.push(handler);
  }

  removeUnhandledRejectionHandler(handler) {
    const handlers = TestSession.unhandledRejectionHandlers;
    handlers.splice(handlers.indexOf(handler), 1);
  }

  isPostgres() {
    return knexUtils.isPostgres(this.knex);
  }

  isMySql() {
    return knexUtils.isMySql(this.knex);
  }
}

TestSession.staticInitCalled = false;
TestSession.unhandledRejectionHandlers = [];

// Creates an asynchronous hook that waits for `delay` milliseconds
// and then increments a `${name}Called` property.
function createHook(name, delay, extraAction) {
  return function () {
    const args = arguments;

    return Promise.delay(delay).then(() => {
      inc(this, `${name}Called`);
      (extraAction || _.noop)(this, args);
    });
  };
}

function inc(obj, key) {
  if (!_.has(obj, key)) {
    obj[key] = 1;
  } else {
    obj[key]++;
  }
}

function registerUnhandledRejectionHandler() {
  Promise.onPossiblyUnhandledRejection(error => {
    if (_.isEmpty(TestSession.unhandledRejectionHandlers)) {
      console.error(error.stack);
    }

    TestSession.unhandledRejectionHandlers.forEach(handler => {
      handler(error);
    });
  });
}

module.exports = TestSession;<|endoftext|>