<commit_before>var React = require('react');
var _ = require('lodash');
var ReactPropTypes = React.PropTypes;
var PillSelector = require('./PillSelector.react');
var QBerModal = require('./QBerModal.react');
var Caret = require('./Caret.react');

function findByURI(source, uri) {
    return source.filter(function( obj ) {
        return obj.uri === uri;
    })[ 0 ];
}

var ValueDefinitionTable = React.createClass({

  // This React class only works if a list of 'values' is passed through its properties.
  propTypes: {
    variable: ReactPropTypes.object.isRequired,
    schemes: ReactPropTypes.array.isRequired
  },

  getInitialState: function() {
    return {
      'visible': true,
      'modal_visible': false,
      'selected_value_uri': undefined,
      'selected_value_label': undefined
    };
  },

  /**
   * @return {object}
   */
  render: function() {

    // This section should be hidden by default
    // and shown when we do have variables in our dataset
    if (this.props.variable.values === undefined || this.props.variable.values.length < 1) {
      return null;
    }

    var table;
    if (this.state.visible) {
      var values = this.props.variable.values;
      var values_rows = [];

      // The button is enabled if there's a variable, and the variable is of category community or coded
      var button_disabled = (this.props.variable && (this.props.variable.category == 'community' || this.props.variable.category == 'coded' )) ? false: true;

      for (var key in values) {

        var mapping;
        if(this.props.variable.category !== 'other'){
          // If we're dealing with a coded or identity variable, we need to show the URI
          var mapped_uri = values[key].uri;
          var mapped_uri_icon;
          if (mapped_uri){
            mapped_uri_icon = ;
          }
          var browse_mapped_uri;
          if (mapped_uri){
            browse_mapped_uri = "http://data.clariah-sdh.eculture.labs.vu.nl/browse?uri="+encodeURIComponent(mapped_uri);
          }

          mapping =

                          {mapped_uri_icon}

                            {mapped_uri}

;
        } else {
          // Otherwise, we show the 'literal' value for the variable
          mapping =

                      {values[key].label}

;
        }

        values_rows.push(

                            { values[key].label }

                            { mapping }

                             { values[key].count }

);
      }

      var modal;
      // We only prepare the modal if we have a community or coded variable
      if (this.props.variable && (this.props.variable.category == 'community' || this.props.variable.category == 'coded' )){
        var title = Select corresponding code for {this.state.selected_value_label};

        var scheme = _.find(this.props.schemes, {'uri': this.props.variable.codelist.uri});

        var sorted_values;
        // If we have a stored scheme, sort the concepts by label
        if(scheme !== undefined) {

          sorted_values = _.sortBy(scheme.concepts,'label');
        } else {
          // Otherwise, we simply sort the values of the variable (i.e. the defaults)
          sorted_values = _.sortBy(this.props.variable.values,'label');
        }

        // Codelist present
        modal = <QBerModal visible={this.state.modal_visible}
                   title={title}
                   value={this.state.selected_value_label}
                   selection={this.state.selected_value_uri}
                   options={sorted_values}
                   doSelect={this._handleSelected}
                   doClose={this._handleToggleModal} />;

      }

      table =

                    {values_rows}

                {modal}

;
    }

    return (

              Frequency Table
              <Caret visible={this.state.visible}/>

              {table}

    );
  },

  _filter: function(option){
    return (option.label.search(regexp) > -1) ? '': (option.uri.search(regexp) > -1) ? '': 'none';
  },

  _handleSelected: function(code_uri){
    // The code uri is the selected uri in the QBerModal PillSelector.

    // values is the list of code values for this variable
    var values = this.props.variable.values;
    // The selected code value, is the currently visible code value
    var selected_value_uri = this.state.selected_value_uri;

    // Get the index of the selected code value, and increment it by 1 (the next code value)
    var next_index = _.findIndex(values, 'uri', this.state.selected_value_uri) + 1;

    // Set index to 0 if the resulting index is outside the values array (looping)
    if (next_index == values.length){
      next_index = 0;
    }

    // Copy the current state
    var new_state = this.state;
    // Set the selected code value to the next id in the values array (i.e. the code at the next index)
    new_state.selected_value_uri = values[next_index].uri;
    new_state.selected_value_label = values[next_index].label;
    // Update the state
    this.setState(new_state);

    // Call the externally defined function that handles the mappings between (external) values and the source values.
    this.props.doMapping(selected_value_uri, code_uri);
  },

  _handleSelectValue: function(e){
    var new_state = this.state;

    new_state.selected_value_label = e.currentTarget.getAttribute('label');
    new_state.selected_value_uri = _.find(this.props.variable.values, 'label', new_state.selected_value_label).uri;

    this.setState(new_state);
    this._handleToggleModal()
  },

  _handleToggleModal: function(){
    var new_state = this.state;
    new_state.modal_visible = !this.state.modal_visible;

    this.setState(new_state);
  },

  /**
   * Event handler for the visible/invisible click
   */
  _onToggle: function() {
    var new_state = this.state;
    new_state.visible = !this.state.visible;
    this.setState(new_state);
  },
});

module.exports = ValueDefinitionTable;
<commit_msg>Value definition table now correctly distinguishes between original values and mappings<commit_after>var React = require('react');
var _ = require('lodash');
var ReactPropTypes = React.PropTypes;
var PillSelector = require('./PillSelector.react');
var QBerModal = require('./QBerModal.react');
var Caret = require('./Caret.react');

function findByURI(source, uri) {
    return source.filter(function( obj ) {
        return obj.uri === uri;
    })[ 0 ];
}

var ValueDefinitionTable = React.createClass({

  // This React class only works if a list of 'values' is passed through its properties.
  propTypes: {
    variable: ReactPropTypes.object.isRequired,
    schemes: ReactPropTypes.array.isRequired
  },

  getInitialState: function() {
    return {
      'visible': true,
      'modal_visible': false,
      'selected_value_uri': undefined,
      'selected_value_label': undefined
    };
  },

  /**
   * @return {object}
   */
  render: function() {

    // This section should be hidden by default
    // and shown when we do have variables in our dataset
    if (this.props.variable.values === undefined || this.props.variable.values.length < 1) {
      return null;
    }

    var table;
    if (this.state.visible) {
      var values = this.props.variable.values;
      var values_rows = [];

      // The button is enabled if there's a variable, and the variable is of category community or coded
      var button_disabled = (this.props.variable && (this.props.variable.category == 'community' || this.props.variable.category == 'coded' )) ? false: true;

      for (var key in values) {

        var mapping;
        if(this.props.variable.category !== 'other'){
          // If we're dealing with a coded or identity variable, we need to show the URI
          var mapped_uri = values[key].uri;
          var mapped_uri_icon;
          if (mapped_uri){
            mapped_uri_icon = ;
          }
          var browse_mapped_uri;
          if (mapped_uri){
            browse_mapped_uri = "http://data.clariah-sdh.eculture.labs.vu.nl/browse?uri="+encodeURIComponent(mapped_uri);
          }

          mapping =

                          {mapped_uri_icon}

                            {mapped_uri}

;
        } else {
          // Otherwise, we show the 'literal' value for the variable
          mapping =

                      {values[key].label}

;
        }

        values_rows.push(

                            { values[key].original.label }

                            { mapping }

                             { values[key].count }

);
      }

      var modal;
      // We only prepare the modal if we have a community or coded variable
      if (this.props.variable && (this.props.variable.category == 'community' || this.props.variable.category == 'coded' )){
        var title = Select corresponding code for {this.state.selected_value_label};

        var scheme = _.find(this.props.schemes, {'uri': this.props.variable.codelist.uri});

        var sorted_values;
        // If we have a stored scheme, sort the concepts by label
        if(scheme !== undefined) {

          sorted_values = _.sortBy(scheme.concepts,'label');
        } else {
          // Otherwise, we simply sort the values of the variable (i.e. the defaults)
          sorted_values = _.sortBy(this.props.variable.values,'label');
        }

        // Codelist present
        modal = <QBerModal visible={this.state.modal_visible}
                   title={title}
                   value={this.state.selected_value_label}
                   selection={this.state.selected_value_uri}
                   options={sorted_values}
                   doSelect={this._handleSelected}
                   doClose={this._handleToggleModal} />;

      }

      table =

                    {values_rows}

                {modal}

;
    }

    return (

              Frequency Table
              <Caret visible={this.state.visible}/>

              {table}

    );
  },

  _filter: function(option){
    return (option.label.search(regexp) > -1) ? '': (option.uri.search(regexp) > -1) ? '': 'none';
  },

  _handleSelected: function(code_uri){
    // The code uri is the selected uri in the QBerModal PillSelector.

    // values is the list of code values for this variable
    var values = this.props.variable.values;
    // The selected code value, is the currently visible code value
    var selected_value_uri = this.state.selected_value_uri;

    // Get the index of the selected code value, and increment it by 1 (the next code value)
    var next_index = _.findIndex(values, 'uri', this.state.selected_value_uri) + 1;

    // Set index to 0 if the resulting index is outside the values array (looping)
    if (next_index == values.length){
      next_index = 0;
    }

    // Copy the current state
    var new_state = this.state;
    // Set the selected code value to the next id in the values array (i.e. the code at the next index)
    new_state.selected_value_uri = values[next_index].uri;
    new_state.selected_value_label = values[next_index].label;
    // Update the state
    this.setState(new_state);

    // Call the externally defined function that handles the mappings between (external) values and the source values.
    this.props.doMapping(selected_value_uri, code_uri);
  },

  _handleSelectValue: function(e){
    var new_state = this.state;

    new_state.selected_value_label = e.currentTarget.getAttribute('label');
    new_state.selected_value_uri = _.find(this.props.variable.values, 'label', new_state.selected_value_label).uri;

    this.setState(new_state);
    this._handleToggleModal()
  },

  _handleToggleModal: function(){
    var new_state = this.state;
    new_state.modal_visible = !this.state.modal_visible;

    this.setState(new_state);
  },

  /**
   * Event handler for the visible/invisible click
   */
  _onToggle: function() {
    var new_state = this.state;
    new_state.visible = !this.state.visible;
    this.setState(new_state);
  },
});

module.exports = ValueDefinitionTable;
<|endoftext|>


<commit_before>var ajax = require('../../ajax')
var adminUrls = require('../../admin-urls')
var browser = require('../../browser')
var cookies = require('../../cookies')
var BaseViewModel = require('../BaseViewModel')
var ko = require('knockout')
var forEach = require('lodash/collection/forEach')

var ListVolunteersModel = function () {
  var self = this

  self.volunteers = ko.observableArray()

  browser.loading()

  var endpoint = self.endpointBuilder.volunteers().build()
  var headers = self.headers(cookies.get('session-token'))

  ajax
    .get(endpoint, headers)
    .then(function (success) {
      var volunteers = success.data
      forEach(volunteers, function (v) {
        v.contactUrl = adminUrls.contactVolunteer + '?id=' + v.id
      })
      self.volunteers(volunteers)
      browser.loaded()
    }, function (error) {
      self.handleServerError(error)
    })
}

