<commit_before>const chai = require('chai');
// TODO refactor in to test helper
const spies = require('chai-spies');

const Promise = require('bluebird');

chai.use(spies);

const Interactor = require('../src/interactor');
const Organizer = require('../src/organizer');

const expect = chai.expect;

class TestInteractor extends Interactor {
  call() {
    this.context.called = true;
    this.context.count += 1;
    if (this.context.rejectMe) {
      this.reject(this.context.error || new Error('You told me to!'));
    } else {
      this.resolve();
    }
  }
}

class TestOrganizer extends Organizer {
  constructor(context) {
    super(context);
    this.interactors = [TestInteractor];
  }
}

describe('Organizer', function() {
  it('single works', function() {
    const org = new TestOrganizer({count: 0});
    return org.exec().then((org) => {
      expect(org.context.count).to.equal(1);
    });
  });

  it('multiple works', function() {
    const org = new TestOrganizer({count: 0});
    org.interactors.push(TestInteractor);
    return org.exec().then((org) => {
      expect(org.context.count).to.equal(2);
    });
  });

  context('before', () => {
    it('called if defined', (done) => {
      class TestOrgWithBefore extends TestOrganizer {
        before() {
          this.context.beforeCalled = true;
          return Promise.resolve();
        }
      }
      const org = new TestOrgWithBefore();
      chai.spy.on(org, 'before');

      org.exec().then(() => {
        expect(org.context.beforeCalled).to.be.true;
        expect(org.before).to.have.been.called;
        done();
      });
    });

    it('rejects immediately if the before returns a rejected promise', (done) => {
      class TestOrgWithBefore extends TestOrganizer {
        before() {
          this.context.beforeCalled = true;
          return Promise.reject(new Error('Taco not included'));
        }
      }
      const org = new TestOrgWithBefore();
      chai.spy.on(org, 'before');

      org.exec().catch((err) => {
        expect(err.message).to.equal('Taco not included');
        expect(org.context.beforeCalled).to.be.true;
        expect(org.before).to.have.been.called;
      }).then(done);
    });
  });

  context('rollback', () => {

    it('called with rejection err', () => {
      class TestOrgWithRollback extends TestOrganizer {
        rollback() {
          return Promise.resolve();
        }
      }
      const error = new Error('squirrel!');
      const org = new TestOrgWithRollback({ count: 0, rejectMe: true, error });

      chai.spy.on(org, 'rollback');
      return org.exec().catch((err) => {
        expect(org.rollback).to.have.been.called.with(error);
        expect(err).to.equal(error);
      });
    });
    it('called if one fails', () => {
      class TestOrgWithRollback extends TestOrganizer {
        rollback() {
          return Promise.resolve();
        }
      }
      const org = new TestOrgWithRollback({ count: 0, rejectMe: true });

      chai.spy.on(org, 'rollback');
      return org.exec().catch(() => {
        expect(org.rollback).to.have.been.called();
      });
    });

    it('replaced err of reject with new one', () => {
      class TestOrgWithRollback extends TestOrganizer {
        rollback() {
          return new Promise((resolve, reject) => {
            reject(new Error('alternate reject'));
          });
        }
      }
      const org = new TestOrgWithRollback({ count: 0, rejectMe: true });

      return org.exec().catch((err) => {
        expect(err.message).to.equal('alternate reject');
      });
    });
  });
});
<commit_msg>added tes to confirm the interactor chain stops on the first reject<commit_after>const chai = require('chai');
// TODO refactor in to test helper
const spies = require('chai-spies');

const Promise = require('bluebird');

chai.use(spies);

const Interactor = require('../src/interactor');
const Organizer = require('../src/organizer');

const expect = chai.expect;

class TestInteractor extends Interactor {
  call() {

    this.context.called = true;
    this.context.count += 1;
    if (this.context.rejectMe) {
      this.reject(this.context.error || new Error('You told me to!'));
    } else if (this.context.rejectOn && this.context.rejectOn == this.context.count) {
      this.reject(this.context.error || new Error(`Reject on error count: ${this.context.count}`));
    } else {
      this.resolve();
    }
  }
}

class TestOrganizer extends Organizer {
  constructor(context) {
    super(context);
    this.interactors = [TestInteractor];
  }
}

describe('Organizer', function() {
  it('single works', function() {
    const org = new TestOrganizer({count: 0});
    return org.exec().then((org) => {
      expect(org.context.count).to.equal(1);
    });
  });

  it('multiple works', function() {
    const org = new TestOrganizer({count: 0});
    org.interactors.push(TestInteractor);
    return org.exec().then((org) => {
      expect(org.context.count).to.equal(2);
    });
  });

  it('multiple does not chain calls on reject', function() {
    const org = new TestOrganizer({count: 0, rejectOn: 2});
    org.interactors.push(TestInteractor);
    org.interactors.push(TestInteractor);
    return org.exec().catch((error) => {
      expect(error.message).to.equal('Reject on error count: 2');
      expect(org.context.count).to.equal(2);
    });
  });

  context('before', () => {
    it('called if defined', (done) => {
      class TestOrgWithBefore extends TestOrganizer {
        before() {
          this.context.beforeCalled = true;
          return Promise.resolve();
        }
      }
      const org = new TestOrgWithBefore();
      chai.spy.on(org, 'before');

      org.exec().then(() => {
        expect(org.context.beforeCalled).to.be.true;
        expect(org.before).to.have.been.called;
        done();
      });
    });

    it('rejects immediately if the before returns a rejected promise', (done) => {
      class TestOrgWithBefore extends TestOrganizer {
        before() {
          this.context.beforeCalled = true;
          return Promise.reject(new Error('Taco not included'));
        }
      }
      const org = new TestOrgWithBefore();
      chai.spy.on(org, 'before');

      org.exec().catch((err) => {
        expect(err.message).to.equal('Taco not included');
        expect(org.context.beforeCalled).to.be.true;
        expect(org.before).to.have.been.called;
      }).then(done);
    });
  });

  context('rollback', () => {

    it('called with rejection err', () => {
      class TestOrgWithRollback extends TestOrganizer {
        rollback() {
          return Promise.resolve();
        }
      }
      const error = new Error('squirrel!');
      const org = new TestOrgWithRollback({ count: 0, rejectMe: true, error });

      chai.spy.on(org, 'rollback');
      return org.exec().catch((err) => {
        expect(org.rollback).to.have.been.called.with(error);
        expect(err).to.equal(error);
      });
    });
    it('called if one fails', () => {
      class TestOrgWithRollback extends TestOrganizer {
        rollback() {
          return Promise.resolve();
        }
      }
      const org = new TestOrgWithRollback({ count: 0, rejectMe: true });

      chai.spy.on(org, 'rollback');
      return org.exec().catch(() => {
        expect(org.rollback).to.have.been.called();
      });
    });

    it('replaced err of reject with new one', () => {
      class TestOrgWithRollback extends TestOrganizer {
        rollback() {
          return new Promise((resolve, reject) => {
            reject(new Error('alternate reject'));
          });
        }
      }
      const org = new TestOrgWithRollback({ count: 0, rejectMe: true });

      return org.exec().catch((err) => {
        expect(err.message).to.equal('alternate reject');
      });
    });
  });
});
<|endoftext|>


<commit_before>'use strict';

function newElement(elType, elAttribute, elAttributeName, elParentId, elText){
  var el = document.createElement(elType);
  el.setAttribute(elAttribute, elAttributeName);
  el.textContent = elText;
  var parentEl = document.getElementById(elParentId);
  parentEl.appendChild(el);
}