ListVolunteersModel.prototype = new BaseViewModel()

module.exports = ListVolunteersModel
<commit_msg>removing lodash<commit_after>var ajax = require('../../ajax')
var adminUrls = require('../../admin-urls')
var browser = require('../../browser')
var cookies = require('../../cookies')
var BaseViewModel = require('../BaseViewModel')
var ko = require('knockout')

var ListVolunteersModel = function () {
  var self = this

  self.volunteers = ko.observableArray()

  browser.loading()

  var endpoint = self.endpointBuilder.volunteers().build()
  var headers = self.headers(cookies.get('session-token'))

  ajax
    .get(endpoint, headers)
    .then(function (success) {
      var volunteers = success.data
      volunteers.forEach(v => v.contactUrl = adminUrls.contactVolunteer + '?id=' + v.id)
      self.volunteers(volunteers)
      browser.loaded()
    }, function (error) {
      self.handleServerError(error)
    })
}

ListVolunteersModel.prototype = new BaseViewModel()

module.exports = ListVolunteersModel
<|endoftext|>


<commit_before>const _              = require("lodash");
const Promise        = require('bluebird');
const sinon          = require('sinon');
const sinonChai      = require("sinon-chai");
const chai           = require('chai');
const chaiAsPromised = require('chai-as-promised');
const couchbase      = require('couchbase').Mock;

const ODM = require('../../index.js');

//this makes sinon-as-promised available in sinon:
require('sinon-as-promised');

chai.use(sinonChai);
chai.use(chaiAsPromised);
chai.should();

const assert = sinon.assert;
const expect = chai.expect;

function defineModel(name, options) {
    options = options || {};

    this.Client = this.odm.define(name, {
        type: 'object',
        schema: {
            name: {
                type: 'string'
            }
        }
    }, {
        timestamps: options.timestamps,
        paranoid: options.paranoid,
        indexes: {
            refDocs: {
                name: {
                    keys: ['name']
                }
            }
        }
    });
}

describe('CRUD operations', function() {
    before('Initialize bucket & Build Models', function() {
        var cluster = new couchbase.Cluster();
        this.bucket = cluster.openBucket('crud');
        this.odm = new ODM({bucket: this.bucket});
    });

    describe('no timestamps', function() {

        before(function() {
            return defineModel.call(this, 'Client');
        });

        after(function() {
            this.odm.Model.validator.removeSchema(/.*/);
        });

        return defineTests();
    });

    describe('with timestamps=true', function() {

        before(function() {
            return defineModel.call(this, 'Client2', {timestamps: true});
        });

        after(function() {
            this.odm.Model.validator.removeSchema(/.*/);
        });

        return defineTests();
    });

    describe('with paranoid=true', function() {

        before(function() {
            return defineModel.call(this, 'Client3', {paranoid: true});
        });

        after(function() {
            this.odm.Model.validator.removeSchema(/.*/);
        });

        return defineTests();
    });

});

function defineTests() {
    describe('create & get', function() {
        before(function() {
            this.id = '92d64e03-bde9-4e9b-9ff5-29a01ed5dc27';
        });

        it('should `create` document with eplicitly provided id value', function() {
            return this.Client.create({
                name: 'test'
            }, {
                key: this.id
            }).should.be.fulfilled;
        });

        it('should `getByIdOrFail` previosly created Client doc by its id and not fail!', function() {
            return this.Client.getByIdOrFail(this.id).should.be.fulfilled;
        });
    });

    describe('update', function() {
        before(function() {
            this.Client.beforeUpdate(function(client, options) {
                client.setData('name', 'changed_in_before_update_hook');
            }, 'beforeUpdate');

            return this.Client.create({name: 'test2'}).bind(this).then(function(client) {
                this.client = client;
            });
        });

        after(function() {
            this.Client.removeHook('beforeUpdate', 'beforeUpdate');
        });

        it('should update document with data mutations applied in `beforeUpdate` hook', function() {
            return this.client.update({name: 'test2_updated'}).then(function(client) {
                var nameValueBeforeRefresh = client.getData('name');
                return client.refresh().then(function(client) {
                    client.getData('name').should.be.equal('changed_in_before_update_hook');
                    nameValueBeforeRefresh.should.be.equal('changed_in_before_update_hook');
                });
            });
        });
    });

    describe('touch', function() {
        before(function() {
            return this.Client.create({name: 'touch'}).bind(this).then(function(client) {
                this.client = client;
            });
        });

        it('should touch the client document and all its reference documents', function() {
            return this.client.touch(10).bind(this).then(function() {
                var key = this.client.getKey().toString();
                var refDocKey = this.Client.buildRefDocKey('touch', {index: 'name'}).toString();
                var keys = [key, refDocKey];

                keys.forEach(function(key) {
                    this.bucket.storage.items[key][key]
                        .should.have.property('expiry').that.is.instanceof(Date);
                }, this);
            });
        });

        it('should return self (Document instance object)', function() {
            return this.client.touch(10).bind(this).then(function(returnValue) {
                returnValue.should.be.equal(this.client);
            });
        });
    });

    describe('destroy', function() {
        before(function() {
            return this.Client.create({name: 'destroy'}).bind(this).then(function(client) {
                this.client = client;
            });
        });

        it('should destroy the client document and all its reference documents', function() {
            let message = /key not found/;

            return this.client.destroy().bind(this).then(function() {
                return this.client.getRefDocs();
            }).map(function(refDoc) {
                return refDoc.refresh().should.be.rejectedWith(ODM.errors.StorageError, message);
            }).then(function() {
                if (this.Client.options.paranoid) {
                    this.client.deleted_at.should.be.a('string');
                    return this.client.refresh();
                } else {
                    return this.client.refresh().should.be.rejectedWith(ODM.errors.StorageError, message);
                }
            });
        });
    });
}
<commit_msg>more tests<commit_after>const _              = require("lodash");
const Promise        = require('bluebird');
const sinon          = require('sinon');
const sinonChai      = require("sinon-chai");
const chai           = require('chai');
const chaiAsPromised = require('chai-as-promised');
const couchbase      = require('couchbase').Mock;

const ODM = require('../../index.js');

//this makes sinon-as-promised available in sinon:
require('sinon-as-promised');

chai.use(sinonChai);
chai.use(chaiAsPromised);
chai.should();

const assert = sinon.assert;
const expect = chai.expect;

function defineModel(name, options) {
    options = options || {};

    this.Client = this.odm.define(name, {
        type: 'object',
        properties: {
            name: {
                type: 'string'
            }
        }
    }, {
        timestamps: options.timestamps,
        paranoid: options.paranoid,
        indexes: {
            refDocs: {
                name: {
                    keys: ['name']
                }
            }
        }
    });
}

describe('CRUD operations', function() {
    before('Initialize bucket & Build Models', function() {
        var cluster = new couchbase.Cluster();
        this.bucket = cluster.openBucket('crud');
        this.odm = new ODM({bucket: this.bucket});
    });

    describe('no timestamps', function() {

        before(function() {
            return defineModel.call(this, 'Client');
        });

        after(function() {
            this.odm.Model.validator.removeSchema(/.*/);
        });

        return defineTests();
    });

    describe('with timestamps=true', function() {

        before(function() {
            return defineModel.call(this, 'Client2', {timestamps: true});
        });

        after(function() {
            this.odm.Model.validator.removeSchema(/.*/);
        });

        return defineTests();
    });

    describe('with paranoid=true', function() {

        before(function() {
            return defineModel.call(this, 'Client3', {paranoid: true});
        });

        after(function() {
            this.odm.Model.validator.removeSchema(/.*/);
        });

        return defineTests();
    });

});

function defineTests() {
    describe('create & get', function() {
        before(function() {
            this.id = '92d64e03-bde9-4e9b-9ff5-29a01ed5dc27';
        });

        it('should `create` document with eplicitly provided id value', function() {
            return this.Client.create({
                name: 'test'
            }, {
                key: this.id
            }).should.be.fulfilled;
        });

        it('should `getByIdOrFail` previosly created Client doc by its id and not fail!', function() {
            return this.Client.getByIdOrFail(this.id).should.be.fulfilled;
        });

        it('should fail when we try to save invalid data', function() {
            return this.Client.create({
                name: {invalid: 'data'} //invalid
            }).should.be.rejectedWith(ODM.errors.ValidationError);
        });
    });

    describe('update', function() {
        before(function() {
            this.Client.beforeUpdate(function(client, options) {
                client.setData('name', 'changed_in_before_update_hook');
            }, 'beforeUpdate');

            return this.Client.create({name: 'test2'}).bind(this).then(function(client) {
                this.client = client;
            });
        });

        after(function() {
            this.Client.removeHook('beforeUpdate', 'beforeUpdate');
        });

        it('should update document with data mutations applied in `beforeUpdate` hook', function() {
            return this.client.update({name: 'test2_updated'}).then(function(client) {
                var nameValueBeforeRefresh = client.getData('name');
                return client.refresh().then(function(client) {
                    client.getData('name').should.be.equal('changed_in_before_update_hook');
                    nameValueBeforeRefresh.should.be.equal('changed_in_before_update_hook');
                });
            });
        });
    });

    describe('touch', function() {
        before(function() {
            return this.Client.create({name: 'touch'}).bind(this).then(function(client) {
                this.client = client;
            });
        });

        it('should touch the client document and all its reference documents', function() {
            return this.client.touch(10).bind(this).then(function() {
                var key = this.client.getKey().toString();
                var refDocKey = this.Client.buildRefDocKey('touch', {index: 'name'}).toString();
                var keys = [key, refDocKey];

                keys.forEach(function(key) {
                    this.bucket.storage.items[key][key]
                        .should.have.property('expiry').that.is.instanceof(Date);
                }, this);
            });
        });

        it('should return self (Document instance object)', function() {
            return this.client.touch(10).bind(this).then(function(returnValue) {
                returnValue.should.be.equal(this.client);
            });
        });
    });

    describe('destroy', function() {
        before(function() {
            return this.Client.create({name: 'destroy'}).bind(this).then(function(client) {
                this.client = client;
            });
        });

        it('should destroy the client document and all its reference documents', function() {
            let message = /key not found/;

            return this.client.destroy().bind(this).then(function() {
                return this.client.getRefDocs();
            }).map(function(refDoc) {
                return refDoc.refresh().should.be.rejectedWith(ODM.errors.StorageError, message);
            }).then(function() {
                if (this.Client.options.paranoid) {
                    this.client.deleted_at.should.be.a('string');
                    return this.client.refresh();
                } else {
                    return this.client.refresh().should.be.rejectedWith(ODM.errors.StorageError, message);
                }
            });
        });
    });
}
<|endoftext|>


<commit_before>/* eslint-disable max-len */

import test from 'ava';
import execute from 'execa';
import fs from 'fs-promise';
import removeDir from 'rimraf-promise';

const command = '../dist/cli.js';

test.afterEach(async function() {
  await removeDir('output');
});

test('non-existent template should cause error', async (t) => {
  const commandArguments = ['-s', 'monokai', '-t', 'foo'];
  const {stderr: actual} = await execute(command, commandArguments);

  t.ok(/^Could not find a template called/.test(actual));
  t.ok(/goo.gl\/6c8djV$/.test(actual));
});