function randomCust(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

function CookieStore(name, minCust, maxCust, avgCookies){
  this.name = name,
  this.minCust = minCust,
  this.maxCust = maxCust,
  this.avgCookies = avgCookies,
  this.cookPerHrArray = [];
  this.totalCook = 0;
}

var timeArr = [];
for (var i = 6; i < 21; i++){
  if (i < 12){
    timeArr.push(i + ':00am');
  } else if (i == 12) {
    timeArr.push('12:00pm');
  } else {
    var time = i - 12;
    timeArr.push(time + ':00pm');
  }
};
//console.log(timeArr);

var storeStrings = ['pike', 'seaTac', 'seaCenter', 'capHill', 'alki'];

var pike = new CookieStore('1st and Pike', 23, 65, 6.3);
var seaTac = new CookieStore('SeaTac Airport', 3, 24, 1.2);
var seaCenter = new CookieStore('Seattle Center', 11, 38, 3.7);
var capHill = new CookieStore('Capitol Hill', 20, 38, 2.3);
var alki = new CookieStore('Alki', 2, 16, 4.6);

var stores = [pike, seaTac, seaCenter, capHill, alki];

CookieStore.prototype.cookPerHr = function(){
  for (var i = 0; i < 15; i++){
    var cookies = Math.ceil(this.avgCookies * randomCust(this.minCust, this.maxCust));
    //console.log(cookies);
    this.cookPerHrArray.push(cookies);
  }
};

CookieStore.prototype.totalCookies = function(){
  var total = 0;
  for (var i = 0; i < 15; i++){
    this.totalCook += this.cookPerHrArray[i];
  }
  return this.totalCookies;
};

// console.log('test');
for (var i = 0; i < stores.length; i++){
  stores[i].cookPerHr();
  stores[i].totalCookies();
}
console.log(pike.cookPerHrArray);
console.log(pike);

newElement('table', 'id', 'master-table', 'store-stats', '');
function displayTableHead(){
  newElement('thead', 'id', 'table-head', 'master-table', '');
  newElement('tr', 'id', 'row-header', 'table-head', '');
  newElement('th', 'class', 'table-header', 'row-header', 'Store');
}
function render(){
  for (var i = 0; i < timeArr.length; i++){
    newElement('th', 'class', 'table-header', 'row-header', timeArr[i]);
  }
  newElement('th', 'class', 'table-header', 'row-header', 'Daily Totals');
  newElement('tbody', 'id', 'table-body', 'master-table', '');
  for (var i = 0; i < stores.length; i++){
    newElement('tr', 'id', ('row' + i), 'table-body', '');
    newElement('th', 'class', storeStrings[i], ('row' + i), stores[i].name);
    for (var j = 0; j < stores[i].cookPerHrArray.length; j++){
      newElement('td', 'class', storeStrings[i], ('row' + i), stores[i].cookPerHrArray[j]);
      //console.log(i);
      //console.log(j);
    }
    newElement('td', 'class', storeStrings[i], ('row' + i), stores[i].totalCook);
    //console.log(stores[i].cookPerHrArray.length);
  }
}

displayTableHead();

var newStoreForm = document.getElementById('new-store-form');
newStoreForm.addEventListener('submit', newStoreSubmit);

function newStoreSubmit(event){
  event.preventDefault();
  event.stopPropagation();

  var name = event.target.cookieStoreName.value;
  var minCust = parseInt(event.target.minCust.value);
  var maxCust = parseInt(event.target.maxCust.value);
  var avgCookies = parseFloat(event.target.avgCookies.value);

  // Create a new object.
  var newStore = new CookieStore(name, minCust, maxCust, avgCookies);
  stores.push(newStore); // Pushes new store into stores array.

  newStore.cookPerHr();
  newStore.totalCookies();

  render();
}
//----------------Demo area------------------------V
<commit_msg>finished table, fully functional<commit_after>'use strict';

function newElement(elType, elAttribute, elAttributeName, elParentId, elText){
  var el = document.createElement(elType);
  el.setAttribute(elAttribute, elAttributeName);
  el.textContent = elText;
  var parentEl = document.getElementById(elParentId);
  parentEl.appendChild(el);
}

function randomCust(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

function CookieStore(name, minCust, maxCust, avgCookies, identity){
  this.name = name,
  this.minCust = minCust,
  this.maxCust = maxCust,
  this.avgCookies = avgCookies,
  this.identity = identity,
  this.cookPerHrArray = [];
  this.totalCook = 0;
}

var timeArr = [];
for (var i = 6; i < 21; i++){
  if (i < 12){
    timeArr.push(i + ':00am');
  } else if (i == 12) {
    timeArr.push('12:00pm');
  } else {
    var time = i - 12;
    timeArr.push(time + ':00pm');
  }
};
//console.log(timeArr);

var storeStrings = ['pike', 'seaTac', 'seaCenter', 'capHill', 'alki'];

var pike = new CookieStore('1st and Pike', 23, 65, 6.3, 'pike');
var seaTac = new CookieStore('SeaTac Airport', 3, 24, 1.2, 'seaTac');
var seaCenter = new CookieStore('Seattle Center', 11, 38, 3.7, 'seaCenter');
var capHill = new CookieStore('Capitol Hill', 20, 38, 2.3, 'capHill');
var alki = new CookieStore('Alki', 2, 16, 4.6, 'alki');

var stores = [pike, seaTac, seaCenter, capHill, alki];

CookieStore.prototype.cookPerHr = function(){
  for (var i = 0; i < 15; i++){
    var cookies = Math.ceil(this.avgCookies * randomCust(this.minCust, this.maxCust));
    //console.log(cookies);
    this.cookPerHrArray.push(cookies);
  }
};

CookieStore.prototype.totalCookies = function(){
  var total = 0;
  for (var i = 0; i < 15; i++){
    this.totalCook += this.cookPerHrArray[i];
  }
  return this.totalCookies;
};

for (var i = 0; i < stores.length; i++){
  stores[i].cookPerHr();
  stores[i].totalCookies();
}
console.log(pike.cookPerHrArray);
console.log(pike);

newElement('table', 'id', 'master-table', 'store-stats', '');
function displayTableHead(){
  newElement('thead', 'id', 'table-head', 'master-table', '');
  newElement('tr', 'id', 'row-header', 'table-head', '');
  newElement('th', 'class', 'table-header', 'row-header', 'Store');
  for (var i = 0; i < timeArr.length; i++){
    newElement('th', 'class', 'table-header', 'row-header', timeArr[i]);
  }
  newElement('th', 'class', 'table-header', 'row-header', 'Daily Totals');
  newElement('tbody', 'id', 'table-body', 'master-table', '');
}

CookieStore.prototype.render = function(){
  newElement('tr', 'id', ('row' + this.identity), 'table-body', '');
  newElement('th', 'class', this.identity, ('row' + this.identity), this.name);
  for (var i = 0; i < this.cookPerHrArray.length; i++){
    newElement('td', 'class', this.identity, ('row' + this.identity), this.cookPerHrArray[i]);
  }
  newElement('td', 'class', this.identity, ('row' + this.identity), this.totalCook);
  //console.log(stores[i].cookPerHrArray.length);
};

displayTableHead();

var newStoreForm = document.getElementById('new-store-form');
newStoreForm.addEventListener('submit', newStoreSubmit);

function newStoreSubmit(event){
  event.preventDefault();
  event.stopPropagation();

  var name = event.target.cookieStoreName.value;
  var minCust = parseInt(event.target.minCust.value);
  var maxCust = parseInt(event.target.maxCust.value);
  var avgCookies = parseFloat(event.target.avgCookies.value);

  // Create a new object.
  var newStore = new CookieStore(name, minCust, maxCust, avgCookies);
  stores.push(newStore); // Pushes new store into stores array.

  newStore.cookPerHr();
  newStore.totalCookies();
  newStore.render();
}

for (var i = 0; i < stores.length; i++){
  stores[i].render();
}
//----------------Demo area------------------------V
<|endoftext|>


<commit_before>/*global expect, Square, execSync, sinon, beforeEach, afterEach */
describe('[square] watch API', function () {
  'use strict';

  /**
   * The location of our testing fixtures.
   *
   * @type {String}
   */
  var path = require('path')
    , fs = require('fs')
    , fixtures = path.join(process.env.PWD, 'test/fixtures')
    , expected = path.join(process.env.PWD, 'test/expected')
    , EventEmitter = process.EventEmitter
    , network = require('os')
    , Watch = require('../lib/watch.js')
    , Square= require('../lib/square.js')
    , canihaz = require('canihaz')();

  /**
   * Async helpers.
   */
  var async = require('async');

  /**
   * Simple dummy function that is used for testing.
   *
   * @api private
   */
  function noop() { console.log(/* dummy function*/); }

  it('exposes constructor', function () {
    expect(Watch).to.be.a('function');
  });

  it('Watcher has watch, refresher, defer and live methods, encapsulates square', function () {
    var square = new Square({ 'disable log transport': true });
    square.parse(fixtures +'/read/adeptable.json');

    var watcher = new Watch(square, 8888, true);
    expect(watcher).to.be.a('object');
    expect(watcher).to.have.property('watch');
    expect(watcher).to.have.property('refresher');
    expect(watcher).to.have.property('live');
    expect(watcher).to.have.property('defer');
    expect(watcher).to.have.property('init');
    expect(watcher).to.have.property('socket');
    expect(watcher).to.have.property('silent');
    expect(watcher.watch).to.be.a('function');
    expect(watcher.refresher).to.be.a('function');
    expect(watcher.live).to.be.a('function');
    expect(watcher.defer).to.be.a('function');
    expect(watcher.init).to.be.a('function');
    expect(watcher.socket).to.be.a('object');
    expect(watcher.silent).to.be.a('boolean');
  });

  describe('@construction', function () {
    var square, watcher;

    beforeEach(function () {
      square = new Square({ 'disable log transport': true });
      square.parse(fixtures +'/read/adeptable.json');
    });

    it('attach Square instance as property', function () {
      watcher = new Watch(square, 8888, true);
      expect(watcher).to.have.property('square');
      expect(watcher.square).to.be.a('object');
      expect(watcher.square).to.be.instanceof(Square);
    });

    it('register event listener to trigger on build', function () {
      var build = sinon.spy(square, 'on');
      watcher = new Watch(square, 8888, true);
      expect(build).to.be.calledOnce;
      expect(build).to.be.calledWith('build');
      build.restore();
    });

    it('asynchronously loads required modules for watch', function () {
      var parallel = sinon.spy(async, 'parallel');
      watcher = new Watch(square, 8888, true);
      expect(parallel).to.be.calledOnce;
      parallel.restore();
    });

    it('logging to console can be switched on/off', function () {
      var quiet = new Watch(square, 8888, true)
        , loud = new Watch(square, 8888);

      expect(quiet.silent).to.be.true;
      expect(loud.silent).to.be.false;
    });
  });

  describe('#watch', function () {
    var Notify, findit, square, watcher;

    beforeEach(function (done) {
      this.timeout(30000);

      canihaz(
          { name: 'fs.notify', version: '*' }
        , { name: 'findit', version: '*' }
        , function lazyloading() {
            Notify = arguments[1];
            findit = arguments[2];

            square = new Square({ 'disable log transport': true });
            square.parse(fixtures +'/write/square.json');
            watcher = new Watch(square, 8888, true);

            done();
          }
      );
    });

    it('calls square#files to get a list of files from the bundle', function () {
      var files = sinon.spy(square, 'files');
      watcher.watch(Notify, findit);
      expect(files).to.be.calledOnce;
      files.restore();
    });

    it('constructs fs.notify and supply a list of files');

    it('will emit idle to start the spinner', function (done) {
      var defer = sinon.spy(watcher, 'defer');

      square.once('idle', function () {
        // Only check for calls after the next loop.
        process.nextTick(function () {
          expect(defer).to.be.calledOnce;
          done();
        });
      });

      watcher.watch(Notify, findit);
      defer.restore();
    });

    it('will register event listeners on the notifier');
    it('will remove `node_modules` from the list of files');
    it('will remove `.`directories from the list of files');
    it('will remove output files from the list of files');
    it('adds additional files as configured by extensions in package.json');
    it('calls the #refresher on detected file changes');
  });

  describe('#refresher', function () {
    var square, watcher;

    beforeEach(function () {
      square = new Square({ 'disable log transport': true });
      square.parse(fixtures +'/read/adeptable.json');

      watcher = new Watch(square, 8888, true);
    });

    it('will log an error if watching fails', function () {
      var log = sinon.spy(square.logger, 'error')
        , err = new Error('My fault');

      watcher.refresher(err, []);
      expect(log).to.be.calledOnce;
      expect(log).to.be.calledWith('Watcher error %s, canceling watch operations on %s', err.message, []);

      log.restore();
    });

    it('will emit processing to stop the spinner', function () {
      var process = sinon.spy(square, 'emit');
      watcher.refresher(undefined, ['files']);

      expect(process).to.be.called;
      expect(process).to.be.calledWith('processing');

      process.restore();
    });

    it('will notify changed files if not silenced', function () {
      var log = sinon.spy(square.logger, 'notice')
        , files = ['files.js', 'moar.js'];

      watcher = new Watch(square, 8888);
      watcher.refresher(undefined, files);

      expect(log).to.be.calledOnce;
      expect(log).to.be.calledWith('changes detected, refreshing %s', files.join(', '));

      log.restore();
    });

    it('calls square#refresh to reinitialize a build', function () {
      var refresh = sinon.spy(square, 'refresh')
        , files = ['files.js', 'moar.js'];

      watcher.refresher(undefined, files);

      expect(refresh).to.be.calledOnce;
      expect(refresh).to.be.calledWith(files);

      refresh.restore();
    });
  });

  describe('#live', function () {
    var square, watcher;

    beforeEach(function () {
      square = new Square({ 'disable log transport': true });
      square.parse(fixtures +'/read/adeptable.json');

      watcher = new Watch(square, 8888, true);
    });

    it('gets the static content of reload.js', function () {
      var args = path.join(__dirname, '..', 'static', 'reload.js')
        , file = sinon.spy(fs, 'readFileSync');

      watcher.live(8888);

      expect(file).to.be.called;
      expect(file).to.be.calledWith(args);

      file.restore();
    });

    it('will try to find the local IP of the network to connect to', function () {
      var interf = sinon.spy(network, 'networkInterfaces');

      watcher.live(8888);

      expect(interf).to.be.calledOnce;
      interf.restore();
    });

    it('logs information on how to use browser reloading if not silenced', function () {
      var log = sinon.spy(square.logger, 'info')
        , normal = sinon.spy(console, 'log');

      watcher = new Watch(square, 8888);

      expect(log).to.be.calledThrice;
      expect(log).to.be.calledWith('Live reload is initializing, make sure you have the following script');
      expect(log).to.be.calledWith('included in your webpage to receive the live reloads:');
      expect(log).to.be.calledWith('paste it right above your closing </body> tag.');

      expect(normal).to.be.called;
      expect(normal).to.be.calledWith('  !function(l,i,v,e){');
      expect(normal).to.be.calledWith('    e=l.createElement(i);v=l.getElementsByTagName(i)[0];e.async=true;');
      expect(normal).to.be.calledWith('    v.parentNode.insertBefore(e,v);');
      expect(normal).to.be.calledWith('  }(document,"script");');

      log.restore();
      normal.restore();
    });

    it('exposes the eventemitter as promise', function () {
      var promise = watcher.live(8888);
      expect(promise).to.be.an('object');
      expect(promise).to.be.instanceof(EventEmitter);
    });
  });
});
<commit_msg>[fix] ok ok have more time...<commit_after>/*global expect, Square, execSync, sinon, beforeEach, afterEach */
describe('[square] watch API', function () {
  'use strict';

  /**
   * The location of our testing fixtures.
   *
   * @type {String}
   */
  var path = require('path')
    , fs = require('fs')
    , fixtures = path.join(process.env.PWD, 'test/fixtures')
    , expected = path.join(process.env.PWD, 'test/expected')
    , EventEmitter = process.EventEmitter
    , network = require('os')
    , Watch = require('../lib/watch.js')
    , Square= require('../lib/square.js')
    , canihaz = require('canihaz')();

  /**
   * Async helpers.
   */
  var async = require('async');

  /**
   * Simple dummy function that is used for testing.
   *
   * @api private
   */
  function noop() { console.log(/* dummy function*/); }

  it('exposes constructor', function () {
    expect(Watch).to.be.a('function');
  });

  it('Watcher has watch, refresher, defer and live methods, encapsulates square', function () {
    var square = new Square({ 'disable log transport': true });
    square.parse(fixtures +'/read/adeptable.json');

    var watcher = new Watch(square, 8888, true);
    expect(watcher).to.be.a('object');
    expect(watcher).to.have.property('watch');
    expect(watcher).to.have.property('refresher');
    expect(watcher).to.have.property('live');
    expect(watcher).to.have.property('defer');
    expect(watcher).to.have.property('init');
    expect(watcher).to.have.property('socket');
    expect(watcher).to.have.property('silent');
    expect(watcher.watch).to.be.a('function');
    expect(watcher.refresher).to.be.a('function');
    expect(watcher.live).to.be.a('function');
    expect(watcher.defer).to.be.a('function');
    expect(watcher.init).to.be.a('function');
    expect(watcher.socket).to.be.a('object');
    expect(watcher.silent).to.be.a('boolean');
  });

  describe('@construction', function () {
    var square, watcher;

    beforeEach(function () {
      square = new Square({ 'disable log transport': true });
      square.parse(fixtures +'/read/adeptable.json');
    });

    it('attach Square instance as property', function () {
      watcher = new Watch(square, 8888, true);
      expect(watcher).to.have.property('square');
      expect(watcher.square).to.be.a('object');
      expect(watcher.square).to.be.instanceof(Square);
    });

    it('register event listener to trigger on build', function () {
      var build = sinon.spy(square, 'on');
      watcher = new Watch(square, 8888, true);
      expect(build).to.be.calledOnce;
      expect(build).to.be.calledWith('build');
      build.restore();
    });

    it('asynchronously loads required modules for watch', function () {
      var parallel = sinon.spy(async, 'parallel');
      watcher = new Watch(square, 8888, true);
      expect(parallel).to.be.calledOnce;
      parallel.restore();
    });

    it('logging to console can be switched on/off', function () {
      var quiet = new Watch(square, 8888, true)
        , loud = new Watch(square, 8888);

      expect(quiet.silent).to.be.true;
      expect(loud.silent).to.be.false;
    });
  });

  describe('#watch', function () {
    var Notify, findit, square, watcher;

    beforeEach(function (done) {
      this.timeout(60000);

      canihaz(
          { name: 'fs.notify', version: '*' }
        , { name: 'findit', version: '*' }
        , function lazyloading() {
            Notify = arguments[1];
            findit = arguments[2];

            square = new Square({ 'disable log transport': true });
            square.parse(fixtures +'/write/square.json');
            watcher = new Watch(square, 8888, true);

            done();
          }
      );
    });

    it('calls square#files to get a list of files from the bundle', function () {
      var files = sinon.spy(square, 'files');
      watcher.watch(Notify, findit);
      expect(files).to.be.calledOnce;
      files.restore();
    });

    it('constructs fs.notify and supply a list of files');

    it('will emit idle to start the spinner', function (done) {
      var defer = sinon.spy(watcher, 'defer');

      square.once('idle', function () {
        // Only check for calls after the next loop.
        process.nextTick(function () {
          expect(defer).to.be.calledOnce;
          done();
        });
      });

      watcher.watch(Notify, findit);
      defer.restore();
    });

    it('will register event listeners on the notifier');
    it('will remove `node_modules` from the list of files');
    it('will remove `.`directories from the list of files');
    it('will remove output files from the list of files');
    it('adds additional files as configured by extensions in package.json');
    it('calls the #refresher on detected file changes');
  });

  describe('#refresher', function () {
    var square, watcher;

    beforeEach(function () {
      square = new Square({ 'disable log transport': true });
      square.parse(fixtures +'/read/adeptable.json');

      watcher = new Watch(square, 8888, true);
    });

    it('will log an error if watching fails', function () {
      var log = sinon.spy(square.logger, 'error')
        , err = new Error('My fault');

      watcher.refresher(err, []);
      expect(log).to.be.calledOnce;
      expect(log).to.be.calledWith('Watcher error %s, canceling watch operations on %s', err.message, []);

      log.restore();
    });

    it('will emit processing to stop the spinner', function () {
      var process = sinon.spy(square, 'emit');
      watcher.refresher(undefined, ['files']);

      expect(process).to.be.called;
      expect(process).to.be.calledWith('processing');

      process.restore();
    });

    it('will notify changed files if not silenced', function () {
      var log = sinon.spy(square.logger, 'notice')
        , files = ['files.js', 'moar.js'];

      watcher = new Watch(square, 8888);
      watcher.refresher(undefined, files);

      expect(log).to.be.calledOnce;
      expect(log).to.be.calledWith('changes detected, refreshing %s', files.join(', '));

      log.restore();
    });

    it('calls square#refresh to reinitialize a build', function () {
      var refresh = sinon.spy(square, 'refresh')
        , files = ['files.js', 'moar.js'];

      watcher.refresher(undefined, files);

      expect(refresh).to.be.calledOnce;
      expect(refresh).to.be.calledWith(files);

      refresh.restore();
    });
  });

  describe('#live', function () {
    var square, watcher;

    beforeEach(function () {
      square = new Square({ 'disable log transport': true });
      square.parse(fixtures +'/read/adeptable.json');

      watcher = new Watch(square, 8888, true);
    });

    it('gets the static content of reload.js', function () {
      var args = path.join(__dirname, '..', 'static', 'reload.js')
        , file = sinon.spy(fs, 'readFileSync');

      watcher.live(8888);

      expect(file).to.be.called;
      expect(file).to.be.calledWith(args);

      file.restore();
    });

    it('will try to find the local IP of the network to connect to', function () {
      var interf = sinon.spy(network, 'networkInterfaces');

      watcher.live(8888);

      expect(interf).to.be.calledOnce;
      interf.restore();
    });

    it('logs information on how to use browser reloading if not silenced', function () {
      var log = sinon.spy(square.logger, 'info')
        , normal = sinon.spy(console, 'log');

      watcher = new Watch(square, 8888);

      expect(log).to.be.calledThrice;
      expect(log).to.be.calledWith('Live reload is initializing, make sure you have the following script');
      expect(log).to.be.calledWith('included in your webpage to receive the live reloads:');
      expect(log).to.be.calledWith('paste it right above your closing </body> tag.');

      expect(normal).to.be.called;
      expect(normal).to.be.calledWith('  !function(l,i,v,e){');
      expect(normal).to.be.calledWith('    e=l.createElement(i);v=l.getElementsByTagName(i)[0];e.async=true;');
      expect(normal).to.be.calledWith('    v.parentNode.insertBefore(e,v);');
      expect(normal).to.be.calledWith('  }(document,"script");');

      log.restore();
      normal.restore();
    });

    it('exposes the eventemitter as promise', function () {
      var promise = watcher.live(8888);
      expect(promise).to.be.an('object');
      expect(promise).to.be.instanceof(EventEmitter);
    });
  });
});
<|endoftext|>


<commit_before>import React, { Component, Fragment } from 'react'
import {
  Container,
  Button,
  Box,
  Flex,
  Heading,
  Text,
  Badge
} from '@hackclub/design-system'
import { AutoSaver, Field, Form } from 'components/Forms'
import Login from 'components/apply/Login'
import { Tr, Td, Th } from 'components/Table'
import LoadingAnimation from 'components/LoadingAnimation'
import InterviewForm from 'components/admin/InterviewForm'
import RejectionForm from 'components/admin/RejectionForm'
import AcceptanceForm from 'components/admin/AcceptanceForm'
import Information from 'components/admin/Information'
import NotesForm from 'components/admin/NotesForm'
import ErrorPage from 'components/admin/ErrorPage'
import Nav from 'components/apply/ApplyNav'
import { Formik } from 'formik'
import api from 'api'
import { xor } from 'lodash'

const Arrow = Text.span.extend.attrs({
  children: '❯'
})`
  transform: rotate(${props => (props.active ? 90 : 0)}deg);
  display: inline-block;
  transition: 0.5s ease-in;
`

const Revealer = Box.extend`
  transform: scaleY(${props => (props.active ? 1 : 0)});
  height: ${props => (props.active ? 'auto' : '0%')};
  opacity: ${props => (props.active ? 1 : 0)};
  transition: 0.5s ease-in;
`

const colorMap = {
  unsubmitted: 'gray.3',
  submitted: 'info',
  interviewed: 'accent',
  rejected: 'red.5',
  accepted: 'success'
}

const FilterButton = ({ toggled, status, toggleFilter }) => (
  <Button.button
    mr={2}
    bg={colorMap[status]}
    children={status}
    onClick={() => toggleFilter(status)}
    style={toggled ? null : { opacity: 0.25 }}
  />
)

class Collapsable extends Component {
  constructor(props) {
    super(props)
    this.state = { status: false }
  }

  render() {
    const { status } = this.state
    return (
      <Fragment>
        <Heading.h2
          my={2}
          style={{ cursor: 'pointer' }}
          onClick={() => {
            this.setState({ status: !status })
          }}
        >
          {this.props.heading} <Arrow ml={2} active={status} />
        </Heading.h2>
        <Revealer active={status}>{this.props.children}</Revealer>
      </Fragment>
    )
  }
}

export default class extends Component {
  constructor(props) {
    super(props)
    this.state = {
      status: 'loading',
      filters: ['unsubmitted', 'rejected'],
      clubApplications: {}
    }
    this.updateApplicationList = this.updateApplicationList.bind(this)
    this.toggleFilter = this.toggleFilter.bind(this)
  }

  addAppToList(apps) {
    const { clubApplications } = this.state
    apps.forEach(app => {
      clubApplications[app.id] = app
    })
    this.setState({ clubApplications })
  }

  componentDidMount() {
    api
      .get('v1/new_club_applications?submitted=true')
      .then(apps => {
        this.addAppToList(apps)
        this.setState({ status: 'success' })
      })
      .then(() =>
        api.get('v1/new_club_applications').then(apps => {
          this.addAppToList(apps)
        })
      )
      .catch(e => {
        if (e.status === 401) {
          this.setState({ status: 'needsToAuth' })
        } else {
          this.setState({ status: 'error' })
        }
      })
  }

  updateApplicationList(updatedApplication) {
    const { clubApplications } = this.state
    clubApplications[updatedApplication.id] = updatedApplication

    this.setState({ clubApplications })
  }

  pointOfContact(application) {
    const profile = application.leader_profiles.find(
      profile =>
        profile.user && profile.user.id === application.point_of_contact_id
    )

    return profile && profile.user.email
  }

  active(application, prop) {
    const { selection, selectType } = this.state
    return selection && selection.id === application.id && selectType === prop
  }

  toggleFilter(filter) {
    const { selection, filters } = this.state
    const updatedFilters = xor(filters, [filter])
    this.setState({ filters: updatedFilters })

    // Deselect applications that get filtered out
    if (
      selection &&
      !this.filterApplication(selection, updatedFilters).visible
    ) {
      this.setState({ selection: null })
    }
  }

  filterApplication(application, filters = this.state.filters) {
    let status
    if (application.accepted_at) {
      status = 'accepted'
    } else if (application.rejected_at) {
      status = 'rejected'
    } else if (application.interviewed_at) {
      status = 'interviewed'
    } else if (application.submitted_at) {
      status = 'submitted'
    } else {
      status = 'unsubmitted'
    }

    return {
      visible: filters.indexOf(status) === -1,
      selected: this.state.selection === application,
      color: colorMap[status]
    }
  }

  render() {
    const {
      status,
      clubApplications,
      selection,
      selectType,
      filters
    } = this.state
    switch (status) {
      case 'loading':
        return <LoadingAnimation />
      case 'needsToAuth':
        return <Login userType="admin" />
      case 'success':
        return (
          <Fragment>

            <Container maxwidth={80} p={[3, 4]}>
              <Flex
                flexDirection={['column', 'row']}
                justify="space-between"
                align="center"
                wrap
              >
                <Heading.h1 f={[5, 6]}>Dashboard</Heading.h1>
              </Flex>
              <Heading.h2 color="muted" f={4} mt={2} regular>
                Hello, it’s{' '}
                {new Date().toLocaleDateString('en-us', { weekday: 'long' })}
                {'. '}You’re doing great.
              </Heading.h2>
              <Flex mt={[3, 4]}>
                {Object.keys(colorMap).map((status, index) => (
                  <FilterButton
                    key={index}
                    toggleFilter={this.toggleFilter}
                    status={status}
                    toggled={this.state.filters.indexOf(status) === -1}
                  />
                ))}
              </Flex>
              <Flex justify="center" mt={[3, 4]}>
                <Box w={1} style={{ overflowY: 'scroll', height: '100vh' }}>

                        ID
                        Name
                        POC

                      {Object.values(clubApplications).map(
                        application =>
                          this.filterApplication(application).visible ? (

 {
                                const alreadySelected =
                                  this.state.selection === application

                                this.setState({
                                  selection: alreadySelected
                                    ? undefined
                                    : application,
                                  selectType: 'notes'
                                })
                              }}
                            >

                                <Badge
                                  bg={this.filterApplication(application).color}
                                  children={application.id}
                                />

                              {application.high_school_name}
                              {this.pointOfContact(application)}

                          ) : null
                      )}

                </Box>
                {selection && (
                  <Flex
                    flexDirection="column"
                    flex="1 1 auto"
                    ml={[null, 4]}
                    style={{ minWidth: '18rem' }}
                  >
                    <Text color="muted" f={1} caps mb={3}>
                      Application{' '}
                      <Badge bg={this.filterApplication(selection).color}>
                        {selection.id}
                      </Badge>
                    </Text>
                    <Collapsable heading="Reject">
                      <RejectionForm
                        application={selection}
                        updateApplicationList={this.updateApplicationList}
                      />
                    </Collapsable>
                    <Collapsable heading="Notes">
                      <NotesForm
                        modelId={selection.id}
                        modelType="new_club_applications"
                      />
                    </Collapsable>
                    <Collapsable heading="Interview">
                      <InterviewForm
                        application={selection}
                        updateApplicationList={this.updateApplicationList}
                      />
                    </Collapsable>
                    <Collapsable heading="Application">
                      <Information application={selection} />
                    </Collapsable>
                    <Collapsable heading="Accept">
                      <AcceptanceForm
                        application={selection}
                        updateApplicationList={this.updateApplicationList}
                      />
                    </Collapsable>
                  </Flex>
                )}
              </Flex>
            </Container>
          </Fragment>
        )
      default:
        return <ErrorPage />
    }
  }
}
<commit_msg>Add 'time in stage' to application dashboard<commit_after>import React, { Component, Fragment } from 'react'
import {
  Container,
  Button,
  Box,
  Flex,
  Heading,
  Text,
  Badge
} from '@hackclub/design-system'
import { AutoSaver, Field, Form } from 'components/Forms'
import Login from 'components/apply/Login'
import { Tr, Td, Th } from 'components/Table'
import LoadingAnimation from 'components/LoadingAnimation'
import InterviewForm from 'components/admin/InterviewForm'
import RejectionForm from 'components/admin/RejectionForm'
import AcceptanceForm from 'components/admin/AcceptanceForm'
import Information from 'components/admin/Information'
import NotesForm from 'components/admin/NotesForm'
import ErrorPage from 'components/admin/ErrorPage'
import Nav from 'components/apply/ApplyNav'
import { Formik } from 'formik'
import api from 'api'
import { timeSince } from 'helpers'
import { xor } from 'lodash'

const Arrow = Text.span.extend.attrs({
  children: '❯'
})`
  transform: rotate(${props => (props.active ? 90 : 0)}deg);
  display: inline-block;
  transition: 0.5s ease-in;
`

const Revealer = Box.extend`
  transform: scaleY(${props => (props.active ? 1 : 0)});
  height: ${props => (props.active ? 'auto' : '0%')};
  opacity: ${props => (props.active ? 1 : 0)};
  transition: 0.5s ease-in;
`

const colorMap = {
  unsubmitted: 'gray.3',
  submitted: 'info',
  interviewed: 'accent',
  rejected: 'red.5',
  accepted: 'success'
}

const FilterButton = ({ toggled, status, toggleFilter }) => (
  <Button.button
    mr={2}
    bg={colorMap[status]}
    children={status}
    onClick={() => toggleFilter(status)}
    style={toggled ? null : { opacity: 0.25 }}
  />
)

class Collapsable extends Component {
  constructor(props) {
    super(props)
    this.state = { status: false }
  }

  render() {
    const { status } = this.state
    return (
      <Fragment>
        <Heading.h2
          my={2}
          style={{ cursor: 'pointer' }}
          onClick={() => {
            this.setState({ status: !status })
          }}
        >
          {this.props.heading} <Arrow ml={2} active={status} />
        </Heading.h2>
        <Revealer active={status}>{this.props.children}</Revealer>
      </Fragment>
    )
  }
}

export default class extends Component {
  constructor(props) {
    super(props)
    this.state = {
      status: 'loading',
      filters: ['unsubmitted', 'rejected'],
      clubApplications: {}
    }
    this.updateApplicationList = this.updateApplicationList.bind(this)
    this.toggleFilter = this.toggleFilter.bind(this)
  }

  addAppToList(apps) {
    const { clubApplications } = this.state
    apps.forEach(app => {
      clubApplications[app.id] = app
    })
    this.setState({ clubApplications })
  }

  componentDidMount() {
    api
      .get('v1/new_club_applications?submitted=true')
      .then(apps => {
        this.addAppToList(apps)
        this.setState({ status: 'success' })
      })
      .then(() =>
        api.get('v1/new_club_applications').then(apps => {
          this.addAppToList(apps)
        })
      )
      .catch(e => {
        if (e.status === 401) {
          this.setState({ status: 'needsToAuth' })
        } else {
          this.setState({ status: 'error' })
        }
      })
  }

  updateApplicationList(updatedApplication) {
    const { clubApplications } = this.state
    clubApplications[updatedApplication.id] = updatedApplication

    this.setState({ clubApplications })
  }

  pointOfContact(application) {
    const profile = application.leader_profiles.find(
      profile =>
        profile.user && profile.user.id === application.point_of_contact_id
    )

    return profile && profile.user.email
  }

  active(application, prop) {
    const { selection, selectType } = this.state
    return selection && selection.id === application.id && selectType === prop
  }

  toggleFilter(filter) {
    const { selection, filters } = this.state
    const updatedFilters = xor(filters, [filter])
    this.setState({ filters: updatedFilters })

    // Deselect applications that get filtered out
    if (
      selection &&
      !this.filterApplication(selection, updatedFilters).visible
    ) {
      this.setState({ selection: null })
    }
  }

  filterApplication(application, filters = this.state.filters) {
    let status, updatedAt
    if (application.accepted_at) {
      status = 'accepted'
      updatedAt = timeSince(application.accepted_at)
    } else if (application.rejected_at) {
      status = 'rejected'
      updatedAt = timeSince(application.rejected_at)
    } else if (application.interviewed_at) {
      status = 'interviewed'
      updatedAt = timeSince(application.interviewed_at)
    } else if (application.submitted_at) {
      status = 'submitted'
      updatedAt = timeSince(application.submitted_at)
    } else {
      status = 'unsubmitted'
      updatedAt = timeSince(application.created_at)
    }

    return {
      visible: filters.indexOf(status) === -1,
      selected: this.state.selection === application,
      color: colorMap[status],
      timeInStage: updatedAt
    }
  }

  render() {
    const {
      status,
      clubApplications,
      selection,
      selectType,
      filters
    } = this.state
    switch (status) {
      case 'loading':
        return <LoadingAnimation />
      case 'needsToAuth':
        return <Login userType="admin" />
      case 'success':
        return (
          <Fragment>

            <Container maxwidth={80} p={[3, 4]}>
              <Flex
                flexDirection={['column', 'row']}
                justify="space-between"
                align="center"
                wrap
              >
                <Heading.h1 f={[5, 6]}>Dashboard</Heading.h1>
              </Flex>
              <Heading.h2 color="muted" f={4} mt={2} regular>
                Hello, it’s{' '}
                {new Date().toLocaleDateString('en-us', { weekday: 'long' })}
                {'. '}You’re doing great.
              </Heading.h2>
              <Flex mt={[3, 4]}>
                {Object.keys(colorMap).map((status, index) => (
                  <FilterButton
                    key={index}
                    toggleFilter={this.toggleFilter}
                    status={status}
                    toggled={this.state.filters.indexOf(status) === -1}
                  />
                ))}
              </Flex>
              <Flex justify="center" mt={[3, 4]}>
                <Box w={1} style={{ overflowY: 'scroll', height: '100vh' }}>

                        ID
                        Name
                        POC
                        Time in Stage

                      {Object.values(clubApplications).map(
                        application =>
                          this.filterApplication(application).visible ? (

 {
                                const alreadySelected =
                                  this.state.selection === application

                                this.setState({
                                  selection: alreadySelected
                                    ? undefined
                                    : application,
                                  selectType: 'notes'
                                })
                              }}
                            >

                                <Badge
                                  bg={this.filterApplication(application).color}
                                  children={application.id}
                                />

                              {application.high_school_name}
                              {this.pointOfContact(application)}

                                {
                                  this.filterApplication(application)
                                    .timeInStage
                                }

                          ) : null
                      )}

                </Box>
                {selection && (
                  <Flex
                    flexDirection="column"
                    flex="1 1 auto"
                    ml={[null, 4]}
                    style={{ minWidth: '18rem' }}
                  >
                    <Text color="muted" f={1} caps mb={3}>
                      Application{' '}
                      <Badge bg={this.filterApplication(selection).color}>
                        {selection.id}
                      </Badge>
                    </Text>
                    <Collapsable heading="Reject">
                      <RejectionForm
                        application={selection}
                        updateApplicationList={this.updateApplicationList}
                      />
                    </Collapsable>
                    <Collapsable heading="Notes">
                      <NotesForm
                        modelId={selection.id}
                        modelType="new_club_applications"
                      />
                    </Collapsable>
                    <Collapsable heading="Interview">
                      <InterviewForm
                        application={selection}
                        updateApplicationList={this.updateApplicationList}
                      />
                    </Collapsable>
                    <Collapsable heading="Application">
                      <Information application={selection} />
                    </Collapsable>
                    <Collapsable heading="Accept">
                      <AcceptanceForm
                        application={selection}
                        updateApplicationList={this.updateApplicationList}
                      />
                    </Collapsable>
                  </Flex>
                )}
              </Flex>
            </Container>
          </Fragment>
        )
      default:
        return <ErrorPage />
    }
  }
}
<|endoftext|>


<commit_before>'use strict';
var hours = ['6am ','7am ','8am ','9am ', '10am ', '11am ','12pm ','1pm ', '2pm ', '3pm ','4pm ', '5pm ','6pm ','7pm '];

function Store (name, minCust, maxCust, avCookies){
  this.name = name;
  this.minCust = minCust;
  this.maxCust = maxCust;
  this.avCookies = avCookies;
  this.soldCookies = [];
  this.totalCookieSales = 0;

  this.customersPerHour = function() {
    var number = Math.round(Math.random() * (this.maxCust - this.minCust + 1) + this.minCust);
    return number;
  };
  this.soldCookies = function(){
    this.soldCookies = [];
    this.totalCookieSales = 0;
    for (var i = 0 ; i < hours.length; i++) {
      var hourlyCookieSales = Math.round(this.avCookies * this.customersPerHour());
      this.soldCookies.push(hourlyCookieSales);
      this.totalCookieSales += hourlyCookieSales;
    }
  };
  this.soldCookies();
};

var stAndPike = new Store('1st and Pike',23 ,65 ,6.3);
var seaTac = new Store('SeaTac Airport', 3 ,24, 1.2);
var seattleCenter = new Store('seattleCenter', 11, 38, 3.7);
var capitolHill = new Store('Capitol Hill', 20, 38, 2.3);
var alki = new Store('Alki', 2, 16, 4.6);
var storeNames = [stAndPike, seaTac, seattleCenter, capitolHill, alki];