test('templates with special name should cause error', async (t) => {
  const templs = ['schemes', 'templates'];
  for (const templ of templs) {
    const commandArguments = ['-s', 'monokai', '-t', templ];
    const {stderr: actual} = await execute(command, commandArguments);

    t.ok(/^Could not find a template called/.test(actual));
    t.ok(/goo.gl\/6c8djV$/.test(actual));
  }
});

test('non-existent scheme should cause error', async (t) => {
  const commandArguments = ['-s', 'bar', '-t', 'i3wm'];
  const {stderr: actual} = await execute(command, commandArguments);

  t.ok(/^Could not find a scheme called/.test(actual));
  t.ok(/goo.gl\/ntnS1I$/.test(actual));
});

test('schemes with special name should cause error', async (t) => {
  const schemes = ['schemes', 'templates'];
  for (const scheme of schemes) {
    const commandArguments = ['-s', scheme, '-t', 'i3wm'];
    const {stderr: actual} = await execute(command, commandArguments);

    t.ok(actual.match(/^Could not find a scheme called/));
    t.ok(actual.match(/goo.gl\/ntnS1I$/));
  }
});

test('invalid command arguments should cause error', async (t) => {
  const invalidCommandArguments = [
    [],
    ['-t', 'i3wm'],
    ['-s', 'oceanicnext'],
    ['--template', 'i3wm'],
    ['--scheme', 'oceanicnext']
  ];
  for (const commandArguments of invalidCommandArguments) {
    const {stderr: actual} = await execute(command, commandArguments);

    t.ok(actual.match(/^fatal: You need to specify \*both\* a template/));
    t.ok(actual.match(/goo.gl\/JwwX13\.$/));
  }
});

test('help arguments should cause help to be output', async (t) => {
  const {stdout: actual} = await execute(command, ['--help']);

  t.ok(actual.match(/Usage/));
  t.ok(actual.match(/Options/));
  t.ok(actual.match(/Example/));
});

test('valid arguments cause output file to be written', async (t) => {
  const scheme = 'oceanicnext';
  const templ = 'i3wm';
  const commandArguments = ['-s', scheme, '-t', templ];
  await execute(command, commandArguments);

  try {
    const path = `output/${templ}/${scheme}`;
    const actual = await fs.readFile(path, 'utf8');

    t.ok(/set \$base00 1B2B34/.test(actual));
  } catch (error) {
    t.fail(error);
  }
});

test('with aliases, valid arguments cause output file to be written', async (t) => {
  const scheme = 'oceanicnext';
  const templ = 'i3wm';
  const commandArguments = ['--scheme', scheme, '--template', templ];
  await execute(command, commandArguments);

  try {
    const path = `output/${templ}/${scheme}`;
    const actual = await fs.readFile(path, 'utf8');

    t.ok(/set \$base00 1B2B34/.test(actual));
  } catch (error) {
    t.fail(error);
  }
});
<commit_msg>refactor(tests): Replace arrow functions with function expressions in "functionalTests.js"<commit_after>/* eslint-disable max-len */

import test from 'ava';
import execute from 'execa';
import fs from 'fs-promise';
import removeDir from 'rimraf-promise';

const command = '../dist/cli.js';

test.afterEach(async function() {
  await removeDir('output');
});

test('non-existent template should cause error', async function (t) {
  const commandArguments = ['-s', 'monokai', '-t', 'foo'];
  const {stderr: actual} = await execute(command, commandArguments);

  t.ok(/^Could not find a template called/.test(actual));
  t.ok(/goo.gl\/6c8djV$/.test(actual));
});

test('templates with special name should cause error', async function (t) {
  const templs = ['schemes', 'templates'];
  for (const templ of templs) {
    const commandArguments = ['-s', 'monokai', '-t', templ];
    const {stderr: actual} = await execute(command, commandArguments);

    t.ok(/^Could not find a template called/.test(actual));
    t.ok(/goo.gl\/6c8djV$/.test(actual));
  }
});

test('non-existent scheme should cause error', async function (t) {
  const commandArguments = ['-s', 'bar', '-t', 'i3wm'];
  const {stderr: actual} = await execute(command, commandArguments);

  t.ok(/^Could not find a scheme called/.test(actual));
  t.ok(/goo.gl\/ntnS1I$/.test(actual));
});

test('schemes with special name should cause error', async function (t) {
  const schemes = ['schemes', 'templates'];
  for (const scheme of schemes) {
    const commandArguments = ['-s', scheme, '-t', 'i3wm'];
    const {stderr: actual} = await execute(command, commandArguments);

    t.ok(actual.match(/^Could not find a scheme called/));
    t.ok(actual.match(/goo.gl\/ntnS1I$/));
  }
});

test('invalid command arguments should cause error', async function (t) {
  const invalidCommandArguments = [
    [],
    ['-t', 'i3wm'],
    ['-s', 'oceanicnext'],
    ['--template', 'i3wm'],
    ['--scheme', 'oceanicnext']
  ];
  for (const commandArguments of invalidCommandArguments) {
    const {stderr: actual} = await execute(command, commandArguments);

    t.ok(actual.match(/^fatal: You need to specify \*both\* a template/));
    t.ok(actual.match(/goo.gl\/JwwX13\.$/));
  }
});

test('help arguments should cause help to be output', async function (t) {
  const {stdout: actual} = await execute(command, ['--help']);

  t.ok(actual.match(/Usage/));
  t.ok(actual.match(/Options/));
  t.ok(actual.match(/Example/));
});

test('valid arguments cause output file to be written', async function (t) {
  const scheme = 'oceanicnext';
  const templ = 'i3wm';
  const commandArguments = ['-s', scheme, '-t', templ];
  await execute(command, commandArguments);

  try {
    const path = `output/${templ}/${scheme}`;
    const actual = await fs.readFile(path, 'utf8');

    t.ok(/set \$base00 1B2B34/.test(actual));
  } catch (error) {
    t.fail(error);
  }
});

test('with aliases, valid arguments cause output file to be written', async function (t) {
  const scheme = 'oceanicnext';
  const templ = 'i3wm';
  const commandArguments = ['--scheme', scheme, '--template', templ];
  await execute(command, commandArguments);

  try {
    const path = `output/${templ}/${scheme}`;
    const actual = await fs.readFile(path, 'utf8');

    t.ok(/set \$base00 1B2B34/.test(actual));
  } catch (error) {
    t.fail(error);
  }
});
<|endoftext|>


<commit_before>// Sanity checks for search integration.  As these are read only, we use a single instance for all tests.
"use strict";
var fluid = fluid || require("infusion");
fluid.loadTestingSupport();
fluid.setLogging(true);

var gpii  = fluid.registerNamespace("gpii");

require("./test-harness");
require("../lib/saneresponse");

var jqUnit = require("node-jqunit");

var kettle = require("kettle");
kettle.loadTestingSupport();

fluid.registerNamespace("gpii.pouch.lucene.tests");

gpii.pouch.lucene.tests.expectNothing = function (){
    jqUnit.expect(0);
};

fluid.defaults("gpii.pouch.lucene.tests.caseHolder", {
    gradeNames: ["gpii.express.tests.caseHolder"],
    expected: {
        // Because of limitations when comparing array data, we have to split each expected set of results into pieces,
        // one piece that can be compared with the overall results (overall), and one piece that can be compared to
        // the "rows" data (rows).
        basic: {
            overall: { "total_rows": 2 },
            rows: [{ "fields": { "default": "Alpha Cat" } }, { "fields": { "default": "Charlie Cat" } }]
        },
        sorted: {
            overall: { "total_rows": 2 },
            rows: [{ "fields": { "default": "Charlie Cat" } }, { "fields": { "default": "Alpha Cat" } }]
        }
    },
    // Our raw test cases, that will have `sequenceStart` prepended before they are run.
    rawModules: [
        {
            tests: [
                {
                    //name: "Testing a basic search...",
                    name: "Testing lucene search integration...",
                    type: "test",
                    sequence: [
                        {
                            func: "{basicRequest}.send"
                        },
                        {
                            listener: "gpii.pouch.lucene.tests.isSaneResponse",
                            event:    "{basicRequest}.events.onComplete",
                            args:     ["{basicRequest}.nativeResponse", "{arguments}.0", 200, "{testCaseHolder}.options.expected.basic"]
                        },
                        {
                            func: "{testEnvironment}.harness.lucene.events.onReadyForShutdown.fire"
                        },
                        {
                            listener: "fluid.identity",
                            event:    "{testEnvironment}.harness.lucene.events.onShutdownComplete"
                        }
                    ]
                },
                {
                    name: "Testing a sorted search...",
                    type: "test",
                    sequence: [
                        {
                            func: "{sortedRequest}.send"
                        },
                        {
                            listener: "gpii.pouch.lucene.tests.isSaneResponse",
                            event:    "{sortedRequest}.events.onComplete",
                            args:     ["{sortedRequest}.nativeResponse", "{arguments}.0", 200, "{testCaseHolder}.options.expected.sorted"]
                        },
                        {
                            func: "{testEnvironment}.harness.lucene.events.onReadyForShutdown.fire"
                        },
                        {
                            listener: "fluid.identity",
                            event:    "{testEnvironment}.harness.lucene.events.onShutdownComplete"
                        }
                    ]
                }
            ]
        }
    ],

    components: {
        basicRequest: {
            type: "kettle.test.request.http",
            options: {
                path:   "/local/sample/_design/lucene/by_content?q=cat",
                port:   "{testEnvironment}.options.lucenePort",
                method: "GET"
            }
        },
        sortedRequest: {
            type: "kettle.test.request.http",
            options: {
                path:   "/local/sample/_design/lucene/by_content?q=cat&sort=\\default",
                port:   "{testEnvironment}.options.lucenePort",
                method: "GET"
            }
        }
    }
});

fluid.defaults("gpii.pouch.lucene.tests", {
    gradeNames: ["fluid.test.testEnvironment"],
    pouchPort:  "9998",
    baseUrl:    {
        expander: {
            funcName: "fluid.stringTemplate",
            args:     ["http://localhost:%port", { port: "{that}.options.pouchPort"}]
        }
    },
    lucenePort: "3598",
    events: {
        constructServer: null,
        onStarted:       null
    },
    components: {
        harness: {
            type:          "gpii.pouch.lucene.tests.harness",
            createOnEvent: "constructServer",
            options: {
                pouchPort:  "{testEnvironment}.options.pouchPort",
                baseUrl:    "{testEnvironment}.options.baseUrl",
                lucenePort: "{testEnvironment}.options.lucenePort",
                listeners: {
                    "onStarted.notifyParent": {
                        func: "{testEnvironment}.events.onStarted.fire"
                    }
                }
            }
        },
        testCaseHolder: {
            type: "gpii.pouch.lucene.tests.caseHolder"
        }
    }
});

gpii.pouch.lucene.tests();<commit_msg>GPII-1241:  Added GET request to preload CouchDB views before hitting Lucene.<commit_after>// Sanity checks for search integration.  As these are read only, we use a single instance for all tests.
"use strict";
var fluid = fluid || require("infusion");
fluid.loadTestingSupport();
fluid.setLogging(true);

var gpii  = fluid.registerNamespace("gpii");

require("./test-harness");
require("../lib/saneresponse");

var jqUnit = require("node-jqunit");

var kettle = require("kettle");
kettle.loadTestingSupport();

fluid.registerNamespace("gpii.pouch.lucene.tests");

gpii.pouch.lucene.tests.expectNothing = function (){
    jqUnit.expect(0);
};

fluid.defaults("gpii.pouch.lucene.tests.caseHolder", {
    gradeNames: ["gpii.express.tests.caseHolder"],
    expected: {
        // Because of limitations when comparing array data, we have to split each expected set of results into pieces,
        // one piece that can be compared with the overall results (overall), and one piece that can be compared to
        // the "rows" data (rows).
        basic: {
            overall: { "total_rows": 2 },
            rows: [{ "fields": { "default": "Alpha Cat" } }, { "fields": { "default": "Charlie Cat" } }]
        },
        sorted: {
            overall: { "total_rows": 2 },
            rows: [{ "fields": { "default": "Charlie Cat" } }, { "fields": { "default": "Alpha Cat" } }]
        }
    },
    // Our raw test cases, that will have `sequenceStart` prepended before they are run.
    rawModules: [
        {
            tests: [
                {
                    //name: "Testing a basic search...",
                    name: "Testing lucene search integration...",
                    type: "test",
                    sequence: [
                        {
                            func: "{basicCouchViewRequest}.send"
                        },
                        {
                            event:    "{basicCouchViewRequest}.events.onComplete",
                            listener: "{basicRequest}.send"
                        },
                        {
                            listener: "gpii.pouch.lucene.tests.isSaneResponse",
                            event:    "{basicRequest}.events.onComplete",
                            args:     ["{basicRequest}.nativeResponse", "{arguments}.0", 200, "{testCaseHolder}.options.expected.basic"]
                        },
                        {
                            func: "{testEnvironment}.harness.lucene.events.onReadyForShutdown.fire"
                        },
                        {
                            listener: "fluid.identity",
                            event:    "{testEnvironment}.harness.lucene.events.onShutdownComplete"
                        }
                    ]
                },
                {
                    name: "Testing a sorted search...",
                    type: "test",
                    sequence: [
                        {
                            func: "{sortedCouchViewRequest}.send"
                        },
                        {
                            event:    "{sortedCouchViewRequest}.events.onComplete",
                            listener: "{sortedRequest}.send"
                        },
                        {
                            listener: "gpii.pouch.lucene.tests.isSaneResponse",
                            event:    "{sortedRequest}.events.onComplete",
                            args:     ["{sortedRequest}.nativeResponse", "{arguments}.0", 200, "{testCaseHolder}.options.expected.sorted"]
                        },
                        {
                            func: "{testEnvironment}.harness.lucene.events.onReadyForShutdown.fire"
                        },
                        {
                            listener: "fluid.identity",
                            event:    "{testEnvironment}.harness.lucene.events.onShutdownComplete"
                        }
                    ]
                }
            ]
        }
    ],

    components: {
        basicCouchViewRequest: {
            type: "kettle.test.request.http",
            options: {
                path:   "/sample/_design/lucene/by_content",
                port:   "{testEnvironment}.options.pouchPort",
                method: "GET"
            }
        },
        basicRequest: {
            type: "kettle.test.request.http",
            options: {
                path:   "/local/sample/_design/lucene/by_content?q=cat",
                port:   "{testEnvironment}.options.lucenePort",
                method: "GET"
            }
        },
        sortedCouchViewRequest: {
            type: "kettle.test.request.http",
            options: {
                path:   "/sample/_design/lucene/by_content",
                port:   "{testEnvironment}.options.pouchPort",
                method: "GET"
            }
        },
        sortedRequest: {
            type: "kettle.test.request.http",
            options: {
                path:   "/local/sample/_design/lucene/by_content?q=cat&sort=\\default",
                port:   "{testEnvironment}.options.lucenePort",
                method: "GET"
            }
        }
    }
});

fluid.defaults("gpii.pouch.lucene.tests", {
    gradeNames: ["fluid.test.testEnvironment"],
    pouchPort:  "9998",
    baseUrl:    {
        expander: {
            funcName: "fluid.stringTemplate",
            args:     ["http://localhost:%port", { port: "{that}.options.pouchPort"}]
        }
    },
    lucenePort: "3598",
    events: {
        constructServer: null,
        onStarted:       null
    },
    components: {
        harness: {
            type:          "gpii.pouch.lucene.tests.harness",
            createOnEvent: "constructServer",
            options: {
                pouchPort:  "{testEnvironment}.options.pouchPort",
                baseUrl:    "{testEnvironment}.options.baseUrl",
                lucenePort: "{testEnvironment}.options.lucenePort",
                listeners: {
                    "onStarted.notifyParent": {
                        func: "{testEnvironment}.events.onStarted.fire"
                    }
                }
            }
        },
        testCaseHolder: {
            type: "gpii.pouch.lucene.tests.caseHolder"
        }
    }
});

gpii.pouch.lucene.tests();<|endoftext|>


<commit_before>import React from 'react';
import { assert } from 'chai';
import { shallow } from 'enzyme';
import CalendarHeatmap from '../../src';
import { shiftDate } from '../../src/dateHelpers';

describe('CalendarHeatmap', () => {
  it('should render as an svg', () => {
    const wrapper = shallow(
      <CalendarHeatmap values={[]} />
    );
    assert.equal(1, wrapper.find('svg').length);
  });

  it('should not throw exceptions in base case', () => {
    assert.doesNotThrow(() => <CalendarHeatmap values={[]} />);
  });

  it('should be able to orient horizontally and vertically', () => {
    const horizontal = shallow(
      <CalendarHeatmap numDays={100} values={[]} horizontal />
    );
    const [, , horWidth, horHeight] = horizontal.props().viewBox.split(' ');
    assert(Number(horWidth) > Number(horHeight), 'horizontal orientation width should be greater than height');

    const vertical = shallow(
      <CalendarHeatmap numDays={100} values={[]} horizontal={false} />
    );
    const [, , vertWidth, vertHeight] = vertical.props().viewBox.split(' ');
    assert(Number(vertWidth) < Number(vertHeight), 'vertical orientation width should be less than height');
  });

  it('should end on the correct day', () => {
    const today = new Date();
    const wrapper = shallow(
      <CalendarHeatmap values={[]} endDate={today} numDays={10} />
    );

    assert.equal(today.getDate(), wrapper.instance().getEndDate().getDate());
    assert.equal(today.getMonth(), wrapper.instance().getEndDate().getMonth());
  });

  it('should start on the correct day', () => {
    const today = new Date();
    const numDays = 10;
    const expectedStartDate = shiftDate(today, -numDays + 1);
    const wrapper = shallow(
      <CalendarHeatmap values={[]} endDate={today} numDays={numDays} />
    );

    assert.equal(expectedStartDate.getDate(), wrapper.instance().getStartDate().getDate());
    assert.equal(expectedStartDate.getMonth(), wrapper.instance().getStartDate().getMonth());
  });
});
<commit_msg>Reorganize and add classForValue test<commit_after>import React from 'react';
import { assert } from 'chai';
import { shallow } from 'enzyme';
import CalendarHeatmap from '../../src';
import { shiftDate } from '../../src/dateHelpers';

describe('CalendarHeatmap', () => {
  it('should render as an svg', () => {
    const wrapper = shallow(
      <CalendarHeatmap values={[]} />
    );
    assert.equal(1, wrapper.find('svg').length);
  });

  it('should not throw exceptions in base case', () => {
    assert.doesNotThrow(() => <CalendarHeatmap values={[]} />);
  });
});

describe('CalendarHeatmap props', () => {
  it('horizontal', () => {
    const horizontal = shallow(
      <CalendarHeatmap numDays={100} values={[]} horizontal />
    );
    const [, , horWidth, horHeight] = horizontal.prop('viewBox').split(' ');
    assert(Number(horWidth) > Number(horHeight), 'horizontal orientation width should be greater than height');

    const vertical = shallow(
      <CalendarHeatmap numDays={100} values={[]} horizontal={false} />
    );
    const [, , vertWidth, vertHeight] = vertical.prop('viewBox').split(' ');
    assert(Number(vertWidth) < Number(vertHeight), 'vertical orientation width should be less than height');
  });

  it('endDate', () => {
    const today = new Date();
    const wrapper = shallow(
      <CalendarHeatmap values={[]} endDate={today} numDays={10} />
    );

    assert(
      today.getDate() === wrapper.instance().getEndDate().getDate() &&
      today.getMonth() === wrapper.instance().getEndDate().getMonth()
    );
  });

  it('numDays', () => {
    const today = new Date();
    const numDays = 10;
    const expectedStartDate = shiftDate(today, -numDays + 1);
    const wrapper = shallow(
      <CalendarHeatmap values={[]} endDate={today} numDays={numDays} />
    );

    assert(
      expectedStartDate.getDate() === wrapper.instance().getStartDate().getDate() &&
      expectedStartDate.getMonth() === wrapper.instance().getStartDate().getMonth()
    );

    assert.equal(numDays, wrapper.find('rect').length);
  });

  it('classForValue', () => {
    const today = new Date();
    const numDays = 10;
    const expectedStartDate = shiftDate(today, -numDays + 1);
    const wrapper = shallow(
      <CalendarHeatmap
        values={[
          { date: expectedStartDate, count: 0 },
          { date: today, count: 1 },
        ]}
        endDate={today}
        numDays={numDays}
        titleForValue={(value) => (value ? value.count : null)}
        classForValue={(value) => {
          if (!value) {
            return null;
          }
          return value.count > 0 ? 'red' : 'white';
        }}
      />
    );

    assert.equal(1, wrapper.find('.white').length);
    assert.equal(1, wrapper.find('.red').length);

    // TODO these attr selectors might be broken with react 15
    // assert(wrapper.first('rect[title=0]').hasClass('white'));
    // assert(wrapper.first('rect[title=1]').hasClass('red'));
  });
});
<|endoftext|>


<commit_before>'use strict';

const createTestRunner = require('../../help/browsertimeRunner')
    .createTestRunner,
  assert = require('assert');

let BROWSERS = ['chrome', 'firefox'];

describe('Inline CSS advice HTTP/2:', function() {
  BROWSERS.forEach(function(browser) {
    describe('browser: ' + browser, function() {
      const runner = createTestRunner(browser, 'performance', true);

      before(() => runner.start(browser));

      after(() => runner.stop());

      it('We should be able to know if we inline CSS and request CSS files', function() {
        return runner
          .runGlobalServer(
            'inlineCss.js',
            'https://www.sitespeed.io/testcases/performance/inlinecss/inlineAndRequestCss.html'
          )
          .then(result => {
            assert.strictEqual(result.score, 95);
          });
      });

      it('We should be able to know if we request CSS file(s)', function() {
        // TODO make this work in FF
        if (browser === 'firefox') {
          this.skip();
        }
        return runner
          .runGlobalServer(
            'inlineCss.js',
            'https://www.sitespeed.io/testcases/performance/inlinecss/noInlineAndRequestCss.html'
          )
          .then(result => {
            assert.strictEqual(result.score, 100);
          });
      });
    });
  });
});
<commit_msg>enable FF test<commit_after>'use strict';