var makeTable = function() {
  var tableSpot = document.getElementsById('pats-table');
  var tab = document.createElement('table');
  tab.id = ('fish-table');
  tableSpot.appendChild(tab);
};
makeTable();

var makeHeader = function() {
  var salesHeader = document.getElementById('fish-table');
  var headerData = document.createElement('tr');
  headerData.id = 'fishHead';
  salesHeader.appendChild(headerData);
  var noData = document.createElement('td');
  nada.innerText = '';
  headerData.appendChild(noData);
  for (var i = 0; i < hours.length; i++) {
    var open = document.createElement('td');
    open.innerText = hours[i];
    headerData.appendChild(open);
  }
  var endCell = document.createElement('td');
  endCell.innerText = ('Totals!');
  headerData.appendChild(endCell);
  table.appendChild(headerData);
};
makeHeader();

var storeBuilder = function(){
  var makePatsTable = document.getElementById('fishHead');
  for (var i = 0; i < storeNames.length; i++) {
    var firstRow = document.createElement('tr');
    newCell.innerText = storeNames[0];
    firstRow.appendChild(newCell);
  for (var i = 0; i < hours.length; i++) {
    var newCell = document.createElement('td');
    var dataCell = document.createElement('td');
    dataCell.innerText = soldCookies[i];
    firstRow.appendChild(dataCell);
  }

  var totalsCell = document.createElement('td');
  totalsCell.innerText = totalCookieSales;
  firstRow.appendChild(totalCell);
  table.appendChild(firstRow);
};

totalCookieSales = 0;
var makeReport = function(){
  var salesReport = document.getElementById;
  var patsReport = document.createElement('tr');
  salesReport.id = ('pats-table');

    for (var i = 0; i < hours.length; i++) {

      var grandTot = 0;
      hours[i].getElementsById

    }
  }
  makeReport();
};