const createTestRunner = require('../../help/browsertimeRunner')
    .createTestRunner,
  assert = require('assert');

let BROWSERS = ['chrome', 'firefox'];

describe('Inline CSS advice HTTP/2:', function() {
  BROWSERS.forEach(function(browser) {
    describe('browser: ' + browser, function() {
      const runner = createTestRunner(browser, 'performance', true);

      before(() => runner.start(browser));

      after(() => runner.stop());

      it('We should be able to know if we inline CSS and request CSS files', function() {
        return runner
          .runGlobalServer(
            'inlineCss.js',
            'https://www.sitespeed.io/testcases/performance/inlinecss/inlineAndRequestCss.html'
          )
          .then(result => {
            assert.strictEqual(result.score, 95);
          });
      });

      it('We should be able to know if we request CSS file(s)', function() {
        // TODO make this work in FF
        /*
        if (browser === 'firefox') {
          this.skip();
        }
        */
        return runner
          .runGlobalServer(
            'inlineCss.js',
            'https://www.sitespeed.io/testcases/performance/inlinecss/noInlineAndRequestCss.html'
          )
          .then(result => {
            assert.strictEqual(result.score, 100);
          });
      });
    });
  });
});
<|endoftext|>


<commit_before>const FriendlyErrorsWebpackPlugin = require('../../../index');

module.exports = {
	mode: 'development',
  entry: __dirname + "/index.js",
  output: {
    path: __dirname + "/dist",
    filename: "bundle.js"
  },
  plugins: [
    new FriendlyErrorsWebpackPlugin()
  ]
};
<commit_msg>Update webpack.config.js<commit_after>const FriendlyErrorsWebpackPlugin = require('../../../index');

module.exports = {
  mode: 'development',
  entry: __dirname + "/index.js",
  output: {
    path: __dirname + "/dist",
    filename: "bundle.js"
  },
  plugins: [
    new FriendlyErrorsWebpackPlugin()
  ]
};
<|endoftext|>


<commit_before>var assert = require('chai').assert;
var nodemock = require('nodemock');
var Deferred = require('jsdeferred').Deferred;
var express = require('express');

var utils = require('./test-utils');

var socketIoAdaptor = require('../lib/frontend/socket.io-adaptor');
var model = require('../lib/model');
var scoketIoCommands = require('../lib/frontend/default-commands/socket.io');
var Connection = require('../lib/backend/connection').Connection;

suite('Socket.IO API', function() {
  var connection;
  var server;
  var clientSocket;

  var testPlugin = {
    'foobar': new model.SocketCommand(),
    'builder': new model.SocketRequestResponse({
      toBackend: function(event, data) { return [event, 'builder request']; },
      toClient: function(event, data) { return [event, 'builder response'] }
    }),
    'customevent': new model.SocketRequestResponse({
      toBackend: function(event, data) { return ['custom', data] },
      toClient: function(event, data) { return [event, 'custom response']; }
    }),
    'pubsub': new model.SocketPublisSubscribe()
  };

  teardown(function() {
    if (connection) {
      utils.readyToDestroyMockedConnection(connection);
      connection = undefined;
    }
    if (clientSocket) {
      clientSocket.disconnect();
      clientSocket = undefined;
    }
    if (server) {
      server.close();
      server = undefined;
    }
  });

  test('registeration of plugin commands', function(done) {
    var basePlugin = {
      getCommand: new model.SocketRequestResponse(),
      putCommand: new model.SocketRequestResponse(),
      postCommand: new model.SocketRequestResponse(),
      deleteCommand: new model.SocketRequestResponse(),
      ignored: new model.REST()
    };
    var overridingPlugin = {
      postCommand: new model.SocketRequestResponse(),
      deleteCommand: new model.SocketRequestResponse()
    };

    var application = express();
    utils.setupServer(application)
      .next(function(newServer) {
        server = newServer;

        var registeredCommands = socketIoAdaptor.register(application, server, {
          connection: utils.createStubbedBackendConnection(),
          plugins: [
            basePlugin,
            overridingPlugin
          ]
        });

        registeredCommands = registeredCommands.map(function(command) {
          return {
            name:       command.name,
            definition: command.definition
          };
        });
        assert.deepEqual(registeredCommands,
                         [{ name:       'search',
                            definition: scoketIoCommands.search },
                          { name:       'getCommand',
                            definition: basePlugin.getCommand },
                          { name:       'putCommand',
                            definition: basePlugin.putCommand },
                          { name:       'postCommand',
                            definition: overridingPlugin.postCommand },
                          { name:       'deleteCommand',
                            definition: overridingPlugin.deleteCommand }]);
        done();
      })
      .error(function(error) {
        done(error);
      });
  });

  test('initialization', function(done) {
    var mockedListener = nodemock
      .mock('connected');

    var application = express();
    application.on('connection', function(socket) {
      mockedListener.connected();
    });

    utils.setupServer(application)
      .next(function(newServer) {
        server = newServer;
        socketIoAdaptor.register(application, server, {
          connection: utils.createStubbedBackendConnection()
        });

        return utils.createClientSocket();
      })
      .next(function(newClientSocket) {
        clientSocket = newClientSocket;
      })
      .wait(0.01)
      .next(function() {
        mockedListener.assertThrows();
        done();
      })
      .error(function(error) {
        done(error);
      });
  });

  test('front to back', function(done) {
    connection = utils.createMockedBackendConnection();

    var application = express();
    utils.setupServer(application)
      .next(function(newServer) {
        server = newServer;
        socketIoAdaptor.register(application, server, {
          connection: connection
        });

        return utils.createClientSocket();
      })
      .next(function(newClientSocket) {
        clientSocket = newClientSocket;

        connection = connection
          .mock('emitMessage')
            .takes('search', { requestMessage: true } function() {}, {});
        clientSocket.emit('search', { requestMessage: true });
      })
      .wait(0.01)
      .next(function() {
        connection.assertThrows();
        done();
      })
      .error(function(error) {
        done(error);
      });
  });

  test('back to front', function(done) {
    connection = utils.createMockedBackendConnection();

    var clientReceiver = nodemock
          .mock('receive')
          .takes({
            statusCode: 200,
            body:       { published: true }
          });

    var application = express();
    utils.setupServer(application)
      .next(function(newServer) {
        server = newServer;
        socketIoAdaptor.register(application, server, {
          connection: connection,
          plugins: [testPlugin]
        });

        return utils.createClientSocket();
      })
      .next(function(newClientSocket) {
        clientSocket = newClientSocket;

        connection.assertThrows();

        clientSocket.on('pubsub', function(data) {
          clientReceiver.receive(data);
        });

        var envelope = {
          type:       'pubsub',
          statusCode: 200,
          body:       { published: true}
        };
        connection.controllers.search.trigger(envelope);
      })
      .wait(0.01)
      .next(function() {
        clientReceiver.assertThrows();
        done();
      })
      .error(function(error) {
        done(error);
      });
  });

  test('front to back, extra command (without builder)', function(done) {
    var extraController = {};
    connection = utils.createMockedBackendConnection();

    var application = express();
    utils.setupServer(application)
      .next(function(newServer) {
        server = newServer;
        socketIoAdaptor.register(application, server, {
          connection: connection,
          plugins: [testPlugin]
        });

        return utils.createClientSocket();
      })
      .next(function(newClientSocket) {
        clientSocket = newClientSocket;

        connection = connection
          .mock('emitMessage')
            .takes('foobar', { requestMessage: true });
        clientSocket.emit('foobar', { requestMessage: true });
      })
      .wait(0.01)
      .next(function() {
        connection.assertThrows();
        done();
      })
      .error(function(error) {
        done(error);
      });
  });

  test('front to back, extra command (with builder)', function(done) {
    var extraController = {};
    connection = utils.createMockedBackendConnection();

    var mockedReceiver = nodemock
          .mock('receive')
            .takes('builder response');

    var application = express();
    utils.setupServer(application)
      .next(function(newServer) {
        server = newServer;
        socketIoAdaptor.register(application, server, {
          connection: connection,
          plugins: [testPlugin]
        });

        return utils.createClientSocket();
      })
      .next(function(newClientSocket) {
        clientSocket = newClientSocket;

        connection = connection
          .mock('emitMessage')
            .takes('builder', 'builder request');
        clientSocket.on('builder.result', function(data) {
          mockedReceiver.receive(data);
        });
        clientSocket.emit('builder', { requestMessage: true });
      })
      .wait(0.01)
      .next(function() {
        connection.assertThrows();
        connection.controllers.builder.trigger({
          statusCode: 200,
          type: 'builder.result',
          body: { responseMessage: true }
        });
      })
      .wait(0.01)
      .next(function() {
        mockedReceiver.assertThrows();
        done();
      })
      .error(function(error) {
        done(error);
      });
  });

  test('front to back, extra command (custom event name)', function(done) {
    var extraController = {};
    connection = utils.createMockedBackendConnection();

    var mockedReceiver = nodemock
          .mock('receive')
            .takes('custom response');

    var application = express();
    utils.setupServer(application)
      .next(function(newServer) {
        server = newServer;
        socketIoAdaptor.register(application, server, {
          connection: connection,
          plugins: [testPlugin]
        });

        return utils.createClientSocket();
      })
      .next(function(newClientSocket) {
        clientSocket = newClientSocket;

        connection = connection
          .mock('emitMessage')
            .takes('customevent', { requestMessage: true });
        clientSocket.on('custom', function(data) {
          mockedReceiver.receive(data);
        });
        clientSocket.emit('customevent', { requestMessage: true });
      })
      .wait(0.01)
      .next(function() {
        connection.assertThrows();
        connection.controllers.customevent.trigger({
          statusCode: 200,
          type: 'customevent.result',
          body: { responseMessage: true }
        });
      })
      .wait(0.01)
      .next(function() {
        mockedReceiver.assertThrows();
        done();
      })
      .error(function(error) {
        done(error);
      });
  });
});

<commit_msg>Fix syntax error: missing comma<commit_after>var assert = require('chai').assert;
var nodemock = require('nodemock');
var Deferred = require('jsdeferred').Deferred;
var express = require('express');

var utils = require('./test-utils');

var socketIoAdaptor = require('../lib/frontend/socket.io-adaptor');
var model = require('../lib/model');
var scoketIoCommands = require('../lib/frontend/default-commands/socket.io');
var Connection = require('../lib/backend/connection').Connection;

suite('Socket.IO API', function() {
  var connection;
  var server;
  var clientSocket;

  var testPlugin = {
    'foobar': new model.SocketCommand(),
    'builder': new model.SocketRequestResponse({
      toBackend: function(event, data) { return [event, 'builder request']; },
      toClient: function(event, data) { return [event, 'builder response'] }
    }),
    'customevent': new model.SocketRequestResponse({
      toBackend: function(event, data) { return ['custom', data] },
      toClient: function(event, data) { return [event, 'custom response']; }
    }),
    'pubsub': new model.SocketPublisSubscribe()
  };

  teardown(function() {
    if (connection) {
      utils.readyToDestroyMockedConnection(connection);
      connection = undefined;
    }
    if (clientSocket) {
      clientSocket.disconnect();
      clientSocket = undefined;
    }
    if (server) {
      server.close();
      server = undefined;
    }
  });

  test('registeration of plugin commands', function(done) {
    var basePlugin = {
      getCommand: new model.SocketRequestResponse(),
      putCommand: new model.SocketRequestResponse(),
      postCommand: new model.SocketRequestResponse(),
      deleteCommand: new model.SocketRequestResponse(),
      ignored: new model.REST()
    };
    var overridingPlugin = {
      postCommand: new model.SocketRequestResponse(),
      deleteCommand: new model.SocketRequestResponse()
    };

    var application = express();
    utils.setupServer(application)
      .next(function(newServer) {
        server = newServer;

        var registeredCommands = socketIoAdaptor.register(application, server, {
          connection: utils.createStubbedBackendConnection(),
          plugins: [
            basePlugin,
            overridingPlugin
          ]
        });

        registeredCommands = registeredCommands.map(function(command) {
          return {
            name:       command.name,
            definition: command.definition
          };
        });
        assert.deepEqual(registeredCommands,
                         [{ name:       'search',
                            definition: scoketIoCommands.search },
                          { name:       'getCommand',
                            definition: basePlugin.getCommand },
                          { name:       'putCommand',
                            definition: basePlugin.putCommand },
                          { name:       'postCommand',
                            definition: overridingPlugin.postCommand },
                          { name:       'deleteCommand',
                            definition: overridingPlugin.deleteCommand }]);
        done();
      })
      .error(function(error) {
        done(error);
      });
  });

  test('initialization', function(done) {
    var mockedListener = nodemock
      .mock('connected');

    var application = express();
    application.on('connection', function(socket) {
      mockedListener.connected();
    });

    utils.setupServer(application)
      .next(function(newServer) {
        server = newServer;
        socketIoAdaptor.register(application, server, {
          connection: utils.createStubbedBackendConnection()
        });

        return utils.createClientSocket();
      })
      .next(function(newClientSocket) {
        clientSocket = newClientSocket;
      })
      .wait(0.01)
      .next(function() {
        mockedListener.assertThrows();
        done();
      })
      .error(function(error) {
        done(error);
      });
  });

  test('front to back', function(done) {
    connection = utils.createMockedBackendConnection();

    var application = express();
    utils.setupServer(application)
      .next(function(newServer) {
        server = newServer;
        socketIoAdaptor.register(application, server, {
          connection: connection
        });

        return utils.createClientSocket();
      })
      .next(function(newClientSocket) {
        clientSocket = newClientSocket;

        connection = connection
          .mock('emitMessage')
            .takes('search', { requestMessage: true }, function() {}, {});
        clientSocket.emit('search', { requestMessage: true });
      })
      .wait(0.01)
      .next(function() {
        connection.assertThrows();
        done();
      })
      .error(function(error) {
        done(error);
      });
  });

  test('back to front', function(done) {
    connection = utils.createMockedBackendConnection();

    var clientReceiver = nodemock
          .mock('receive')
          .takes({
            statusCode: 200,
            body:       { published: true }
          });

    var application = express();
    utils.setupServer(application)
      .next(function(newServer) {
        server = newServer;
        socketIoAdaptor.register(application, server, {
          connection: connection,
          plugins: [testPlugin]
        });

        return utils.createClientSocket();
      })
      .next(function(newClientSocket) {
        clientSocket = newClientSocket;

        connection.assertThrows();

        clientSocket.on('pubsub', function(data) {
          clientReceiver.receive(data);
        });

        var envelope = {
          type:       'pubsub',
          statusCode: 200,
          body:       { published: true}
        };
        connection.controllers.search.trigger(envelope);
      })
      .wait(0.01)
      .next(function() {
        clientReceiver.assertThrows();
        done();
      })
      .error(function(error) {
        done(error);
      });
  });

  test('front to back, extra command (without builder)', function(done) {
    var extraController = {};
    connection = utils.createMockedBackendConnection();

    var application = express();
    utils.setupServer(application)
      .next(function(newServer) {
        server = newServer;
        socketIoAdaptor.register(application, server, {
          connection: connection,
          plugins: [testPlugin]
        });

        return utils.createClientSocket();
      })
      .next(function(newClientSocket) {
        clientSocket = newClientSocket;

        connection = connection
          .mock('emitMessage')
            .takes('foobar', { requestMessage: true });
        clientSocket.emit('foobar', { requestMessage: true });
      })
      .wait(0.01)
      .next(function() {
        connection.assertThrows();
        done();
      })
      .error(function(error) {
        done(error);
      });
  });

  test('front to back, extra command (with builder)', function(done) {
    var extraController = {};
    connection = utils.createMockedBackendConnection();

    var mockedReceiver = nodemock
          .mock('receive')
            .takes('builder response');

    var application = express();
    utils.setupServer(application)
      .next(function(newServer) {
        server = newServer;
        socketIoAdaptor.register(application, server, {
          connection: connection,
          plugins: [testPlugin]
        });

        return utils.createClientSocket();
      })
      .next(function(newClientSocket) {
        clientSocket = newClientSocket;

        connection = connection
          .mock('emitMessage')
            .takes('builder', 'builder request');
        clientSocket.on('builder.result', function(data) {
          mockedReceiver.receive(data);
        });
        clientSocket.emit('builder', { requestMessage: true });
      })
      .wait(0.01)
      .next(function() {
        connection.assertThrows();
        connection.controllers.builder.trigger({
          statusCode: 200,
          type: 'builder.result',
          body: { responseMessage: true }
        });
      })
      .wait(0.01)
      .next(function() {
        mockedReceiver.assertThrows();
        done();
      })
      .error(function(error) {
        done(error);
      });
  });

  test('front to back, extra command (custom event name)', function(done) {
    var extraController = {};
    connection = utils.createMockedBackendConnection();

    var mockedReceiver = nodemock
          .mock('receive')
            .takes('custom response');

    var application = express();
    utils.setupServer(application)
      .next(function(newServer) {
        server = newServer;
        socketIoAdaptor.register(application, server, {
          connection: connection,
          plugins: [testPlugin]
        });

        return utils.createClientSocket();
      })
      .next(function(newClientSocket) {
        clientSocket = newClientSocket;

        connection = connection
          .mock('emitMessage')
            .takes('customevent', { requestMessage: true });
        clientSocket.on('custom', function(data) {
          mockedReceiver.receive(data);
        });
        clientSocket.emit('customevent', { requestMessage: true });
      })
      .wait(0.01)
      .next(function() {
        connection.assertThrows();
        connection.controllers.customevent.trigger({
          statusCode: 200,
          type: 'customevent.result',
          body: { responseMessage: true }
        });
      })
      .wait(0.01)
      .next(function() {
        mockedReceiver.assertThrows();
        done();
      })
      .error(function(error) {
        done(error);
      });
  });
});

<|endoftext|>


<commit_before>var assert = require('assert');
var mixinMetadata = require('../../../lib/hooks/request/metadata');

describe('Request hook', function () {
  describe('metadata', function () {
    beforeEach(function() {
      this.req = {
        headers: {},
        header: function(key) { return this.headers[key]; },
        app: {
          data: { 'trust proxy': false },
          get: function(key) { return this.data[key]; }
        },
        _sails: { hooks: {} }
      };
      this.res = {};
    });

    describe('without a reverse proxy', function() {
      it('should set req.port to 80 for http requests', function() {
        this.req.protocol = 'http';
        this.req.host = 'example.org';
        this.req.headers.Host = 'example.org';
        mixinMetadata(this.req);
        assert.equal(this.req.port, 80);
      });

      it('should set req.port to 443 for https requests', function() {
        this.req.protocol = 'https';
        this.req.host = 'example.org';
        this.req.headers.Host = 'example.org';
        mixinMetadata(this.req);
        assert.equal(this.req.port, 443);
      });

      it('should not add a port to baseUrl on port 80 or 443', function() {
        this.req.protocol = 'http';
        this.req.host = 'example.org';
        this.req.headers.Host = 'example.org';
        mixinMetadata(this.req);
        assert.equal(this.req.baseUrl, 'http://example.org');

        this.req.protocol = 'https';
        this.req.host = 'example.org';
        this.req.headers.Host = 'example.org';
        mixinMetadata(this.req);
        assert.equal(this.req.baseUrl, 'https://example.org');
      });

      it('should add a port to baseUrl on a custom port', function() {
        this.req.protocol = 'http';
        this.req.host = 'example.org';
        this.req.headers.Host = 'example.org:1337';
        mixinMetadata(this.req);
        assert.equal(this.req.baseUrl, 'http://example.org:1337');
      });

      it('should handle running as HTTP on port 443', function() {
        this.req.protocol = 'http';
        this.req.host = 'example.org';
        this.req.headers.Host = 'example.org:443';
        mixinMetadata(this.req);
        assert.equal(this.req.port, 443);
        assert.equal(this.req.baseUrl, 'http://example.org:443');
      });
    });

    describe('with a reverse proxy and app.enable("trust proxy")', function() {
      beforeEach(function() {
        this.req.app.data['trust proxy'] = true;
      });

      /*
       * In this case, req.protocol as set by Express is aware of the
       * X-Forwarded-Proto header field. The only complication: req.host
       * doesn't include a port number; req.header('host') might be wrong, too,
       * so we can't trust it either.
       */

      it('should handle a simple HTTP case with X-Forwarded-Host', function() {
        this.req.protocol = 'http'; // we assume Express got this right
        this.req.host = 'server.local';
        this.req.headers.Host = 'server.local';
        this.req.headers['X-Forwarded-Host'] = 'example.org';
        mixinMetadata(this.req);
        assert.equal(this.req.port, 80);
        assert.equal(this.req.baseUrl, 'http://example.org');
      });

      it('should handle when X-Forwarded-Host is not set', function() {
        this.req.protocol = 'http'; // we assume Express got this right
        this.req.host = 'server.local';
        this.req.headers.Host = 'example.org:81';
        mixinMetadata(this.req);
        assert.equal(this.req.port, 81);
        assert.equal(this.req.baseUrl, 'http://example.org:81');
      });

      it('should handle a simple HTTPS case with X-Forwarded-Host', function() {
        this.req.protocol = 'https'; // we assume Express got this right
        this.req.host = 'server.local';
        this.req.headers.Host = 'server.local';
        this.req.headers['X-Forwarded-Host'] = 'example.org';
        mixinMetadata(this.req);
        assert.equal(this.req.port, 443);
        assert.equal(this.req.baseUrl, 'https://example.org');
      });

      it('should handle running on a nonstandard port', function() {
        this.req.protocol = 'https'; // we assume Express got this right
        this.req.host = 'server.local';
        this.req.headers.Host = 'server.local:10000';
        this.req.headers['X-Forwarded-Host'] = 'example.org';
        mixinMetadata(this.req);
        assert.equal(this.req.port, 443);
        assert.equal(this.req.baseUrl, 'https://example.org');
      });

      it('should handle a list of x-forwarded-host values', function() {
        this.req.protocol = 'https'; // we assume Express got this right
        this.req.host = 'server2.local';
        this.req.headers.Host = 'server2.local:10000';
        this.req.headers['X-Forwarded-Host'] = 'example.org, server1.local';
        mixinMetadata(this.req);
        assert.equal(this.req.port, 443);
        assert.equal(this.req.baseUrl, 'https://example.org');
      });

      it('should handle running on a weird port through a reverse proxy', function() {
        this.req.protocol = 'http';
        this.req.host = 'server.local';
        this.req.headers.Host = 'server.local:1000';
        this.req.headers['X-Forwarded-Host'] = 'example.org:81';
        mixinMetadata(this.req);
        assert.equal(this.req.port, 81);
        assert.equal(this.req.baseUrl, 'http://example.org:81');
      });

      it('should handle running as HTTP on port 443', function() {
        this.req.protocol = 'http';
        this.req.host = 'server.local';
        this.req.headers.Host = 'server.local:443';
        this.req.headers['X-Forwarded-Host'] = 'example.org:443';
        mixinMetadata(this.req);
        assert.equal(this.req.port, 443);
        assert.equal(this.req.baseUrl, 'http://example.org:443');
      });
    });
  });
});
<commit_msg>Fix metadata tests<commit_after>var assert = require('assert');
var mixinMetadata = require('../../../lib/hooks/request/metadata');
// var Sails = require('../../../lib/app');