var makeFooter = function(){
  var tableBottom = document.getElementById('pats-table');
  var footerSpace = document.createElement('tr');
  var totalCell = document.createElement('td');
  totalCell.innerText = ('Daily Totals');
  var overAllTotalCell = document.createElement('td');
  var overAllTotal = 0;
  footerSpace.appendChild(totalCell);
  for (var i = 0; i < hours.length; i++) {
    var totalsByHour = document.createElement('th');
    var allSales = 0;
    for (var j = 0; j < storeNames.length; j++) {
      allSales += storeNames[i].soldCookies[j];
    }
    overAllTotal += allSales;
    overAllTotalCell.innerText = overAllTotal;
    totalsByHour.innerText = allSales;
    footerSpace.appendChild(totalsByHour);
  }
  footerSpace.appendChild(overAllTotalCell);
  tableBottom.appendChild(footerSpace);
};
makeFooter();

var orderForm = document.getElementById('order-form');
orderForm.addEventListener('submit', addNewStore);

function addNewStore(event){
  event.preventDefault();
  var storeNames = form.elements['storeNames'].value;
  var minCust = parsInt(form.elements['minCust'].value);
  var maxCust = parsInt(form.elements['maxCust'].value);
  var avCookies = parsFloat(form.elements['avCookies'].value);
  var newStores = new store(name, minCust, maxCust, avCookies);
  newStores.storeBuilder();
  form.reset();
};
addNewStore();

// var getTable = document.createElement('table');
// var getSales = getElementsByTagName('body')[0];
// getSales.appendChild('table');
// getTable.setAttribute('id', 'table');
// this.makeReport = function(){
//   var salesReport = document.getElementById('header');
//   var storeData = document.createElement('tr');
//   storeData.id = 'report';
//   salesReport.appendChild(storeData);
//   for (var i = 0; i < storeNames.length; i++) {
//     var storeRow = document.createElement('tr');
//     var nameLabel = document.createElement('td');
//     nameLabel.innerText = storeNames[i];
//     salesReport.appendChild(storeRow);
//     this.hourlySales = function(){
//       this.customersPerHour = function() {
//         var number = Math.round(Math.random() * (this.maxCust - this.minCust + 1) + this.minCust);
//         return number;
//       };
//       for (var i = 0 ; i < hours.length; i++) {
//         var hourlyCookieSales = Math.round(this.avCookies * this.customersPerHour());
//         this.soldCookies.push(hourlyCookieSales);
//         this.totalCookieSales += hourlyCookieSales;
//         for (var j = 0; j < this.soldCookies.length; j++) {
//           var numCookiesSold = document.createElement('td');
//           numCookiesSold.innerText = this.soldCookies[j];
//         }
//       }
//     };
//   }
// };
// this.makeReport();
  // var makeReport = function(){
  //   var salesReport = document.getElementById('salesTable');
  //   var tablebody = document.createElement('tr');
  //   salesReport.id = ''
  //
  //
  //   data.innerText = hours;
  //   salesHeader.appendChild(salesTable);
  // };
  //
  // var makeReport = function(){
  //   var salesReport = document.getElementById('salesTable');
  //   var tablebody = document.createElement('tr');
  //   salesReport.id = ''
  //
  //
  //     var TableData = function(){
  //     var placeBody = document.getElementById('salesTable');
  //
  //   }
  // }
  //   var tableLoco = document.getElementById('salesTable');
  //   var locoRow = document.createElement('tr');
  //
  // //   var name = this.name;
  // //   locoRow.id = name;
  // //   locoRow.innerText = name;
  // //   tableLoco.appendChild(locoRow);
  // //   var findName = document.getElementById(name);
  // //   for (var i = 0; i < this.soldCookies.length; i++) {
  // //     var newCell = document.createElement('td');
  // //     var dataText = this.soldCookies[i];
  // //     newCell.innerText = dataText;
  // //     findName.appendChild(newCell);
  // //   }
  // //   var newCell = document.createElement('td');
  // //   var dataText = this.totalCookieSales;
  // //   newCell.innerText = dataText;
  // //   findName.appendChild(newCell);
  // // };
  // // allStores.push(this);