describe('Request hook', function () {
  describe('metadata', function () {

    beforeEach(function() {
      this.req = {
        headers: {},
        get: function(key) { return this.headers[key]; },
        app: {
          data: { 'trust proxy': false },
          get: function(key) { return this.data[key]; }
        },
        _sails: {
          hooks: {},
          config: {}
        }
      };
    });

    describe('without a reverse proxy', function() {
      it('should set req.port to 80 for http requests', function() {
        this.req.protocol = 'http';
        this.req.host = 'example.org';
        this.req.headers.Host = 'example.org';
        mixinMetadata(this.req);
        assert.equal(this.req.port, 80);
      });

      it('should set req.port to 443 for https requests', function() {
        this.req.protocol = 'https';
        this.req.host = 'example.org';
        this.req.headers.Host = 'example.org';
        mixinMetadata(this.req);
        assert.equal(this.req.port, 443);
      });

      it('should not add a port to baseUrl on port 80 or 443', function() {
        this.req.protocol = 'http';
        this.req.host = 'example.org';
        this.req.headers.Host = 'example.org';
        mixinMetadata(this.req);
        assert.equal(this.req.baseUrl, 'http://example.org');

        this.req.protocol = 'https';
        this.req.host = 'example.org';
        this.req.headers.Host = 'example.org';
        mixinMetadata(this.req);
        assert.equal(this.req.baseUrl, 'https://example.org');
      });

      it('should add a port to baseUrl on a custom port', function() {
        this.req.protocol = 'http';
        this.req.host = 'example.org';
        this.req.headers.Host = 'example.org:1337';
        mixinMetadata(this.req);
        assert.equal(this.req.baseUrl, 'http://example.org:1337');
      });

      it('should handle running as HTTP on port 443', function() {
        this.req.protocol = 'http';
        this.req.host = 'example.org';
        this.req.headers.Host = 'example.org:443';
        mixinMetadata(this.req);
        assert.equal(this.req.port, 443);
        assert.equal(this.req.baseUrl, 'http://example.org:443');
      });
    });

    describe('with a reverse proxy and app.enable("trust proxy")', function() {

      beforeEach(function() {
        // Fake a situation where trust proxy is enabled
        // (without having set sails.config.http accordingly)
        this.req.app.data['trust proxy'] = true;
      });

      /*
       * In this case, req.protocol as set by Express is aware of the
       * X-Forwarded-Proto header field. The only complication: req.host
       * doesn't include a port number; req.header('host') might be wrong, too,
       * so we can't trust it either.
       */

      it('should handle a simple HTTP case with X-Forwarded-Host', function() {
        this.req.protocol = 'http'; // we assume Express got this right
        this.req.host = 'server.local';
        this.req.headers.Host = 'server.local';
        this.req.headers['X-Forwarded-Host'] = 'example.org';
        mixinMetadata(this.req);
        assert.equal(this.req.port, 80);
        assert.equal(this.req.baseUrl, 'http://example.org');
      });

      it('should handle when X-Forwarded-Host is not set', function() {
        this.req.protocol = 'http'; // we assume Express got this right
        this.req.host = 'server.local';
        this.req.headers.Host = 'example.org:81';
        mixinMetadata(this.req);
        assert.equal(this.req.port, 81);
        assert.equal(this.req.baseUrl, 'http://example.org:81');
      });

      it('should handle a simple HTTPS case with X-Forwarded-Host', function() {
        this.req.protocol = 'https'; // we assume Express got this right
        this.req.host = 'server.local';
        this.req.headers.Host = 'server.local';
        this.req.headers['X-Forwarded-Host'] = 'example.org';
        mixinMetadata(this.req);
        assert.equal(this.req.port, 443);
        assert.equal(this.req.baseUrl, 'https://example.org');
      });

      it('should handle running on a nonstandard port', function() {
        this.req.protocol = 'https'; // we assume Express got this right
        this.req.host = 'server.local';
        this.req.headers.Host = 'server.local:10000';
        this.req.headers['X-Forwarded-Host'] = 'example.org';
        mixinMetadata(this.req);
        assert.equal(this.req.port, 443);
        assert.equal(this.req.baseUrl, 'https://example.org');
      });

      it('should handle a list of x-forwarded-host values', function() {
        this.req.protocol = 'https'; // we assume Express got this right
        this.req.host = 'server2.local';
        this.req.headers.Host = 'server2.local:10000';
        this.req.headers['X-Forwarded-Host'] = 'example.org, server1.local';
        mixinMetadata(this.req);
        assert.equal(this.req.port, 443);
        assert.equal(this.req.baseUrl, 'https://example.org');
      });

      it('should handle running on a weird port through a reverse proxy', function() {
        this.req.protocol = 'http';
        this.req.host = 'server.local';
        this.req.headers.Host = 'server.local:1000';
        this.req.headers['X-Forwarded-Host'] = 'example.org:81';
        mixinMetadata(this.req);
        assert.equal(this.req.port, 81);
        assert.equal(this.req.baseUrl, 'http://example.org:81');
      });

      it('should handle running as HTTP on port 443', function() {
        this.req.protocol = 'http';
        this.req.host = 'server.local';
        this.req.headers.Host = 'server.local:443';
        this.req.headers['X-Forwarded-Host'] = 'example.org:443';
        mixinMetadata(this.req);
        assert.equal(this.req.port, 443);
        assert.equal(this.req.baseUrl, 'http://example.org:443');
      });
    });

  });

});
<|endoftext|>


<commit_before>import { expect } from 'chai';

import * as commutable from 'commutable';
import * as constants from '../../../src/notebook/constants';

import reducers from '../../../src/notebook/reducers';

import {
  dummyJSON,
  dummyCommutable,
} from '../dummy-nb';

import {
  fromJS,
} from 'commutable';

import {
  List,
  Map,
} from 'immutable';

const initialDocument = new Map();
const monocellDocument = initialDocument.set('notebook', commutable.appendCell(dummyCommutable, commutable.emptyCodeCell));

describe('setNotebook', () => {
  it('converts a JSON notebook to our commutable notebook and puts in state', () => {
    const initialState = {
      app: null,
      document: initialDocument,
    };
    const data = fromJS(dummyJSON);
    const state = reducers(initialState, { type: constants.SET_NOTEBOOK, data });
    expect(state.document.getIn(['notebook', 'nbformat'])).to.equal(4);
  });
});

describe('focusCell', () => {
  it('should set focusedCell to the appropriate cell ID', () => {
    const originalState = {
      document: monocellDocument,
    };

    const id = originalState.document.getIn(['notebook', 'cellOrder']).last();

    const action = {
      type: constants.FOCUS_CELL,
      id,
    };

    const state = reducers(originalState, action);
    expect(state.document.get('focusedCell')).to.equal(id);
  });
});

describe('focusNextCell', () => {
  it('should focus the next cell if not the last cell', () => {
    const originalState = {
      document: monocellDocument,
    };

    const id = originalState.document.getIn(['notebook', 'cellOrder']).first();

    const action = {
      type: constants.FOCUS_NEXT_CELL,
      id,
    };

    const state = reducers(originalState, action);
    expect(state.document.get('focusedCell')).to.not.be.null;
  });
  it('should return same state if last cell and createCellIfUndefined is false', () => {
    const originalState = {
      document: monocellDocument,
    };

    const id = originalState.document.getIn(['notebook', 'cellOrder']).last();

    const action = {
      type: constants.FOCUS_NEXT_CELL,
      id,
    };

    const state = reducers(originalState, action);
    expect(state.document.get('focusedCell')).to.not.be.null;
    expect(state.document.getIn(['notebook', 'cellOrder']).size).to.equal(3);
  });
  it('should create and focus a new cell if last cell', () => {
    const originalState = {
      document: {
        notebook: dummyCommutable,
      }
    };

    const id = originalState.document.notebook.get('cellOrder').last();

    const action = {
      type: constants.FOCUS_NEXT_CELL,
      id,
      createCellIfUndefined: true,
    };

    const state = reducers(originalState, action);
    expect(state.document.focusedCell).to.not.be.null;
    expect(state.document.notebook.get('cellOrder').size).to.equal(3);
  });
});

describe('focusPreviousCell', () => {
  it('should focus the previous cell', () => {
    const originalState = {
      document: initialDocument.set('notebook', dummyCommutable),
    };

    const id = originalState.document.getIn(['notebook', 'cellOrder']).last();
    const previousId = originalState.document.getIn(['notebook', 'cellOrder']).first();

    const action = {
      type: constants.FOCUS_PREVIOUS_CELL,
      id,
    };

    const state = reducers(originalState, action);
    expect(state.document.get('focusedCell')).to.equal(previousId);
  });
});

describe('updateExecutionCount', () => {
  it('updates the execution count by id', () => {
    const originalState = {
      document: monocellDocument,
    };

    const id = originalState.document.getIn(['notebook', 'cellOrder']).last();

    const action = {
      type: constants.UPDATE_CELL_EXECUTION_COUNT,
      id,
      count: 42,
    };

    const state = reducers(originalState, action);
    expect(state.document.getIn(['notebook', 'cellMap', id, 'execution_count'])).to.equal(42);
  });
});

describe('moveCell', () => {
  it('should swap the first and last cell appropriately', () => {
    const originalState = {
      document: initialDocument.set('notebook', dummyCommutable),
    };

    const cellOrder = originalState.document.getIn(['notebook', 'cellOrder']);
    const id = cellOrder.last();
    const destinationId = cellOrder.first();

    const action = {
      type: constants.MOVE_CELL,
      id,
      destinationId,
    };

    const state = reducers(originalState, action);
    expect(state.document.getIn(['notebook', 'cellOrder']).last()).to.equal(id);
    expect(state.document.getIn(['notebook', 'cellOrder']).first()).to.equal(destinationId);
  });
});

describe('clearCellOutput', () => {
  it('should clear outputs list', () => {
    const originalState = {
      document: initialDocument.set('notebook',
        commutable.appendCell(dummyCommutable,
          commutable.emptyCodeCell.set('outputs', ['dummy outputs']))
      ),
    };

    const id = originalState.document.getIn(['notebook', 'cellOrder']).last();

    const action = {
      type: constants.CLEAR_CELL_OUTPUT,
      id,
    };

    const state = reducers(originalState, action);
    const outputs = state.document.getIn(['notebook', 'cellMap', id, 'outputs']);
    expect(outputs).to.equal(List.of());
  });
});

describe('newCellAfter', () => {
  it('creates a brand new cell after the given id', () => {
    const originalState = {
      document: monocellDocument,
    };
    const id = originalState.document.getIn(['notebook', 'cellOrder']).last();

    const action = {
      type: constants.NEW_CELL_AFTER,
      id,
      cellType: 'markdown',
    };

    const state = reducers(originalState, action);
    expect(state.document.getIn(['notebook', 'cellOrder']).size).to.equal(4);
    const cellID = state.document.getIn(['notebook', 'cellOrder']).last();
    const cell = state.document.getIn(['notebook', 'cellMap', cellID]);
    expect(cell.get('cell_type')).to.equal('markdown');
  });
});

describe('newCellBefore', () => {
  it('creates a new cell after the given id', () => {
    const originalState = {
      document: initialDocument.set('notebook', dummyCommutable),
    };

    const id = originalState.document.getIn(['notebook', 'cellOrder']).last();

    const action = {
      type: constants.NEW_CELL_BEFORE,
      id,
      cellType: 'markdown',
    };

    const state = reducers(originalState, action);
    expect(state.document.getIn(['notebook', 'cellOrder']).size).to.equal(3);
    expect(state.document.getIn(['notebook', 'cellOrder']).last()).to.equal(id);
  });
});

describe('mergeCellAfter', () => {
  it('merges cells appropriately', () => {
    const originalState = {
      document: initialDocument.set('notebook', dummyCommutable),
    }

    const id = originalState.document.getIn(['notebook', 'cellOrder']).first();
    const action = {
      type: constants.MERGE_CELL_AFTER,
      id,
    }

    const state = reducers(originalState, action);
    expect(state.document.getIn(['notebook', 'cellOrder']).size).to.equal(1);
    expect(state.document.getIn(['notebook', 'cellOrder']).first()).to.equal(id);
  });
});

describe('newCellAppend', () => {
  it('appends a new code cell at the end', () => {
    const originalState = {
      document: initialDocument.set('notebook', dummyCommutable),
    };

    const action = {
      type: constants.NEW_CELL_APPEND,
      cellType: 'code',
    };

    const state = reducers(originalState, action);
    expect(state.document.getIn(['notebook', 'cellOrder']).size).to.equal(3);
  });
});
<commit_msg>Add test for stickyCells<commit_after>import { expect } from 'chai';

import * as commutable from 'commutable';
import * as constants from '../../../src/notebook/constants';

import reducers from '../../../src/notebook/reducers';

import {
  dummyJSON,
  dummyCommutable,
} from '../dummy-nb';

import {
  fromJS,
} from 'commutable';

import {
  List,
  Map,
} from 'immutable';

const initialDocument = new Map();
const monocellDocument = initialDocument.set('notebook', commutable.appendCell(dummyCommutable, commutable.emptyCodeCell));

describe('setNotebook', () => {
  it('converts a JSON notebook to our commutable notebook and puts in state', () => {
    const initialState = {
      app: null,
      document: initialDocument,
    };
    const data = fromJS(dummyJSON);
    const state = reducers(initialState, { type: constants.SET_NOTEBOOK, data });
    expect(state.document.getIn(['notebook', 'nbformat'])).to.equal(4);
  });
});

describe('focusCell', () => {
  it('should set focusedCell to the appropriate cell ID', () => {
    const originalState = {
      document: monocellDocument,
    };

    const id = originalState.document.getIn(['notebook', 'cellOrder']).last();

    const action = {
      type: constants.FOCUS_CELL,
      id,
    };

    const state = reducers(originalState, action);
    expect(state.document.get('focusedCell')).to.equal(id);
  });
});

describe('focusNextCell', () => {
  it('should focus the next cell if not the last cell', () => {
    const originalState = {
      document: monocellDocument,
    };

    const id = originalState.document.getIn(['notebook', 'cellOrder']).first();

    const action = {
      type: constants.FOCUS_NEXT_CELL,
      id,
    };

    const state = reducers(originalState, action);
    expect(state.document.get('focusedCell')).to.not.be.null;
  });
  it('should return same state if last cell and createCellIfUndefined is false', () => {
    const originalState = {
      document: monocellDocument,
    };

    const id = originalState.document.getIn(['notebook', 'cellOrder']).last();

    const action = {
      type: constants.FOCUS_NEXT_CELL,
      id,
    };

    const state = reducers(originalState, action);
    expect(state.document.get('focusedCell')).to.not.be.null;
    expect(state.document.getIn(['notebook', 'cellOrder']).size).to.equal(3);
  });
  it('should create and focus a new cell if last cell', () => {
    const originalState = {
      document: {
        notebook: dummyCommutable,
      }
    };

    const id = originalState.document.notebook.get('cellOrder').last();

    const action = {
      type: constants.FOCUS_NEXT_CELL,
      id,
      createCellIfUndefined: true,
    };

    const state = reducers(originalState, action);
    expect(state.document.focusedCell).to.not.be.null;
    expect(state.document.notebook.get('cellOrder').size).to.equal(3);
  });
});

describe('focusPreviousCell', () => {
  it('should focus the previous cell', () => {
    const originalState = {
      document: initialDocument.set('notebook', dummyCommutable),
    };

    const id = originalState.document.getIn(['notebook', 'cellOrder']).last();
    const previousId = originalState.document.getIn(['notebook', 'cellOrder']).first();

    const action = {
      type: constants.FOCUS_PREVIOUS_CELL,
      id,
    };

    const state = reducers(originalState, action);
    expect(state.document.get('focusedCell')).to.equal(previousId);
  });
});

describe('toggleStickyCell', () => {
  it('should stick the cell given its ID', () => {
    const originalState = {
      document: {
        notebook: dummyCommutable,
      }
    };

    const id = originalState.document.notebook.get('cellOrder').first();

    const action = {
      type: constants.TOGGLE_STICKY_CELL,
      id,
    }

    const state = reducers(originalState, action);
    expect(state.document.stickyCells.get(id)).to.be.true;
  });
});

describe('updateExecutionCount', () => {
  it('updates the execution count by id', () => {
    const originalState = {
      document: monocellDocument,
    };

    const id = originalState.document.getIn(['notebook', 'cellOrder']).last();

    const action = {
      type: constants.UPDATE_CELL_EXECUTION_COUNT,
      id,
      count: 42,
    };

    const state = reducers(originalState, action);
    expect(state.document.getIn(['notebook', 'cellMap', id, 'execution_count'])).to.equal(42);
  });
});

describe('moveCell', () => {
  it('should swap the first and last cell appropriately', () => {
    const originalState = {
      document: initialDocument.set('notebook', dummyCommutable),
    };

    const cellOrder = originalState.document.getIn(['notebook', 'cellOrder']);
    const id = cellOrder.last();
    const destinationId = cellOrder.first();

    const action = {
      type: constants.MOVE_CELL,
      id,
      destinationId,
    };

    const state = reducers(originalState, action);
    expect(state.document.getIn(['notebook', 'cellOrder']).last()).to.equal(id);
    expect(state.document.getIn(['notebook', 'cellOrder']).first()).to.equal(destinationId);
  });
});

describe('clearCellOutput', () => {
  it('should clear outputs list', () => {
    const originalState = {
      document: initialDocument.set('notebook',
        commutable.appendCell(dummyCommutable,
          commutable.emptyCodeCell.set('outputs', ['dummy outputs']))
      ),
    };

    const id = originalState.document.getIn(['notebook', 'cellOrder']).last();

    const action = {
      type: constants.CLEAR_CELL_OUTPUT,
      id,
    };

    const state = reducers(originalState, action);
    const outputs = state.document.getIn(['notebook', 'cellMap', id, 'outputs']);
    expect(outputs).to.equal(List.of());
  });
});

describe('newCellAfter', () => {
  it('creates a brand new cell after the given id', () => {
    const originalState = {
      document: monocellDocument,
    };
    const id = originalState.document.getIn(['notebook', 'cellOrder']).last();

    const action = {
      type: constants.NEW_CELL_AFTER,
      id,
      cellType: 'markdown',
    };

    const state = reducers(originalState, action);
    expect(state.document.getIn(['notebook', 'cellOrder']).size).to.equal(4);
    const cellID = state.document.getIn(['notebook', 'cellOrder']).last();
    const cell = state.document.getIn(['notebook', 'cellMap', cellID]);
    expect(cell.get('cell_type')).to.equal('markdown');
  });
});

describe('newCellBefore', () => {
  it('creates a new cell after the given id', () => {
    const originalState = {
      document: initialDocument.set('notebook', dummyCommutable),
    };

    const id = originalState.document.getIn(['notebook', 'cellOrder']).last();

    const action = {
      type: constants.NEW_CELL_BEFORE,
      id,
      cellType: 'markdown',
    };

    const state = reducers(originalState, action);
    expect(state.document.getIn(['notebook', 'cellOrder']).size).to.equal(3);
    expect(state.document.getIn(['notebook', 'cellOrder']).last()).to.equal(id);
  });
});

describe('mergeCellAfter', () => {
  it('merges cells appropriately', () => {
    const originalState = {
      document: initialDocument.set('notebook', dummyCommutable),
    }

    const id = originalState.document.getIn(['notebook', 'cellOrder']).first();
    const action = {
      type: constants.MERGE_CELL_AFTER,
      id,
    }

    const state = reducers(originalState, action);
    expect(state.document.getIn(['notebook', 'cellOrder']).size).to.equal(1);
    expect(state.document.getIn(['notebook', 'cellOrder']).first()).to.equal(id);
  });
});

describe('newCellAppend', () => {
  it('appends a new code cell at the end', () => {
    const originalState = {
      document: initialDocument.set('notebook', dummyCommutable),
    };

    const action = {
      type: constants.NEW_CELL_APPEND,
      cellType: 'code',
    };

    const state = reducers(originalState, action);
    expect(state.document.getIn(['notebook', 'cellOrder']).size).to.equal(3);
  });
});
<|endoftext|>