// };
//
//
// var tableHeader = function(){
//   var findTable = document.getElementById('salesTable');
//   var headRow = document.createElement('tr');
//   headRow.id = 'firstRow';
//   findTable.appendChild(headRow);
//   for (var i = 0; i < hours.length; i++) {
//     var makeHeading = document.createElement('th');
//     var headingText = hours[i];
//     makeHeading.innerText = headingText;
//     headRow.appendChild(makeHeading);
//
///
//
// makeTable();
// tableHeader();
// stAndPike.dailySalesReport();
// SeaTac.dailySalesReport();
// seattleCenter.dailySalesReport();
// capitolHill.dailySalesReport();
// Alki.dailySalesReport();
// makeFooter();
//
//
//
// // var makeForm function(){
// //   var placement =  document.getElementsByTagName('form');
// //   var
// // }
// // storeU.dailySalesReport();
// // var newE1 = document.createElement(li);
// // var newText = document.createTextNode(store5.name);
// // newE1.appendChild(newtext);
// // var list = document.getElementsByTagName('ul')[4];
// // position.appendChild(newEl);
// //
// // var body = document.getElementsByTagName('body')[0];
<commit_msg> still working on the totals row<commit_after>'use strict';
var hours = ['6am ','7am ','8am ','9am ', '10am ', '11am ','12pm ','1pm ', '2pm ', '3pm ','4pm ', '5pm ','6pm ','7pm '];

function Store (name, minCust, maxCust, avCookies){
  this.name = name;
  this.minCust = minCust;
  this.maxCust = maxCust;
  this.avCookies = avCookies;
  this.soldCookies = [];
  this.totalCookieSales = 0;

  this.customersPerHour = function() {
    var number = Math.round(Math.random() * (this.maxCust - this.minCust + 1) + this.minCust);
    return number;
  };
  this.soldCookies = function(){
    this.soldCookies = [];
    this.totalCookieSales = 0;
    for (var i = 0 ; i < hours.length; i++) {
      var hourlyCookieSales = Math.round(this.avCookies * this.customersPerHour());
      this.soldCookies.push(hourlyCookieSales);
      this.totalCookieSales += hourlyCookieSales;
    }
  };
  this.soldCookies();
};

var stAndPike = new Store('1st and Pike',23 ,65 ,6.3);
var seaTac = new Store('SeaTac Airport', 3 ,24, 1.2);
var seattleCenter = new Store('seattleCenter', 11, 38, 3.7);
var capitolHill = new Store('Capitol Hill', 20, 38, 2.3);
var alki = new Store('Alki', 2, 16, 4.6);
var storeNames = [stAndPike, seaTac, seattleCenter, capitolHill, alki];

var makeTable = function() {
  var tableSpot = document.getElementsById('pats-table');
  var tab = document.createElement('table');
  tab.id = ('fish-table');
  tableSpot.appendChild(tab);
};
makeTable();

var makeHeader = function() {
  var salesHeader = document.getElementById('fish-table');
  var headerData = document.createElement('tr');
  headerData.id = 'fishHead';
  salesHeader.appendChild(headerData);
  var noData = document.createElement('td');
  nada.innerText = '';
  headerData.appendChild(noData);
  for (var i = 0; i < hours.length; i++) {
    var open = document.createElement('td');
    open.innerText = hours[i];
    headerData.appendChild(open);
  }
  var endCell = document.createElement('td');
  endCell.innerText = ('Totals!');
  headerData.appendChild(endCell);
  table.appendChild(headerData);
};
makeHeader();

var storeBuilder = function(){
  var makePatsTable = document.getElementById('fishHead');
  for (var i = 0; i < storeNames.length; i++) {
    var firstRow = document.createElement('tr');
    newCell.innerText = storeNames[0];
    firstRow.appendChild(newCell);

    for (var i = 0; i < hours.length; i++) {
      var newCell = document.createElement('td');
      var dataCell = document.createElement('td');
      dataCell.innerText = soldCookies[i];
      firstRow.appendChild(dataCell);
    }

    var totalsCell = document.createElement('td');
    totalsCell.innerText = totalCookieSales;
    firstRow.appendChild(totalCell);
    table.appendChild(firstRow);
  };
  totalCookieSales = 0;
  var makeReport = function(){
    var salesReport = document.getElementById;
    var patsReport = document.createElement('tr');

    for (var i = 0; i < hours.length; i++) {
      totalCookieSales
      document.createElement('td'):

        break;
      var grandTot += hours
      .getElementsById;

    }
  }
  makeReport();
};

var makeFooter = function(){
  var tableBottom = document.getElementById('pats-table');
  var footerSpace = document.createElement('tr');
  var totalCell = document.createElement('td');
  totalCell.innerText = ('Daily Totals');
  var overAllTotalCell = document.createElement('td');
  var overAllTotal = 0;
  footerSpace.appendChild(totalCell);
  for (var i = 0; i < hours.length; i++) {
    var totalsByHour = document.createElement('th');
    var allSales = 0;
    for (var j = 0; j < storeNames.length; j++) {
      allSales += storeNames[i].soldCookies[j];
    }
    overAllTotal += allSales;
    overAllTotalCell.innerText = overAllTotal;
    totalsByHour.innerText = allSales;
    footerSpace.appendChild(totalsByHour);
  }
  footerSpace.appendChild(overAllTotalCell);
  tableBottom.appendChild(footerSpace);
};
makeFooter();

var orderForm = document.getElementById('order-form');
orderForm.addEventListener('submit', addNewStore);

function addNewStore(event){
  event.preventDefault();
  var storeNames = form.elements['storeNames'].value;
  var minCust = parsInt(form.elements['minCust'].value);
  var maxCust = parsInt(form.elements['maxCust'].value);
  var avCookies = parsFloat(form.elements['avCookies'].value);
  var newStores = new store(name, minCust, maxCust, avCookies);
  newStores.storeBuilder();
  form.reset();
};
addNewStore();

// var getTable = document.createElement('table');
// var getSales = getElementsByTagName('body')[0];
// getSales.appendChild('table');
// getTable.setAttribute('id', 'table');
// this.makeReport = function(){
//   var salesReport = document.getElementById('header');
//   var storeData = document.createElement('tr');
//   storeData.id = 'report';
//   salesReport.appendChild(storeData);
//   for (var i = 0; i < storeNames.length; i++) {
//     var storeRow = document.createElement('tr');
//     var nameLabel = document.createElement('td');
//     nameLabel.innerText = storeNames[i];
//     salesReport.appendChild(storeRow);
//     this.hourlySales = function(){
//       this.customersPerHour = function() {
//         var number = Math.round(Math.random() * (this.maxCust - this.minCust + 1) + this.minCust);
//         return number;
//       };
//       for (var i = 0 ; i < hours.length; i++) {
//         var hourlyCookieSales = Math.round(this.avCookies * this.customersPerHour());
//         this.soldCookies.push(hourlyCookieSales);
//         this.totalCookieSales += hourlyCookieSales;
//         for (var j = 0; j < this.soldCookies.length; j++) {
//           var numCookiesSold = document.createElement('td');
//           numCookiesSold.innerText = this.soldCookies[j];
//         }
//       }
//     };
//   }
// };
// this.makeReport();
  // var makeReport = function(){
  //   var salesReport = document.getElementById('salesTable');
  //   var tablebody = document.createElement('tr');
  //   salesReport.id = ''
  //
  //
  //   data.innerText = hours;
  //   salesHeader.appendChild(salesTable);
  // };
  //
  // var makeReport = function(){
  //   var salesReport = document.getElementById('salesTable');
  //   var tablebody = document.createElement('tr');
  //   salesReport.id = ''
  //
  //
  //     var TableData = function(){
  //     var placeBody = document.getElementById('salesTable');
  //
  //   }
  // }
  //   var tableLoco = document.getElementById('salesTable');
  //   var locoRow = document.createElement('tr');
  //
  // //   var name = this.name;
  // //   locoRow.id = name;
  // //   locoRow.innerText = name;
  // //   tableLoco.appendChild(locoRow);
  // //   var findName = document.getElementById(name);
  // //   for (var i = 0; i < this.soldCookies.length; i++) {
  // //     var newCell = document.createElement('td');
  // //     var dataText = this.soldCookies[i];
  // //     newCell.innerText = dataText;
  // //     findName.appendChild(newCell);
  // //   }
  // //   var newCell = document.createElement('td');
  // //   var dataText = this.totalCookieSales;
  // //   newCell.innerText = dataText;
  // //   findName.appendChild(newCell);
  // // };
  // // allStores.push(this);
// };
//
//
// var tableHeader = function(){
//   var findTable = document.getElementById('salesTable');
//   var headRow = document.createElement('tr');
//   headRow.id = 'firstRow';
//   findTable.appendChild(headRow);
//   for (var i = 0; i < hours.length; i++) {
//     var makeHeading = document.createElement('th');
//     var headingText = hours[i];
//     makeHeading.innerText = headingText;
//     headRow.appendChild(makeHeading);
//
///
//
// makeTable();
// tableHeader();
// stAndPike.dailySalesReport();
// SeaTac.dailySalesReport();
// seattleCenter.dailySalesReport();
// capitolHill.dailySalesReport();
// Alki.dailySalesReport();
// makeFooter();
//
//
//
// // var makeForm function(){
// //   var placement =  document.getElementsByTagName('form');
// //   var
// // }
// // storeU.dailySalesReport();
// // var newE1 = document.createElement(li);
// // var newText = document.createTextNode(store5.name);
// // newE1.appendChild(newtext);
// // var list = document.getElementsByTagName('ul')[4];
// // position.appendChild(newEl);
// //
// // var body = document.getElementsByTagName('body')[0];
<|endoftext|>


<commit_before>var blessed = require('../');
var fs = require('fs');

var argv = {};

process.argv = process.argv.map(function(arg, i) {
  if (~arg.indexOf('=')) {
    arg = arg.split('=');
    if (/^[0-9.]+$/.test(arg[1])) arg[1] = +arg[1];
    argv[arg[0].replace(/^-+/, '')] = arg[1];
    return;
  }
  if (arg.indexOf('--') === 0) {
    arg = arg.slice(2);
    argv[arg] = true;
    return;
  }
  return arg;
}).filter(Boolean);

var screen = blessed.screen({
  tput: true,
  smartCSR: true,
  dump: __dirname + '/logs/png.log'
});

var box1 = blessed.box({
  parent: screen,
  left: 4,
  top: 3,
  width: 10,
  height: 6,
  border: 'line',
  style: {
    bg: 'green'
  },
  content: fs.readFileSync(__dirname + '/lorem.txt', 'utf8')
});

var box2 = blessed.box({
  parent: screen,
  left: 20,
  top: 8,
  width: 40,
  height: 15,
  border: 'line',
  style: {
    bg: 'green'
  },
  content: fs.readFileSync(__dirname + '/lorem.txt', 'utf8')
});

var file = process.argv[2];
var testImage = __dirname + '/test-image.png';
var spinfox = __dirname + '/spinfox.png';

// XXX I'm not sure of the license of this file,
// so I'm not going to redistribute it in the repo.
var url = 'https://people.mozilla.org/~dolske/apng/spinfox.png';

if (!file) {
  try {
    if (!fs.existsSync(spinfox)) {
      var buf = blessed.png.curl(url);
      fs.writeFileSync(spinfox, buf);
    }
    file = spinfox;
  } catch (e) {
    file = testImage;
  }
}

if (!argv.width && !argv.height && !argv.scale) {
  argv.width = 20;
}

var png = blessed.png({
  parent: screen,
  // border: 'line',
  width: argv.width,
  height: argv.height,
  top: 2,
  left: 0,
  file: file,
  draggable: true,
  scale: argv.scale,
  ascii: argv.ascii,
  optimization: argv.optimization,
  speed: argv.speed
});

screen.render();

screen.key('q', function() {
  process.exit(0);
});

var timeout = setInterval(function() {
  png.left++;
  screen.render();
}, 100);

png.on('mousedown', function() {
  clearInterval(timeout);
});
<commit_msg>minor<commit_after>var blessed = require('../');
var fs = require('fs');

var argv = {};

process.argv = process.argv.map(function(arg, i) {
  if (/^--\w+=/.test(arg)) {
    arg = arg.split('=');
    if (/^[0-9.]+$/.test(arg[1])) arg[1] = +arg[1];
    argv[arg[0].replace(/^--/, '')] = arg[1];
    return;
  }
  if (arg.indexOf('--') === 0) {
    arg = arg.slice(2);
    argv[arg] = true;
    return;
  }
  return arg;
}).filter(Boolean);

var screen = blessed.screen({
  tput: true,
  smartCSR: true,
  dump: __dirname + '/logs/png.log'
});

var box1 = blessed.box({
  parent: screen,
  left: 4,
  top: 3,
  width: 10,
  height: 6,
  border: 'line',
  style: {
    bg: 'green'
  },
  content: fs.readFileSync(__dirname + '/lorem.txt', 'utf8')
});

var box2 = blessed.box({
  parent: screen,
  left: 20,
  top: 8,
  width: 40,
  height: 15,
  border: 'line',
  style: {
    bg: 'green'
  },
  content: fs.readFileSync(__dirname + '/lorem.txt', 'utf8')
});

var file = process.argv[2];
var testImage = __dirname + '/test-image.png';
var spinfox = __dirname + '/spinfox.png';

// XXX I'm not sure of the license of this file,
// so I'm not going to redistribute it in the repo.
var url = 'https://people.mozilla.org/~dolske/apng/spinfox.png';

if (!file) {
  try {
    if (!fs.existsSync(spinfox)) {
      var buf = blessed.png.curl(url);
      fs.writeFileSync(spinfox, buf);
    }
    file = spinfox;
  } catch (e) {
    file = testImage;
  }
}

if (!argv.width && !argv.height && !argv.scale) {
  argv.width = 20;
}

var png = blessed.png({
  parent: screen,
  // border: 'line',
  width: argv.width,
  height: argv.height,
  top: 2,
  left: 0,
  file: file,
  draggable: true,
  scale: argv.scale,
  ascii: argv.ascii,
  optimization: argv.optimization,
  speed: argv.speed
});

screen.render();

screen.key('q', function() {
  process.exit(0);
});

var timeout = setInterval(function() {
  png.left++;
  screen.render();
}, 100);

png.on('mousedown', function() {
  clearInterval(timeout);
});
<|endoftext|>


<commit_before>define(['pex/geom/hem/HEMesh', 'pex/utils/ArrayUtils'], function(HEMesh, ArrayUtils) {

  function selected(o) { return o.selected; }

  function HESelection() {
  }

  HEMesh.prototype.clearVerticesSelection = function() {
    for(var i=0; i<this.vertices.length; i++) {
      this.vertices[i].selected = false;
    }
    return this;
  };

  HEMesh.prototype.clearEdgeSelection = function() {
    for(var i=0; i<this.edges.length; i++) {
      this.edges[i].selected = false;
    }
    return this;
  };

  HEMesh.prototype.clearFaceSelection = function() {
    for(var i=0; i<this.faces.length; i++) {
      this.faces[i].selected = false;
    }
    return this;
  };

  HEMesh.prototype.clearSelection = function() {
    this.clearVerticesSelection();
    this.clearEdgeSelection();
    this.clearFaceSelection();
    return this;
  };

  //repeat until number is satified or there is no vertices left...
  HEMesh.prototype.selectRandomVertices = function(count) {
    count = (count === undefined) ? this.vertices.length/2 : count;
    count = Math.min(count, this.vertices.length);
    if (count <= 1) count = Math.floor(count * this.vertices.length);

    var vertices = this.vertices;
    this.clearSelection();

    function selectVertex(i) { vertices[i].selected = true; }

    var indexList = ArrayUtils.range(0, this.vertices.length);
    indexList = ArrayUtils.shuffled(indexList);
    indexList = ArrayUtils.first(indexList, count);
    indexList.forEach(selectVertex);

    return this;
  };

  //repeat until number is satified or there is no vertices left...
  HEMesh.prototype.selectRandomFaces = function(count) {
    count = (count === undefined) ? this.faces.length/2 : count;
    count = Math.min(count, this.faces.length);
    if (count < 1) count = Math.floor(count * this.faces.length);

    var faces = this.faces;
    this.clearSelection();

    function selectFace(i) { faces[i].selected = true; }

    var indexList = ArrayUtils.range(0, this.faces.length);
    indexList = ArrayUtils.shuffled(indexList);
    indexList = ArrayUtils.first(indexList, count);
    indexList.forEach(selectFace);

    return this;
  };

  HEMesh.prototype.selectAllFaces = function() {
    function selectFace(f) { f.selected = true; }
    this.faces.forEach(selectFace);
    return this;
  };

  HEMesh.prototype.selectFace = function(face) {
    face.selected = true;
    return this;
  }

  HEMesh.prototype.expandVerticesSelectionToFaces = function() {
    this.vertices.filter(selected).forEach(function(vertex) {
      vertex.forEachFace(function(face) {
        face.selected = true;
      });
    });
    return this;
  };

  HEMesh.prototype.expandFaceSelection = function() {
    var neighborsToSelect = [];
    this.getSelectedFaces().forEach(function(face) {
      face.getNeighborFaces().forEach(function(neighborFace) {
        if (neighborsToSelect.indexOf(neighborFace) == -1) neighborsToSelect.push(neighborFace);
      });
    });
    function selectFace(face) { face.selected = true; }
    neighborsToSelect.forEach(selectFace);
    return this;
  };

  HEMesh.prototype.getSelectedVertices = function() {
    return this.vertices.filter(selected);
  };

  HEMesh.prototype.getSelectedFaces = function() {
    return this.faces.filter(selected);
  };

  HEMesh.prototype.hasSelection = function() {
    var selectedVertexCount = this.vertices.filter(selected).length;
    var selectedEdgesCount = this.edges.filter(selected).length;
    var selectedFacesCount = this.faces.filter(selected).length;

    return selectedVertexCount + selectedEdgesCount + selectedFacesCount > 0;
  };

  return HESelection;
});
<commit_msg>HEMesh selection utility functions<commit_after>define(['pex/geom/hem/HEMesh', 'pex/utils/ArrayUtils'], function(HEMesh, ArrayUtils) {

  function selected(o) { return o.selected; }

  function HESelection() {
  }

  HEMesh.prototype.clearVerticesSelection = function() {
    for(var i=0; i<this.vertices.length; i++) {
      this.vertices[i].selected = false;
    }
    return this;
  };

  HEMesh.prototype.clearEdgeSelection = function() {
    for(var i=0; i<this.edges.length; i++) {
      this.edges[i].selected = false;
    }
    return this;
  };

  HEMesh.prototype.clearFaceSelection = function() {
    for(var i=0; i<this.faces.length; i++) {
      this.faces[i].selected = false;
    }
    return this;
  };

  HEMesh.prototype.clearSelection = function() {
    this.clearVerticesSelection();
    this.clearEdgeSelection();
    this.clearFaceSelection();
    return this;
  };

  //repeat until number is satified or there is no vertices left...
  HEMesh.prototype.selectRandomVertices = function(count) {
    count = (count === undefined) ? this.vertices.length/2 : count;
    count = Math.min(count, this.vertices.length);
    if (count <= 1) count = Math.floor(count * this.vertices.length);

    var vertices = this.vertices;
    this.clearSelection();

    function selectVertex(i) { vertices[i].selected = true; }

    var indexList = ArrayUtils.range(0, this.vertices.length);
    indexList = ArrayUtils.shuffled(indexList);
    indexList = ArrayUtils.first(indexList, count);
    indexList.forEach(selectVertex);

    return this;
  };

  //repeat until number is satified or there is no vertices left...
  HEMesh.prototype.selectRandomFaces = function(count) {
    count = (count === undefined) ? this.faces.length/2 : count;
    count = Math.min(count, this.faces.length);
    if (count < 1) count = Math.floor(count * this.faces.length);

    var faces = this.faces;
    this.clearSelection();

    function selectFace(i) { faces[i].selected = true; }

    var indexList = ArrayUtils.range(0, this.faces.length);
    indexList = ArrayUtils.shuffled(indexList);
    indexList = ArrayUtils.first(indexList, count);
    indexList.forEach(selectFace);

    return this;
  };

  HEMesh.prototype.selectAllFaces = function() {
    function selectFace(f) { f.selected = true; }
    this.faces.forEach(selectFace);
    return this;
  };

  HEMesh.prototype.selectFace = function(face) {
    face.selected = true;
    return this;
  }

  HEMesh.prototype.expandVerticesSelectionToFaces = function() {
    this.vertices.filter(selected).forEach(function(vertex) {
      vertex.forEachFace(function(face) {
        face.selected = true;
      });
    });
    return this;
  };

  HEMesh.prototype.expandFaceSelection = function() {
    var neighborsToSelect = [];
    this.getSelectedFaces().forEach(function(face) {
      face.getNeighborFaces().forEach(function(neighborFace) {
        if (neighborsToSelect.indexOf(neighborFace) == -1) neighborsToSelect.push(neighborFace);
      });
    });
    function selectFace(face) { face.selected = true; }
    neighborsToSelect.forEach(selectFace);
    return this;
  };

  HEMesh.prototype.getSelectedVertices = function() {
    return this.vertices.filter(selected);
  };

  HEMesh.prototype.getSelectedFaces = function() {
    return this.faces.filter(selected);
  };

  HEMesh.prototype.hasSelection = function() {
    var selectedVertexCount = this.vertices.filter(selected).length;
    var selectedEdgesCount = this.edges.filter(selected).length;
    var selectedFacesCount = this.faces.filter(selected).length;

    return selectedVertexCount + selectedEdgesCount + selectedFacesCount > 0;
  };

  HEMesh.prototype.selectVerticesBy = function(filter) {
    this.vertices.filter(filter).forEach(function(vert) { vert.selected = true; });
    return this;
  }

  HEMesh.prototype.selectEdgesBy = function(filter) {
    this.edges.filter(filter).forEach(function(v) { edge.selected = true; });
    return this;
  }

  HEMesh.prototype.selectFacesBy = function(filter) {
    this.faces.filter(filter).forEach(function(face) { face.selected = true; });
    return this;
  }

  return HESelection;
});
<|endoftext|>


<commit_before>var path = require('path')
var jsonBuffStream = require('json-multibuffer-stream')
var concat = require('concat-stream')
var buff = require('multibuffer')
var bops = require('bops')
var docUtils = require(path.join(__dirname, '..', '..', 'lib', 'document'))

module.exports.buffToJson = function(test, common) {
  test('buff <-> json', function(t) {
    var test = {'hello': 'world', 'foo': {'bar': '[baz]', 'pizza': [1,2,3]}}
    var columns = Object.keys(test)

    var encoded = jsonBuffStream.encode(test)
    var decoded = jsonBuffStream.decode(columns, encoded).decoded
    decoded.foo = JSON.parse(decoded.foo)
    t.deepEqual(test, decoded, 'encoded/decoded matches')
    t.end()
  })
}

module.exports.rowKeys = function(test, common) {
  test('rowKeys returns correctly formatted keys', function(t) {
    var sep = '\xff'

    var keys = {
      seq: 's',
      data: 'd',
      rev: 'r',
      cur: 'c'
    }

    var a = docUtils.rowKeys(keys, sep, 'foo', '1-abc', '4')
    t.deepEqual(a, { row: 'ÿdÿfooÿ01-abc', seq: 'ÿsÿ04', cur: "ÿcÿfoo" })

    t.end()
  })
}

module.exports.decodeKey = function(test, common) {
  test('decodeKey parses key format correctly', function(t) {
    var key = 'ÿdÿfooÿ01-abc'
    var obj = docUtils.decodeKey(key)
    var expected = {
      _id: 'foo',
      _rev: '1-abc'
    }
    t.deepEqual(obj, expected)
    t.end()
  })
}

module.exports.putJson = function(test, common) {
  test('.put json', function(t) {
    common.getDat(t, function(dat, done) {
      dat.put({"foo": "bar"}, function(err, doc) {
        if (err) throw err
        var cat = dat.createReadStream()

        cat.pipe(concat(function(data) {
          t.equal(data.length, 1)
          t.equal(data[0].foo, "bar")
          setImmediate(done)
        }))
      })
    })
  })
}

module.exports.putJsonPrimary = function(test, common) {
  test('.put json w/ primary key option', function(t) {
    common.getDat(t, function(dat, done) {
      dat.put({"foo": "bar"}, {primary: 'foo'}, function(err, doc) {
        if (err) throw err
        dat.get('bar', function(err, data) {
          t.notOk(err, 'no err')
          t.equal(data.foo, "bar")
          setImmediate(done)
        })
      })
    })
  })
}

module.exports.multiplePutJson = function(test, common) {
  test('.put same json multiple times (random id generation)', function(t) {
    common.getDat(t, function(dat, done) {
      dat.put({"foo": "bar"}, function(err) {
        if (err) throw err
        dat.put({"foo": "bar"}, function(err) {
          if (err) throw err
          var cat = dat.createReadStream()

          cat.pipe(concat(function(data) {
            t.equal(data.length, 2)
            t.equal(data[0].foo, "bar")
            t.equal(data[1].foo, "bar")
            done()
          }))
        })
      })
    })
  })
}

module.exports.putBuff = function(test, common) {
  test('.put buff', function(t) {
    common.getDat(t, function(dat, done) {
      var row = buff.pack([bops.from('bar')])

      dat.put(row, {columns: ['foo']}, function(err) {
        if (err) throw err
        var cat = dat.createReadStream()

        cat.pipe(concat(function(data) {
          t.equal(data.length, 1)
          t.equal(data[0].foo, "bar")
          done()
        }))
      })
    })
  })
}

module.exports.deleteRow = function(test, common) {
  test('delete row', function(t) {
    common.getDat(t, function(dat, done) {
      dat.put({"foo": "bar"}, function(err, doc) {
        if (err) throw err
        dat.delete(doc._id, function(err) {
          t.false(err, 'should delete okay')
          dat.get(doc._id, function(err, doc) {
            t.true(err, 'doc should now be not found')
            t.false(doc, 'doc should be null')
            setTimeout(done, 10) // TODO WHY????
          })
        })
      })
    })
  })
}

module.exports.getAtRev = function(test, common) {
  test('get row at specific rev', function(t) {
    common.getDat(t, function(dat, done) {
      dat.put({"foo": "bar"}, function(err, doc) {
        if (err) throw err
        var rev1 = doc._rev
        doc.pizza = 'taco'
        dat.put(doc, function(err, doc) {
          t.false(err)
          if (!doc) doc = {}
          dat.get(doc._id, {rev: rev1}, function(err, docAtRev) {
            t.false(err, 'no err')
            if (!docAtRev) docAtRev = {}
            t.equal(docAtRev.pizza, undefined, 'doc is version 1')
            setImmediate(done)
          })
        })
      })
    })
  })
}

module.exports.all = function (test, common) {
  module.exports.buffToJson(test, common)
  module.exports.rowKeys(test, common)
  module.exports.decodeKey(test, common)
  module.exports.putJson(test, common)
  module.exports.putJsonPrimary(test, common)
  module.exports.multiplePutJson(test, common)
  module.exports.putBuff(test, common)
  module.exports.deleteRow(test, common)
  module.exports.getAtRev(test, common)
}
<commit_msg>failing test for put rev conflict<commit_after>var path = require('path')
var jsonBuffStream = require('json-multibuffer-stream')
var concat = require('concat-stream')
var buff = require('multibuffer')
var bops = require('bops')
var docUtils = require(path.join(__dirname, '..', '..', 'lib', 'document'))

module.exports.buffToJson = function(test, common) {
  test('buff <-> json', function(t) {
    var test = {'hello': 'world', 'foo': {'bar': '[baz]', 'pizza': [1,2,3]}}
    var columns = Object.keys(test)

    var encoded = jsonBuffStream.encode(test)
    var decoded = jsonBuffStream.decode(columns, encoded).decoded
    decoded.foo = JSON.parse(decoded.foo)
    t.deepEqual(test, decoded, 'encoded/decoded matches')
    t.end()
  })
}

module.exports.rowKeys = function(test, common) {
  test('rowKeys returns correctly formatted keys', function(t) {
    var sep = '\xff'

    var keys = {
      seq: 's',
      data: 'd',
      rev: 'r',
      cur: 'c'
    }

    var a = docUtils.rowKeys(keys, sep, 'foo', '1-abc', '4')
    t.deepEqual(a, { row: 'ÿdÿfooÿ01-abc', seq: 'ÿsÿ04', cur: "ÿcÿfoo" })

    t.end()
  })
}

module.exports.decodeKey = function(test, common) {
  test('decodeKey parses key format correctly', function(t) {
    var key = 'ÿdÿfooÿ01-abc'
    var obj = docUtils.decodeKey(key)
    var expected = {
      _id: 'foo',
      _rev: '1-abc'
    }
    t.deepEqual(obj, expected)
    t.end()
  })
}

module.exports.putJson = function(test, common) {
  test('.put json', function(t) {
    common.getDat(t, function(dat, done) {
      dat.put({"foo": "bar"}, function(err, doc) {
        if (err) throw err
        var cat = dat.createReadStream()

        cat.pipe(concat(function(data) {
          t.equal(data.length, 1)
          t.equal(data[0].foo, "bar")
          setImmediate(done)
        }))
      })
    })
  })
}

module.exports.putJsonPrimary = function(test, common) {
  test('.put json w/ primary key option', function(t) {
    common.getDat(t, function(dat, done) {
      dat.put({"foo": "bar"}, {primary: 'foo'}, function(err, doc) {
        if (err) throw err
        dat.get('bar', function(err, data) {
          t.notOk(err, 'no err')
          t.equal(data.foo, "bar")
          setImmediate(done)
        })
      })
    })
  })
}

module.exports.updateJson = function(test, common) {
  test('.put and then update json', function(t) {
    common.getDat(t, function(dat, done) {
      dat.put({"_id": "foo"}, function(err, doc) {
        if (err) throw err
        t.ok(doc._rev, 'should return doc w/ rev')
        dat.put({"_id": "foo"}, function(err, doc2) {
          t.ok(err, 'should err')
          t.notOk(doc2, "should not return data")
          dat.put(doc, function(err, doc3) {
            t.notOk(err, 'no err')
            t.equals(doc._rev[0], '2', 'should be at rev 2')
            setImmediate(done)
          })
        })
      })
    })
  })
}

module.exports.multiplePutJson = function(test, common) {
  test('.put same json multiple times (random id generation)', function(t) {
    common.getDat(t, function(dat, done) {
      dat.put({"foo": "bar"}, function(err) {
        if (err) throw err
        dat.put({"foo": "bar"}, function(err) {
          if (err) throw err
          var cat = dat.createReadStream()

          cat.pipe(concat(function(data) {
            t.equal(data.length, 2)
            t.equal(data[0].foo, "bar")
            t.equal(data[1].foo, "bar")
            done()
          }))
        })
      })
    })
  })
}

module.exports.putBuff = function(test, common) {
  test('.put buff', function(t) {
    common.getDat(t, function(dat, done) {
      var row = buff.pack([bops.from('bar')])

      dat.put(row, {columns: ['foo']}, function(err) {
        if (err) throw err
        var cat = dat.createReadStream()

        cat.pipe(concat(function(data) {
          t.equal(data.length, 1)
          t.equal(data[0].foo, "bar")
          done()
        }))
      })
    })
  })
}

module.exports.deleteRow = function(test, common) {
  test('delete row', function(t) {
    common.getDat(t, function(dat, done) {
      dat.put({"foo": "bar"}, function(err, doc) {
        if (err) throw err
        dat.delete(doc._id, function(err) {
          t.false(err, 'should delete okay')
          dat.get(doc._id, function(err, doc) {
            t.true(err, 'doc should now be not found')
            t.false(doc, 'doc should be null')
            setTimeout(done, 10) // TODO WHY????
          })
        })
      })
    })
  })
}

module.exports.getAtRev = function(test, common) {
  test('get row at specific rev', function(t) {
    common.getDat(t, function(dat, done) {
      dat.put({"foo": "bar"}, function(err, doc) {
        if (err) throw err
        var rev1 = doc._rev
        doc.pizza = 'taco'
        dat.put(doc, function(err, doc) {
          t.false(err)
          if (!doc) doc = {}
          dat.get(doc._id, {rev: rev1}, function(err, docAtRev) {
            t.false(err, 'no err')
            if (!docAtRev) docAtRev = {}
            t.equal(docAtRev.pizza, undefined, 'doc is version 1')
            setImmediate(done)
          })
        })
      })
    })
  })
}

module.exports.all = function (test, common) {
  module.exports.buffToJson(test, common)
  module.exports.rowKeys(test, common)
  module.exports.decodeKey(test, common)
  module.exports.putJson(test, common)
  module.exports.putJsonPrimary(test, common)
  module.exports.updateJson(test, common)
  module.exports.multiplePutJson(test, common)
  module.exports.putBuff(test, common)
  module.exports.deleteRow(test, common)
  module.exports.getAtRev(test, common)
}
<|endoftext|>